Rewrite the kernel hashtable struct
This commit is contained in:
@ -4,47 +4,81 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include "hal/hal.h"
|
||||||
|
#include "util/util.h"
|
||||||
|
|
||||||
#define HSHTB_FNV32_BASE 0x811c9dc5
|
#define HSHTB_FNV32_OFF 0x811c9dc5u
|
||||||
|
#define HSHTB_FNV32_PRIME 0x01000193u
|
||||||
|
|
||||||
static inline uint32_t hshtb_fnv32(char *s, size_t len) {
|
static inline uint32_t hshtb_fnv32(const void *data, size_t len) {
|
||||||
uint32_t h = HSHTB_FNV32_BASE;
|
const unsigned char *p = (const unsigned char *)data;
|
||||||
|
uint32_t h = HSHTB_FNV32_OFF;
|
||||||
for (size_t i = 0; i < len; i++) {
|
for (size_t i = 0; i < len; i++) {
|
||||||
h ^= s[i];
|
h ^= p[i];
|
||||||
h += (h << 1) + (h << 4) + (h << 7) + (h << 8) + (h << 24);
|
h *= HSHTB_FNV32_PRIME;
|
||||||
}
|
}
|
||||||
return h >> 8;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define HSHTB_ALLOC(tb, name, k, keyname, out) \
|
enum {
|
||||||
|
HSHTB_EMPTY = 0,
|
||||||
|
HSHTB_TAKEN = 1,
|
||||||
|
HSHTB_TOMB = 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define HSHTB_ALLOC(tb, keyfield, k, out) \
|
||||||
do { \
|
do { \
|
||||||
size_t len = sizeof((tb)->name) / sizeof((tb)->name[0]); \
|
size_t __len = sizeof((tb)) / sizeof((tb)[0]); \
|
||||||
size_t idx = hshtb_fnv32(k, hal_strlen(k)) % len; \
|
uint32_t __h = hshtb_fnv32((k), strlen((k))); \
|
||||||
size_t i = idx; \
|
size_t __idx = __h % __len; \
|
||||||
|
size_t __start = __idx; \
|
||||||
|
typeof(&(tb)[0]) __tomb = NULL; \
|
||||||
do { \
|
do { \
|
||||||
if (!(tb)->name[i].taken) { \
|
if ((tb)[__idx]._hshtbstate == HSHTB_EMPTY) { \
|
||||||
(out) = &((tb)->name[i]); \
|
typeof(&(tb)[0]) __slot = __tomb ? __tomb : &(tb)[__idx]; \
|
||||||
hal_memset((out), 0, sizeof(*(out))); \
|
hal_memset(__slot, 0, sizeof(*__slot)); \
|
||||||
(out)->taken = true; \
|
__slot->_hshtbstate = HSHTB_TAKEN; \
|
||||||
hal_memcpy((out)->keyname, k, hal_strlen(k)); \
|
hal_memcpy(__slot->keyfield, (k), MIN(sizeof(__slot->keyfield) - 1, hal_strlen((k)))); \
|
||||||
|
(out) = __slot; \
|
||||||
break; \
|
break; \
|
||||||
} \
|
} \
|
||||||
i = (i + 1) % len; \
|
if ((tb)[__idx]._hshtbstate == HSHTB_TAKEN && hal_strcmp((tb)[__idx].keyfield, (k)) == 0) { \
|
||||||
} while(i != idx); \
|
(out) = &(tb)[__idx]; \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
if ((tb)[__idx]._hshtbstate == HSHTB_TOMB && !__tomb) { \
|
||||||
|
__tomb = &(tb)[__idx]; \
|
||||||
|
} \
|
||||||
|
__idx = (__idx + 1) % __len; \
|
||||||
|
} while(__idx != __start); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#define HSHTB_GET(tb, name, k, keyname, out) \
|
#define HSHTB_GET(tb, keyfield, k, out) \
|
||||||
do { \
|
do { \
|
||||||
size_t len = sizeof((tb)->name) / sizeof((tb)->name[0]); \
|
size_t __len = sizeof((tb)) / sizeof((tb)[0]); \
|
||||||
size_t idx = hshtb_fnv32(k, hal_strlen(k)) % len; \
|
uint32_t __h = hshtb_fnv32((k), hal_strlen((k))); \
|
||||||
size_t i = idx; \
|
size_t __idx = __h % __len; \
|
||||||
|
size_t __start = __idx; \
|
||||||
|
(out) = NULL; \
|
||||||
do { \
|
do { \
|
||||||
if (hal_memcmp((tb)->name[i].keyname, k, hal_strlen(k)) == 0) { \
|
if ((tb)[__idx]._hshtbstate == HSHTB_EMPTY) { \
|
||||||
(out) = &((tb)->name[i]); \
|
|
||||||
break; \
|
break; \
|
||||||
} \
|
} \
|
||||||
i = (i + 1) % len; \
|
if ((tb)[__idx]._hshtbstate == HSHTB_TAKEN && hal_strcmp((tb)[__idx].keyfield, (k)) == 0) { \
|
||||||
} while(i != idx); \
|
(out) = &(tb)[__idx]; \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
__idx = (__idx + 1) % __len; \
|
||||||
|
} while(__idx != __start); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
#define HSHTB_DELETE(tb, keyfield, k) \
|
||||||
|
do { \
|
||||||
|
typeof(&(tb)[0]) __e; \
|
||||||
|
HSHTB_GET((tb), (keyfield), (k), __e); \
|
||||||
|
if (__e) { \
|
||||||
|
__e->state = HSHTB_TOMB; \
|
||||||
|
} \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#endif // HSHTB_H_
|
#endif // HSHTB_H_
|
||||||
|
@ -54,7 +54,7 @@ int32_t vfs_stat(char *mountpoint, const char *path, IoctlStat *stat) {
|
|||||||
VfsMountPoint *mp = NULL;
|
VfsMountPoint *mp = NULL;
|
||||||
|
|
||||||
spinlock_acquire(&VFS_TABLE.spinlock);
|
spinlock_acquire(&VFS_TABLE.spinlock);
|
||||||
HSHTB_GET(&VFS_TABLE, mountpoints, mountpoint, label, mp);
|
HSHTB_GET(VFS_TABLE.mountpoints, label, mountpoint, mp);
|
||||||
spinlock_release(&VFS_TABLE.spinlock);
|
spinlock_release(&VFS_TABLE.spinlock);
|
||||||
|
|
||||||
if (mp == NULL) {
|
if (mp == NULL) {
|
||||||
@ -68,7 +68,7 @@ int32_t vfs_fetchdirent(char *mountpoint, const char *path, IoctlDirent *direntb
|
|||||||
VfsMountPoint *mp = NULL;
|
VfsMountPoint *mp = NULL;
|
||||||
|
|
||||||
spinlock_acquire(&VFS_TABLE.spinlock);
|
spinlock_acquire(&VFS_TABLE.spinlock);
|
||||||
HSHTB_GET(&VFS_TABLE, mountpoints, mountpoint, label, mp);
|
HSHTB_GET(VFS_TABLE.mountpoints, label, mountpoint, mp);
|
||||||
spinlock_release(&VFS_TABLE.spinlock);
|
spinlock_release(&VFS_TABLE.spinlock);
|
||||||
|
|
||||||
if (mp == NULL) {
|
if (mp == NULL) {
|
||||||
@ -82,7 +82,7 @@ int32_t vfs_mount(char *mountpoint, int32_t fstype, StoreDev *backingsd, bool fo
|
|||||||
VfsMountPoint *mp = NULL;
|
VfsMountPoint *mp = NULL;
|
||||||
|
|
||||||
spinlock_acquire(&VFS_TABLE.spinlock);
|
spinlock_acquire(&VFS_TABLE.spinlock);
|
||||||
HSHTB_ALLOC(&VFS_TABLE, mountpoints, mountpoint, label, mp);
|
HSHTB_ALLOC(VFS_TABLE.mountpoints, label, mountpoint, mp);
|
||||||
spinlock_release(&VFS_TABLE.spinlock);
|
spinlock_release(&VFS_TABLE.spinlock);
|
||||||
|
|
||||||
if (mp == NULL) {
|
if (mp == NULL) {
|
||||||
@ -107,7 +107,7 @@ int32_t vfs_unmount(char *mountpoint) {
|
|||||||
VfsMountPoint *mp = NULL;
|
VfsMountPoint *mp = NULL;
|
||||||
|
|
||||||
spinlock_acquire(&VFS_TABLE.spinlock);
|
spinlock_acquire(&VFS_TABLE.spinlock);
|
||||||
HSHTB_GET(&VFS_TABLE, mountpoints, mountpoint, label, mp);
|
HSHTB_GET(VFS_TABLE.mountpoints, label, mountpoint, mp);
|
||||||
spinlock_release(&VFS_TABLE.spinlock);
|
spinlock_release(&VFS_TABLE.spinlock);
|
||||||
|
|
||||||
if (mp == NULL) {
|
if (mp == NULL) {
|
||||||
@ -129,7 +129,7 @@ VfsObj *vfs_open(char *mountpoint, const char *path, uint32_t flags) {
|
|||||||
VfsMountPoint *mp = NULL;
|
VfsMountPoint *mp = NULL;
|
||||||
|
|
||||||
spinlock_acquire(&VFS_TABLE.spinlock);
|
spinlock_acquire(&VFS_TABLE.spinlock);
|
||||||
HSHTB_GET(&VFS_TABLE, mountpoints, mountpoint, label, mp);
|
HSHTB_GET(VFS_TABLE.mountpoints, label, mountpoint, mp);
|
||||||
spinlock_release(&VFS_TABLE.spinlock);
|
spinlock_release(&VFS_TABLE.spinlock);
|
||||||
|
|
||||||
if (mp == NULL) {
|
if (mp == NULL) {
|
||||||
@ -168,7 +168,7 @@ void vfs_init(void) {
|
|||||||
LOG("vfs", "init\n");
|
LOG("vfs", "init\n");
|
||||||
|
|
||||||
for (size_t i = 0; i < LEN(VFS_TABLE.mountpoints); i++) {
|
for (size_t i = 0; i < LEN(VFS_TABLE.mountpoints); i++) {
|
||||||
if (!VFS_TABLE.mountpoints[i].taken) continue;
|
if (VFS_TABLE.mountpoints[i]._hshtbstate != HSHTB_TAKEN) continue;
|
||||||
VfsMountPoint *vmp = &VFS_TABLE.mountpoints[i];
|
VfsMountPoint *vmp = &VFS_TABLE.mountpoints[i];
|
||||||
LOG("vfs", "mount point %s: %s, backing device: %s\n",
|
LOG("vfs", "mount point %s: %s, backing device: %s\n",
|
||||||
vmp->label, vfs_strings[vmp->fstype], storedev_strings[vmp->backingsd->sdtype]);
|
vmp->label, vfs_strings[vmp->fstype], storedev_strings[vmp->backingsd->sdtype]);
|
||||||
|
@ -42,8 +42,9 @@ typedef struct VfsObj {
|
|||||||
} VfsObj;
|
} VfsObj;
|
||||||
|
|
||||||
typedef struct VfsMountPoint {
|
typedef struct VfsMountPoint {
|
||||||
bool taken;
|
int _hshtbstate;
|
||||||
uint8_t label[VFS_MOUNTPOINT_LABEL_MAX];
|
char label[VFS_MOUNTPOINT_LABEL_MAX];
|
||||||
|
|
||||||
int32_t fstype;
|
int32_t fstype;
|
||||||
StoreDev *backingsd;
|
StoreDev *backingsd;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user