int flat_skiplist_delete(FlatSkiplist *sl, void *data) { int i; int level_index; FlatSkiplistNode *previous; FlatSkiplistNode *deleted; previous = flat_skiplist_get_previous(sl, data, &level_index); if (previous == NULL) { return ENOENT; } deleted = previous->links[level_index]; for (i=level_index; i>=0; i--) { while (previous->links[i] != sl->tail && sl->compare_func(data, previous->links[i]->data) < 0) { previous = previous->links[i]; } assert(sl->compare_func(data, previous->links[i]->data) == 0); previous->links[i] = previous->links[i]->links[i]; } deleted->links[0]->prev = previous; if (sl->free_func != NULL) { sl->free_func(deleted->data); } fast_mblock_free_object(sl->mblocks + level_index, deleted); return 0; }
static void deal_timeout_tasks(ScheduleContext *pContext, FastTimerEntry *head) { FastTimerEntry *entry; FastTimerEntry *current; FastDelayTask *task; entry = head->next; while (entry != NULL) { current = entry; entry = entry->next; current->prev = current->next = NULL; //must set NULL because NOT in time wheel task = (FastDelayTask *)current; if (!task->new_thread) { task->task_func(task->func_args); fast_mblock_free_object(&pContext->mblock, task); } else { struct delay_thread_context delay_context; pthread_t tid; int result; int i; task->thread_running = false; delay_context.task = task; delay_context.schedule_context = pContext; if ((result=pthread_create(&tid, NULL, sched_call_delay_func, &delay_context)) != 0) { logError("file: "__FILE__", line: %d, " \ "create thread failed, " \ "errno: %d, error info: %s", \ __LINE__, result, STRERROR(result)); } else { usleep(1*1000); for (i=1; !task->thread_running && i<100; i++) { logDebug("file: "__FILE__", line: %d, " "task args: %p, waiting thread ready, count %d", __LINE__, task->func_args, i); usleep(1*1000); } } } } }
void fast_allocator_free(struct fast_allocator_context *acontext, void *ptr) { struct allocator_wrapper *pWrapper; struct fast_allocator_info *allocator_info; void *obj; if (ptr == NULL) { return; } obj = (char *)ptr - sizeof(struct allocator_wrapper); pWrapper = (struct allocator_wrapper *)obj; if (pWrapper->allocator_index < 0 || pWrapper->allocator_index >= acontext->allocator_array.count) { logError("file: "__FILE__", line: %d, " "invalid allocator index: %d", __LINE__, pWrapper->allocator_index); return; } allocator_info = acontext->allocator_array.allocators[pWrapper->allocator_index]; if (pWrapper->magic_number != allocator_info->magic_number) { logError("file: "__FILE__", line: %d, " "invalid magic number: %d != %d", __LINE__, pWrapper->magic_number, allocator_info->magic_number); return; } __sync_sub_and_fetch(&acontext->alloc_bytes, pWrapper->alloc_bytes); pWrapper->allocator_index = -1; pWrapper->magic_number = 0; if (allocator_info->pooled) { fast_mblock_free_object(&allocator_info->mblock, obj); } else { fast_allocator_malloc_trunk_notify_func(-1 * pWrapper->alloc_bytes, acontext); free(obj); } }
static void *sched_call_delay_func(void *args) { struct delay_thread_context *delay_context; ScheduleContext *pContext; FastDelayTask *task; delay_context = (struct delay_thread_context *)args; task = delay_context->task; pContext = delay_context->schedule_context; logDebug("file: "__FILE__", line: %d, " \ "delay thread enter, task args: %p", __LINE__, task->func_args); task->thread_running = true; task->task_func(task->func_args); logDebug("file: "__FILE__", line: %d, " \ "delay thread exit, task args: %p", __LINE__, task->func_args); fast_mblock_free_object(&pContext->mblock, task); pthread_detach(pthread_self()); return NULL; }