int PoolExercise(int verbose, struct cfg *cfg, char *args[]) { void *data; int rate, i; struct linkedlist *l; struct pool *p; cfg = NULL; args[0] = NULL; if ((p = pool_new(EXERCISE_SM_COUNT, (new_fn)allocator_alloc, allocator_free, NULL, NULL, BUFFER_SIZE_SM, 0, NULL)) == NULL || (l = linkedlist_new(0, NULL)) == NULL) { PMNO(errno); return 1; } rate = EXERCISE_R0; for (i = 0; i < EXERCISE_SM_COUNT; i++) { if (i == EXERCISE_SM_P1) { rate = EXERCISE_R1; } else if (i == EXERCISE_SM_P2) { rate = EXERCISE_R2; } else if (i == EXERCISE_SM_P3) { rate = EXERCISE_R3; } if (rand() % 10 < rate) { if (pool_size(p) == EXERCISE_SM_COUNT && pool_unused(p) == 0) { continue; } else if ((data = pool_get(p)) == NULL) { AMSG(""); return -1; } else if (linkedlist_add(l, data) == -1) { AMSG("%04d %p s=%d,u=%d\n", i, data, pool_size(p), pool_unused(p)); return -1; } tcase_printf(verbose, "%04d get %p s=%d,u=%d\n", i, data, pool_size(p), pool_unused(p)); } else if ((data = linkedlist_remove(l, 0))) { if (data == NULL || pool_release(p, data) == -1) { AMSG("%04d %p s=%d,u=%d\n", i, data, pool_size(p), pool_unused(p)); return -1; } tcase_printf(verbose, "%04d rel %p s=%d,u=%d\n", i, data, pool_size(p), pool_unused(p)); } else { tcase_printf(verbose, "%04d nothing to release\n", i); } } linkedlist_del(l, NULL, NULL); pool_del(p); return 0; }
int fs_umount(struct filesystem *fs) { assert(fs); if(fs->driver && fs->driver->umount) fs->driver->umount(fs); vfs_inode_umount(fs->point); if(fs != devfs) linkedlist_remove(&fslist, &fs->listnode); return 0; }
void tm_process_wait_cleanup(struct process *proc) { assert(proc != current_process); /* prevent this process from being "cleaned up" multiple times */ if(!(atomic_fetch_or(&proc->flags, PROCESS_CLEANED) & PROCESS_CLEANED)) { assert(proc->thread_count == 0); linkedlist_remove(process_list, &proc->listnode); mutex_destroy(&proc->map_lock); if(proc->parent) tm_process_put(proc->parent); tm_process_put(proc); /* process_list releases its pointer */ } }
int hash_delete(struct hash *h, const void *key, size_t keylen) { __lock(h); size_t index = __hashfn(key, keylen, h->length); if(h->table[index] == NULL) { __unlock(h); return -ENOENT; } struct hashelem tmp; tmp.key = key; tmp.keylen = keylen; struct linkedentry *ent = linkedlist_find(h->table[index], __ll_check_exist, &tmp); if(ent) { linkedlist_remove(h->table[index], ent); h->count--; } __unlock(h); return ent ? 0 : -ENOENT; }
uint32_t get_hole(uint32_t i) { if (i > U) return NULL; if (i < L) i = L; if (freelist[i].count) { linknode *ptr = freelist[i] .first; /* Remove first element from the free list. */ linkedlist_remove(&freelist[i], ptr, NULL); if (i > 11) arch_vmpage_unmap(NULL, ptr); return (uint32_t) ptr; } else { uint32_t ret = get_hole(i+1); if (ret == NULL) return ret; /* Split ret to two (2^i) chunks, one is free, the other returned. */ arch_vmpage_map(NULL, ret + pow2(i), 0); linkedlist_add(&freelist[i], (linknode *) (ret + pow2(i))); /* printk("ret: %x %dBytes\n", ret, pow2(i)); */ return ret; } }
static char *test_linkedlist_remove() { linkedlist_t list; linkedlist_init(&list); int x = 1, y = 2, z = 3; linkedlist_insert(&list, &x); linkedlist_insert(&list, &y); linkedlist_insert(&list, &z); mu_assert_equals_int("Error: head value", x, *(int *)linkedlist_gethead(&list)); mu_assert_equals_int("Error: tail value", z, *(int *)linkedlist_gettail(&list)); mu_assert_equals_int("Error: size value before remove", 3, linkedlist_getsize(&list)); linkedlist_remove(&list, &y); mu_assert_equals_int("Error: head value", x, *(int *)linkedlist_gethead(&list)); mu_assert_equals_int("Error: tail value", z, *(int *)linkedlist_gettail(&list)); mu_assert_equals_int("Error: size value after remove", 2, linkedlist_getsize(&list)); linkedlist_destroy(&list); return 0; }
/* drop a reference to an inode. */ void vfs_icache_put(struct inode *node) { assert(node->count > 0); mutex_acquire(ic_lock); if(atomic_fetch_sub(&node->count, 1) == 1) { if(node->flags & INODE_PERSIST) { if(node->nlink != 0) { mutex_release(ic_lock); return; } } assert(node->flags & INODE_INUSE); atomic_fetch_and(&node->flags, ~INODE_INUSE); if(node->filesystem) { atomic_fetch_sub(&node->filesystem->usecount, 1); } linkedlist_remove(ic_inuse, &node->inuse_item); queue_enqueue_item(ic_lru, &node->lru_item, node); } mutex_release(ic_lock); }
int32_t waitpid(int32_t pid, int32_t *status) { /* loop on process linked list until find the process with the "pid". */ pd_t *prev = NULL; pd_t *child = proclist.first; while (child != NULL && child->proc->pid != pid) { prev = child; child = child->next; } if (child == NULL) return -1; /* pid is invalid */ if (!(child->proc->terminated)) { /* wait until the child exits. */ curproc->blocked_for_child = pid; block(); while (!child->proc->terminated); }; /* return status */ *status = child->proc->status; /* remove process descriptor from the list: */ linkedlist_remove((linkedlist*)&proclist,(linknode*)child,(linknode*)prev); /* unallocated the process structure. */ kfree(child->proc->kstack); arch_vmdestroy(&child->proc->umem); kfree(child->proc); /* for debugging */ /*mem_leaks(pid);*/ /* return */ return pid; }
void tm_thread_do_exit(void) { assert(current_thread->held_locks == 0); assert(current_thread->blocklist == 0); struct async_call *thread_cleanup_call = async_call_create(¤t_thread->cleanup_call, 0, tm_thread_destroy, (unsigned long)current_thread, 0); struct ticker *ticker = (void *)atomic_exchange(¤t_thread->alarm_ticker, NULL); if(ticker) { if(ticker_delete(ticker, ¤t_thread->alarm_timeout) != -ENOENT) tm_thread_put(current_thread); } linkedlist_remove(¤t_process->threadlist, ¤t_thread->pnode); tm_thread_remove_kerfs_entries(current_thread); atomic_fetch_sub_explicit(&running_threads, 1, memory_order_relaxed); if(atomic_fetch_sub(¤t_process->thread_count, 1) == 1) { atomic_fetch_sub_explicit(&running_processes, 1, memory_order_relaxed); tm_process_remove_kerfs_entries(current_process); tm_process_exit(current_thread->exit_code); } cpu_disable_preemption(); assert(!current_thread->blocklist); tqueue_remove(current_thread->cpu->active_queue, ¤t_thread->activenode); atomic_fetch_sub_explicit(¤t_thread->cpu->numtasks, 1, memory_order_relaxed); tm_thread_raise_flag(current_thread, THREAD_SCHEDULE); current_thread->state = THREADSTATE_DEAD; workqueue_insert(&__current_cpu->work, thread_cleanup_call); cpu_interrupt_set(0); /* don't schedule away until we get back to the syscall handler! */ cpu_enable_preemption(); }
int fs_filesystem_unregister(struct fsdriver *fd) { linkedlist_remove(&fsdriverslist, &fd->listnode); return hash_delete(&fsdrivershash, fd->name, strlen(fd->name)); }
/* indicates that an inode no longer needs to be written to the filesystem */ void vfs_inode_unset_dirty(struct inode *node) { assert(node->flags & INODE_DIRTY); linkedlist_remove(ic_dirty, &node->dirty_item); atomic_fetch_and(&node->flags, ~INODE_DIRTY); }
void* linkedlist_remove_at(linkedlist _list, int i) { node* n = find_by_index((linkedlist_t*)_list, i); if(NULL == n) return NULL; return linkedlist_remove(_list, n->data); }