int myThreadCreate(thread_t *pThread, void *(*pStartRoutine)(void *), void *pArgument, int pLimitTime, char *pSchedulerType) { if (threadsQueue != NULL) { sigprocmask(SIG_BLOCK, &sigProcMask, NULL); TCB newTCB = createNewTCB(); getcontext(&(newTCB->threadContext)); if (newTCB == NULL) { freeThread(newTCB); sigprocmask(SIG_UNBLOCK, &sigProcMask, NULL); return NOT_ENOUGH_MEMORY; } else { if(pLimitTime > 0) { newTCB->limitTime = pLimitTime; } newTCB->threadContext.uc_link = &exitContext; newTCB->startQuantum = threadsQueue->quantums; setSchedulerType(newTCB, pSchedulerType); makecontext(&(newTCB->threadContext), wrapperFunction, 2, pStartRoutine, pArgument); *pThread = newTCB->threadID; //printf("MyThread: Nuevo thread creado: %ld\n", *pThread); insertThread(threadsQueue, newTCB); sigprocmask(SIG_UNBLOCK, &sigProcMask, NULL); return SUCESS; } } else { return MY_THREAD_NOT_INITIALIZED; } }
int deleteHeadThread(TCBQueue pQueue) { int result = SUCESS; TCB previousThread, headThread; if(pQueue == NULL) { result = INVALID_OPERATION; } else { headThread = pQueue->head; previousThread = pQueue->headParent; if(headThread != NULL) { if(pQueue->count == 1) { pQueue->head = NULL; pQueue->headParent = NULL; } else { pQueue->head = headThread->nextThread; previousThread->nextThread = pQueue->head; } headThread->roundRobin == 1 ? pQueue->countRoundRobin-- : pQueue->countSort--; freeThread(headThread); pQueue->count--; } else { result = INVALID_OPERATION; } } return result; }
/* This function is called repeatedly to get subsequent threads in the iteration. The only way to * resume suspended threads is to continue calling this function until it returns NULL. * * @param state state structure initialized by a call to one of the startDo functions. * * @return NULL if there is an error or if no more threads are available. Sets the error fields as * listed detailed for omrintrospect_threads_startDo_with_signal. */ J9PlatformThread * omrintrospect_threads_nextDo(J9ThreadWalkState *state) { int result = 0; struct PlatformWalkData *data = state->platform_data; DWORD processId = GetCurrentProcessId(); if (data == NULL) { /* state is invalid */ RECORD_ERROR(state, INVALID_STATE, 0); return NULL; } /* cleanup the previous threads */ freeThread(state, state->current_thread); /* initialize the thread walk if not already done */ if (data->walkStarted == FALSE) { result = Thread32First(data->snapshot, &data->thread32); data->walkStarted = TRUE; } else { result = Thread32Next(data->snapshot, &data->thread32); } if (result == FALSE) { result = -1; goto cleanup; } /* get the next thread in this process */ while (data->thread32.th32OwnerProcessID != processId || data->thread32.th32ThreadID == data->filterThread) { if (Thread32Next(data->snapshot, &data->thread32) == FALSE) { goto cleanup; } } if ((result = setup_native_thread(state, NULL)) != 0) { RECORD_ERROR(state, COLLECTION_FAILURE, result); goto cleanup; } return state->current_thread; cleanup: if (result != 0) { result = GetLastError(); if (result == ERROR_NO_MORE_FILES) { /* this is a ligitimate end of thread list error value */ result = ERROR_SUCCESS; } else { RECORD_ERROR(state, COLLECTION_FAILURE, result); } } SetLastError(result); cleanup(state); return NULL; }
void MyThreadExit(void) { Thread *this = currentThread; removeParentFromBlockedQueue(this); updateParentFieldForChildren(this); currentThread = getNextThread(); freeThread(this); setcontext(&(currentThread->uctxt)); }
void stop(Server* server) { assert(server != NULL); int i; for(i = 0; i < server->nthreads; i++) { freeThread(server->threads[i]); } free(server->threads); eventLoopDel(server->loop, server->acceptor); eventLoopClose(server->loop); }
/* This function is called repeatedly to get subsequent threads in the iteration. The only way to * resume suspended threads is to continue calling this function until it returns NULL. * * @param state state structure initialized by a call to one of the startDo functions. * * @return NULL if there is an error or if no more threads are available. Sets the error fields as * listed detailed for j9introspect_threads_startDo_with_signal. */ J9PlatformThread * omrintrospect_threads_nextDo(J9ThreadWalkState *state) { int result = 0; PlatformWalkData *data = state->platform_data; if (NULL == data) { /* state is invalid */ RECORD_ERROR(state, INVALID_STATE, 0); return NULL; } /* Cleanup the previous threads. */ freeThread(state, state->current_thread); data->threadIndex += 1; if (data->filterThread == data->threadList[data->threadIndex]) { data->threadIndex += 1; } if (data->threadIndex == data->threadCount) { /* Finished processing threads. */ return NULL; } result = setupNativeThread(state, NULL); if (0 != result) { RECORD_ERROR(state, COLLECTION_FAILURE, result); goto cleanup; } return state->current_thread; cleanup: resumeAllPreempted(data); return NULL; }
/* * Cleans up all state that we've created as part of the walk, including freeing up * the last returned thread, the debug library symbols, etc. */ void cleanup(J9ThreadWalkState *state) { BOOL resumedOK = TRUE; struct PlatformWalkData *data; if (state) { data = state->platform_data; if (data) { if (data->snapshot && data->snapshot != INVALID_HANDLE_VALUE) { if (resume_all_preempted(data) == -1) { resumedOK = FALSE; } if (!resumedOK || GetLastError() != ERROR_INVALID_HANDLE) { /* it seems this can raise an exception if the handle has become invalid */ CloseHandle(data->snapshot); } data->snapshot = NULL; } /* clean up the heap */ state->portLibrary->heap_free(state->portLibrary, state->heap, data); state->platform_data = NULL; } if (state->current_thread) { freeThread(state, state->current_thread); } free_dbg_symbols(state->portLibrary); } return; }
/** * pthread_join a thread with given tid. */ void xthread::join(xthread * current, pthread_t tid, void ** result) { xthread * joinee; // Since now I am calling join, let's set this thread to bounded from now on. // This is terrible, maybe we should check whether there is only one thread or not??? current->setBounded(); joinee = xmap::getInstance().getThread(tid); if(current == joinee) { PRERR("Thread %d cannot join myslef (tid %d)\n", current->getTid(), (int)tid); abort(); } if(joinee == NULL) { PRERR("Thread %d is not existing\n", (int)tid); abort(); } // fprintf(stderr, "%d: acquire the thread %d's lock\n", getpid(), (int)tid); // Acquire the joinee's lock!!! joinee->lock(); // If the thread already finished, then we have to cleanup the // child thread. if(!joinee->isThreadDead()) { /* Thread is still running normally, not in the deadqueue. */ // Add myself to the joinee's waiting list. // Now the joinee should guarantee to put me onto my bounded core putJoineeQueue(joinee); // If I am yielding, then I won't come back here until // the thread I am waiting put me into the run queue again. threadYieldHoldingLock(joinee->getLock()); PRDBG("the joining thread is running on process %d\n", getpid()); //PRWRN("the joining thread is running on process %d\n", getpid()); joinee->lock(); } if(!joinee->isThreadDead()) { PRERR("Joinee should be putted into the dead queue, tid %d status is %d\n", tid, joinee->status); abort(); } // Release the lock before we free the thread joinee->unlock(); PRDBG("Joining thread %d, before remove queue\n", tid); // Remove joinee from its queue. joinee->removeFromDeadQueue(); PRDBG("Joining thread %d, after remove queue\n", tid); // Set the result to 0 if(result) { *result = joinee->retval; } // Then we can free this control block. freeThread(joinee); // Check whether I am the only thread // If yes, then I should be working on my bounded core. if(xmap::getInstance().hasOneThreadOnly()) { int coreid = current->getBoundCore(); // FIXME, must cooperate with others parts if the process isnot going to xmemory::getInstance().cleanupMemoryMappings(); // Switch to bounded core if not. if(process::getInstance().getCoreId() != coreid) { xqueue * pqueue = processmap::getInstance().getPQueue(coreid); threadYieldToRunQueue(pqueue); } } }