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;
}
Example #3
0
/* 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;
}
Example #4
0
void MyThreadExit(void) {
	Thread *this = currentThread;
		
	removeParentFromBlockedQueue(this);	 
	updateParentFieldForChildren(this);
		
	currentThread = getNextThread();	
	freeThread(this);	

	setcontext(&(currentThread->uctxt));
}
Example #5
0
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);	
}
Example #6
0
/* 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;
}
Example #7
0
/*
 * 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;
}
Example #8
0
/**
 * 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);
    }
  }
}