#include #include #include enum futex_flags { FUTEX_CREATE = 0x01u, }; static struct btree futex_list = {0}; static spin_lock_t futex_list_lock = SPIN_LOCK_INIT; static struct vm_cache futex_cache = { .c_name = "futex", .c_obj_size = sizeof(struct futex), }; BTREE_DEFINE_SIMPLE_INSERT(struct futex, f_node, f_key, put_futex) BTREE_DEFINE_SIMPLE_GET(struct futex, futex_key_t, f_node, f_key, get_futex) kern_status_t futex_init(void) { vm_cache_init(&futex_cache); return KERN_OK; } static struct futex *get_data(futex_key_t key, enum futex_flags flags) { spin_lock(&futex_list_lock); struct futex *futex = get_futex(&futex_list, key); spin_unlock(&futex_list_lock); if (!futex && !(flags & FUTEX_CREATE)) { return NULL; } futex = vm_cache_alloc(&futex_cache, VM_NORMAL); futex->f_key = key; spin_lock(&futex_list_lock); put_futex(&futex_list, futex); spin_unlock(&futex_list_lock); return futex; } kern_status_t futex_get( struct address_space *space, kern_futex_t *futex, futex_key_t *out) { unsigned long flags; address_space_lock_irqsave(space, &flags); kern_status_t status = address_space_translate( space, (virt_addr_t)futex, out, &flags); address_space_unlock_irqrestore(space, flags); return status; } kern_status_t futex_wait(futex_key_t futex, kern_futex_t new_val) { return KERN_UNIMPLEMENTED; } kern_status_t futex_wake(futex_key_t futex, size_t nwaiters) { return KERN_UNIMPLEMENTED; }