static void load(const char *filename, uint flags, void *img_data, uint img_size, uintptr_t group, TextureLoaded sync_cb, void *cb_data) { assert(sync_cb != NULL); SDL_mutexP(storage_mutex); { /* See if task for this filename already exists. */ Task *task; HASH_FIND_STR(task_hash, filename, task); if (task == NULL) { task = mp_alloc(&mp_tasks); /* Set task filename and add to hash. */ assert(*filename != '\0' && strlen(filename) < sizeof(task->filename)); strcpy(task->filename, filename); HASH_ADD_STR(task_hash, filename, task); /* Set source buffer and size. */ task->img_data = img_data; task->img_size = img_size; if (texture_is_loaded(filename, flags)) { /* Already loaded: add to finished_tasks. */ DL_PREPEND(finished_tasks, task); num_finished++; } else { /* * Insert into active list and signal task * processing thread. */ task->active = 1; DL_PREPEND(active_tasks, task); SDL_CondSignal(checktask_cond); } } else if (task->active) { /* Move to the front of active task queue. */ DL_DELETE(active_tasks, task); DL_PREPEND(active_tasks, task); } /* Set/change group, flags, callback and its data pointer. */ task->group = (group != 0) ? group : (uintptr_t)sync_cb; task->sync_cb = sync_cb; task->cb_data = cb_data; task->flags = flags; } SDL_mutexV(storage_mutex); }
/*----------------------------------------------------------------------------- * Create a new MemBlock, return NULL on out of memory *----------------------------------------------------------------------------*/ static MemBlock *new_block( size_t client_size, char *file, int lineno ) { MemBlock *block; size_t block_size; /* create memory to hold MemBlock + client area + fence */ block_size = BLOCK_SIZE( client_size ); block = malloc( block_size ); check( block, "memory alloc (%u bytes) failed at %s:%d", client_size, file, lineno ); /* init block */ block->signature = MEMBLOCK_SIGN; block->destructor = NULL; block->flags.in_collection = FALSE; block->flags.destroy_atextit = FALSE; block->client_size = client_size; block->file = file; block->lineno = lineno; /* fill fences */ memset( START_FENCE_PTR( block ), FENCE_SIGN, FENCE_SIZE ); memset( END_FENCE_PTR( block ), FENCE_SIGN, FENCE_SIZE ); /* add to list of blocks in reverse order, so that cleanup is reversed */ DL_PREPEND(g_mem_blocks, block); return block; error: return NULL; }
jlong rvmStartThread(Env* env, JavaThread* threadObj) { Env* newEnv = rvmCreateEnv(env->vm); if (!newEnv) { rvmThrowOutOfMemoryError(env); // rvmCreateEnv() doesn't throw OutOfMemoryError if allocation fails return 0; } rvmLockThreadsList(); if (threadObj->threadPtr != 0) { rvmThrowIllegalStateException(env, "thread has already been started"); rvmUnlockThreadsList(); return 0; } Thread* thread = allocThread(env); if (!thread) { rvmUnlockThreadsList(); return 0; } size_t stackSize = (size_t) threadObj->stackSize; if (stackSize == 0) { stackSize = THREAD_DEFAULT_STACK_SIZE; } else if (stackSize < THREAD_MIN_STACK_SIZE) { stackSize = THREAD_MIN_STACK_SIZE; } stackSize += THREAD_SIGNAL_STACK_SIZE; stackSize = (stackSize + THREAD_STACK_SIZE_MULTIPLE - 1) & ~(THREAD_STACK_SIZE_MULTIPLE - 1); pthread_attr_t threadAttr; pthread_attr_init(&threadAttr); pthread_attr_setdetachstate(&threadAttr, PTHREAD_CREATE_DETACHED); pthread_attr_setstacksize(&threadAttr, stackSize); pthread_attr_setguardsize(&threadAttr, THREAD_STACK_GUARD_SIZE); ThreadEntryPointArgs args = {0}; args.env = newEnv; args.thread = thread; args.threadObj = threadObj; int err = 0; if ((err = pthread_create(&thread->pThread, &threadAttr, startThreadEntryPoint, &args)) != 0) { rvmUnlockThreadsList(); rvmThrowInternalErrorErrno(env, err); return 0; } while (thread->status != THREAD_STARTING) { pthread_cond_wait(&threadStartCond, &threadsLock); } DL_PREPEND(threads, thread); pthread_cond_broadcast(&threadsChangedCond); thread->status = THREAD_VMWAIT; pthread_cond_broadcast(&threadStartCond); rvmUnlockThreadsList(); return PTR_TO_LONG(thread); }
void CCScheduler::priorityIn(tListEntry **ppList, SelectorProtocol *pTarget, int nPriority, bool bPaused) { tListEntry *pListElement = (tListEntry *)malloc(sizeof(*pListElement)); pListElement->target = pTarget; pListElement->priority = nPriority; pListElement->paused = bPaused; pListElement->next = pListElement->prev = NULL; // listElement->impMethod = (TICK_IMP) [target methodForSelector:updateSelector]; // empey list ? if (! *ppList) { DL_APPEND(*ppList, pListElement); } else { bool bAdded = false; for (tListEntry *pElement = *ppList; pElement; pElement = pElement->next) { if (nPriority < pElement->priority) { if (pElement == *ppList) { DL_PREPEND(*ppList, pListElement); } else { pListElement->next = pElement; pListElement->prev = pElement->prev; pElement->prev->next = pListElement; pElement->prev = pListElement; } bAdded = true; break; } } // Not added? priority has the higher value. Append it. if (! bAdded) { DL_APPEND(*ppList, pListElement); } } // update hash entry for quick access tHashUpdateEntry *pHashElement = (tHashUpdateEntry *)calloc(sizeof(*pHashElement), 1); pHashElement->target = pTarget; pTarget->selectorProtocolRetain(); pHashElement->list = ppList; pHashElement->entry = pListElement; HASH_ADD_INT(m_pHashForUpdates, target, pHashElement); }
KUSB_EXP BOOL KUSB_API OvlK_Acquire( _out KOVL_HANDLE* OverlappedK, _in KOVL_POOL_HANDLE PoolHandle) { PKOVL_EL overlappedEL = NULL; PKOVL_POOL_HANDLE_INTERNAL handle; BOOL isNewFromPool = FALSE; ErrorParamAction(!IsHandleValid(OverlappedK), "OverlappedK", return FALSE); *OverlappedK = NULL; Pub_To_Priv_OvlPoolK(PoolHandle, handle, return FALSE); ErrorSetAction(!PoolHandle_Inc_OvlPoolK(handle), ERROR_RESOURCE_NOT_AVAILABLE, return FALSE, "->PoolHandle_Inc_OvlPoolK"); overlappedEL = handle->ReleasedList; ErrorSetAction(!overlappedEL, ERROR_NO_MORE_ITEMS, PoolHandle_Dec_OvlPoolK(handle); return FALSE, "No more overlapped handles"); DL_DELETE(handle->ReleasedList, overlappedEL); if (!overlappedEL->Handle) { isNewFromPool = TRUE; // Get a new OverlappedK handle. overlappedEL->Handle = PoolHandle_Acquire_OvlK(Cleanup_OvlK); if (!overlappedEL->Handle) { DL_PREPEND(handle->ReleasedList, overlappedEL); ErrorNoSet(!overlappedEL->Handle, Error, "->PoolHandle_Acquire_OvlK"); } } overlappedEL->Handle->MasterLink = overlappedEL; overlappedEL->Handle->Pool = handle; o_Reuse(overlappedEL->Handle); *OverlappedK = (KOVL_HANDLE)overlappedEL->Handle; if (isNewFromPool) PoolHandle_Live_OvlK(overlappedEL->Handle); overlappedEL->Handle->IsAcquired = 1; DL_APPEND(handle->AcquiredList, overlappedEL); PoolHandle_Dec_OvlPoolK(handle); return TRUE; Error: PoolHandle_Dec_OvlPoolK(handle); return FALSE; }
KUSB_EXP BOOL KUSB_API OvlK_Release( _in KOVL_HANDLE OverlappedK) { PKOVL_HANDLE_INTERNAL overlapped = NULL; BOOL success = FALSE; Pub_To_Priv_OvlK(OverlappedK, overlapped, return FALSE); ErrorParamAction(!PoolHandle_Inc_OvlK(overlapped), "OverlappedK", return FALSE); success = overlapped->Pool ? (InterlockedExchange(&overlapped->IsAcquired, 0) != 0) : FALSE; ErrorSet(!success, Done, ERROR_ACCESS_DENIED, "OverlappedK is not acquired."); DL_DELETE(overlapped->Pool->AcquiredList, overlapped->MasterLink); DL_PREPEND(overlapped->Pool->ReleasedList, overlapped->MasterLink); Done: PoolHandle_Dec_OvlK(overlapped); return success; }
/** * Parse metaserver 'server' node. * * @param node * Node to parse. */ static void parse_metaserver_node (xmlNodePtr node) { HARD_ASSERT(node != NULL); server_struct *server = ecalloc(1, sizeof(*server)); server->port_crypto = -1; server->is_meta = true; for (xmlNodePtr tmp = node->children; tmp != NULL; tmp = tmp->next) { if (!parse_metaserver_data_node(tmp, server)) { goto error; } } if (server->hostname == NULL || server->port == 0 || server->name == NULL || server->version == NULL || server->desc == NULL) { LOG(ERROR, "Incomplete data from metaserver"); goto error; } if (!parse_metaserver_cert(server)) { /* Logging already done */ goto error; } SDL_LockMutex(server_head_mutex); DL_PREPEND(server_head, server); server_count++; SDL_UnlockMutex(server_head_mutex); return; error: metaserver_free(server); }
int main(int argc, char *argv[]) { int i; el els[10], *e; for(i=0;i<10;i++) els[i].id='a'+i; /* test CDL macros */ printf("CDL macros\n"); CDL_PREPEND(head,&els[0]); CDL_PREPEND(head,&els[1]); CDL_PREPEND(head,&els[2]); CDL_PREPEND(head,&els[3]); CDL_FOREACH(head,e) printf("%c ", e->id); printf("\n"); /* point head to head->next */ printf("advancing head pointer\n"); head = head->next; CDL_FOREACH(head,e) printf("%c ", e->id); printf("\n"); /* follow circular loop a few times */ for(i=0,e=head;e && i<10;i++,e=e->next) printf("%c ", e->id); printf("\n"); /* follow circular loop backwards a few times */ for(i=0,e=head;e && i<10;i++,e=e->prev) printf("%c ", e->id); printf("\n"); printf("deleting b\n"); CDL_DELETE(head,&els[1]); CDL_FOREACH(head,e) printf("%c ", e->id); printf("\n"); printf("deleting (a)\n"); CDL_DELETE(head,&els[0]); CDL_FOREACH(head,e) printf("%c ", e->id); printf("\n"); printf("deleting (c)\n"); CDL_DELETE(head,&els[2]); CDL_FOREACH(head,e) printf("%c ", e->id); printf("\n"); printf("deleting (d)\n"); CDL_DELETE(head,&els[3]); CDL_FOREACH(head,e) printf("%c ", e->id); printf("\n"); /* test DL macros */ printf("DL macros\n"); DL_PREPEND(head,&els[0]); DL_PREPEND(head,&els[1]); DL_PREPEND(head,&els[2]); DL_APPEND(head,&els[3]); DL_FOREACH(head,e) printf("%c ", e->id); printf("\n"); printf("deleting c\n"); DL_DELETE(head,&els[2]); DL_FOREACH(head,e) printf("%c ", e->id); printf("\n"); printf("deleting a\n"); DL_DELETE(head,&els[0]); DL_FOREACH(head,e) printf("%c ", e->id); printf("\n"); printf("deleting b\n"); DL_DELETE(head,&els[1]); DL_FOREACH(head,e) printf("%c ", e->id); printf("\n"); printf("deleting d\n"); DL_DELETE(head,&els[3]); DL_FOREACH(head,e) printf("%c ", e->id); printf("\n"); /* test LL macros */ printf("LL macros\n"); LL_PREPEND(head,&els[0]); LL_PREPEND(head,&els[1]); LL_PREPEND(head,&els[2]); LL_APPEND(head,&els[3]); LL_FOREACH(head,e) printf("%c ", e->id); printf("\n"); printf("deleting c\n"); LL_DELETE(head,&els[2]); LL_FOREACH(head,e) printf("%c ", e->id); printf("\n"); printf("deleting a\n"); LL_DELETE(head,&els[0]); LL_FOREACH(head,e) printf("%c ", e->id); printf("\n"); printf("deleting b\n"); LL_DELETE(head,&els[1]); LL_FOREACH(head,e) printf("%c ", e->id); printf("\n"); printf("deleting d\n"); LL_DELETE(head,&els[3]); LL_FOREACH(head,e) printf("%c ", e->id); printf("\n"); return 0; }
static jint attachThread(VM* vm, Env** envPtr, char* name, Object* group, jboolean daemon) { Env* env = *envPtr; // env is NULL if rvmAttachCurrentThread() was called. If non NULL rvmInitThreads() was called. if (!env) { // If the thread was already attached there's an Env* associated with the thread. env = (Env*) pthread_getspecific(tlsEnvKey); if (env) { env->attachCount++; *envPtr = env; return JNI_OK; } } if (!env) { env = rvmCreateEnv(vm); if (!env) goto error; } setThreadEnv(env); if (rvmExceptionOccurred(env)) goto error; Thread* thread = allocThread(env); if (!thread) goto error; thread->stackAddr = getStackAddress(); thread->pThread = pthread_self(); env->currentThread = thread; rvmChangeThreadStatus(env, thread, THREAD_RUNNING); JavaThread* threadObj = (JavaThread*) rvmAllocateObject(env, java_lang_Thread); if (!threadObj) goto error; rvmLockThreadsList(); if (!initThread(env, thread, threadObj)) { rvmUnlockThreadsList(); goto error; } if (!rvmSetupSignals(env)) { rvmUnlockThreadsList(); goto error; } DL_PREPEND(threads, thread); pthread_cond_broadcast(&threadsChangedCond); rvmUnlockThreadsList(); Object* threadName = NULL; if (name) { threadName = rvmNewStringUTF(env, name, -1); if (!threadName) goto error_remove; } Method* threadConstructor = rvmGetInstanceMethod2(env, java_lang_Thread, "<init>", "(JLjava/lang/String;Ljava/lang/ThreadGroup;Z)V"); if (!threadConstructor) goto error_remove; rvmCallNonvirtualVoidInstanceMethod(env, (Object*) threadObj, threadConstructor, PTR_TO_LONG(thread), threadName, group, daemon); if (rvmExceptionOccurred(env)) goto error_remove; *envPtr = env; return JNI_OK; error_remove: rvmLockThreadsList(); DL_DELETE(threads, thread); pthread_cond_broadcast(&threadsChangedCond); rvmTearDownSignals(env); rvmUnlockThreadsList(); error: if (env) env->currentThread = NULL; clearThreadEnv(); return JNI_ERR; }