Exemplo n.º 1
0
int my_pthread_create( void (*func)(void) )
{
	if ( numThreads == MAX_THREADS ) return LF_MAXTHREADS;
	num_high_priority_threads++;
	/* Add the new function to the end of the thread list */
	getcontext( &threadList[numThreads].context );

	/* Set the context to a newly allocated stack */
	threadList[numThreads].context.uc_link = 0;
	threadList[numThreads].stack = malloc( FIBER_STACK );
	threadList[numThreads].context.uc_stack.ss_sp = threadList[numThreads].stack;
	threadList[numThreads].context.uc_stack.ss_size = FIBER_STACK;
	threadList[numThreads].context.uc_stack.ss_flags = 0;
	threadList[numThreads].start_address = (void*)myallocate(4095,__FILE__,__LINE__,0);
	threadList[numThreads].end_address = threadList[numThreads].start_address + 4095;
	threadList[numThreads].current_index = 0;
	
	if ( threadList[numThreads].stack == 0 || threadList[numThreads].start_address == NULL)
	{
		LF_DEBUG_OUT( "Error: Could not allocate stack. or heapspace" );
		return LF_MALLOCERROR;
	}
	
	/* Create the context. The context calls threadStart( func ). */
	makecontext( &threadList[ numThreads ].context, (void (*)(void)) &threadStart, 1, func );
	++ numThreads;
	
	return LF_NOERROR;
}
Exemplo n.º 2
0
 int spawnFiber( ctr_object* block )
 {
 	if ( numFibers == MAX_FIBERS ) return LF_MAXFIBERS;

 	// Add the new function to the end of the fiber list
 	getcontext( &fiberList[numFibers].context );

 	// Set the context to a newly allocated stack
 	fiberList[numFibers].context.uc_link = 0;
 	fiberList[numFibers].context.uc_stack.ss_sp = malloc( FIBER_STACK );
 	fiberList[numFibers].context.uc_stack.ss_size = FIBER_STACK;
 	fiberList[numFibers].context.uc_stack.ss_flags = 0;

 	if ( fiberList[numFibers].context.uc_stack.ss_sp == 0 )
 	{
 		LF_DEBUG_OUT( "Error: Could not allocate stack.", 0 );
 		return LF_MALLOCERROR;
 	}

 	// Create the context. The context calls fiberStart( func ).
 	makecontext( &fiberList[ numFibers ].context, (void (*)(void)) &fiberStart, 1, block );
 	++ numFibers;

 	return LF_NOERROR;
 }
Exemplo n.º 3
0
int spawnFiber( void (*func)(void) )
{
	if ( numFibers == MAX_FIBERS ) return LF_MAXFIBERS;
	
	/* Add the new function to the end of the fiber list */
	getcontext( &fiberList[numFibers].context );

	/* Set the context to a newly allocated stack */
	fiberList[numFibers].context.uc_link = 0;
	fiberList[numFibers].stack = malloc( FIBER_STACK );
	fiberList[numFibers].context.uc_stack.ss_sp = fiberList[numFibers].stack;
	fiberList[numFibers].context.uc_stack.ss_size = FIBER_STACK;
	fiberList[numFibers].context.uc_stack.ss_flags = 0;
	
	if ( fiberList[numFibers].stack == 0 )
	{
		LF_DEBUG_OUT( "Error: Could not allocate stack." );
		return LF_MALLOCERROR;
	}
	
	/* Create the context. The context calls fiberStart( func ). */
	makecontext( &fiberList[ numFibers ].context, (void (*)(void)) &fiberStart, 1, func );
	++ numFibers;
	
	return LF_NOERROR;
}
Exemplo n.º 4
0
 // Switches from a fiber to main or from main to a fiber
 void fiberYield()
 {
 	// If we are in a fiber, switch to the main process
 	if ( inFiber )
 	{
 		// Switch to the main context
 		LF_DEBUG_OUT( "libfiber debug: Fiber %d yielding the processor...", currentFiber );

 		swapcontext( &fiberList[currentFiber].context, &mainContext );
 	}
 	// Else, we are in the main process and we need to dispatch a new fiber
 	else
 	{
 		if ( numFibers == 0 ) return;

 		// Saved the state so call the next fiber
 		currentFiber = (currentFiber + 1) % numFibers;

 		LF_DEBUG_OUT( "Switching to fiber %d.", currentFiber );
 		inFiber = 1;
 		swapcontext( &mainContext, &fiberList[ currentFiber ].context );
 		inFiber = 0;
 		LF_DEBUG_OUT( "Fiber %d switched to main context.", currentFiber );

 		if ( fiberList[currentFiber].active == 0 )
 		{
 			LF_DEBUG_OUT( "Fiber %d is finished. Cleaning up.\n", currentFiber );
 			// Free the "current" fiber's stack
 			free( fiberList[currentFiber].context.uc_stack.ss_sp );

 			// Swap the last fiber with the current, now empty, entry
 			-- numFibers;
 			if ( currentFiber != numFibers )
 			{
 				fiberList[ currentFiber ] = fiberList[ numFibers ];
 			}
 			fiberList[ numFibers ].active = 0;
 		}

 	}
 	return;
 }
Exemplo n.º 5
0
int spawn_thread1( void (*func)(void) )
{
	struct thread1Arguments* arguments = NULL;
	if ( numthreads == MAX_THREADS ) return LF_MAXTHREADS;
	thread1List[numthreads].stack = malloc( THREAD_STACK );		/* Allocate the stack */
	
	if ( thread1List[numthreads].stack == 0 )
	{
		LF_DEBUG_OUT( "Error: Could not allocate stack." );
		return LF_MALLOCERROR;
	}

	
	arguments = (struct thread1Arguments*) malloc( sizeof(*arguments) );	/* Create the arguments structure. */
	
	if ( arguments == 0 ) {
		free( thread1List[numthreads].stack );
		LF_DEBUG_OUT( "Error: Could not allocate thread arguments." );
		return LF_MALLOCERROR;
	}
	arguments->function = func;

	/* Call the clone system call to create the child thread */
	thread1List[numthreads].pid = clone( &thread1Start, (char*) thread1List[numthreads].stack + THREAD_STACK,
		SIGCHLD | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_VM, arguments );

	if ( thread1List[numthreads].pid == -1 )
	{
		free( thread1List[numthreads].stack );
		free( arguments );
		LF_DEBUG_OUT( "Error: clone system call failed." );
		return LF_CLONEERROR;
	}
	
	numthreads ++;
	
	return LF_NOERROR;
}
Exemplo n.º 6
0
 int waitForAllFibers()
 {
 	int fibersRemaining = 0;

 	// If we are in a fiber, wait for all the *other* fibers to quit
 	if ( inFiber ) fibersRemaining = 1;

 	LF_DEBUG_OUT( "Waiting until there are only %d threads remaining...", fibersRemaining );

 	// Execute the fibers until they quit
 	while ( numFibers > fibersRemaining )
 	{
 		fiberYield();
 	}

 	return LF_NOERROR;
 }
Exemplo n.º 7
0
int waitForAllthreads()
{
	pid_t pid;
	int i;
	int threadsRemaining = 0;
		
	/* Check to see if we are in a thread, since we don't get signals in the child threads */
	pid = getpid();
	if ( pid != parentPid ) return LF_INTHREAD;			
		
	/* Wait for the THREADs to quit, then free the stacks */
	while ( numthreads > threadsRemaining )
	{
		pid = wait( 0 );
		if ( pid == -1 )
		{
			LF_DEBUG_OUT( "Error: wait system call failed." );
			exit( 1 );
		}
		
		
		for ( i = 0; i < numthreads; ++ i )	/* Find the thread, free the stack, and swap it with the last one */
		{
			if ( thread1List[i].pid == pid )
			{
				LF_DEBUG_OUT1( "Child thread pid = %d exited", pid );
				numthreads --;
				
				free( thread1List[i].stack );
				if ( i != numthreads )
				{
					thread1List[i] = thread1List[numthreads];
				}
				
				i = -1;
				break;
			}
		}
		if ( i == numthreads )
		{
			LF_DEBUG_OUT1( "Did not find child pid = %d in the thread list", pid ); 
		}
	}
	
	return LF_NOERROR;
}
Exemplo n.º 8
0
int spawnFiber( void (*func)(void) )
{
	struct sigaction handler;
	struct sigaction oldHandler;
	
	stack_t stack;
	stack_t oldStack;
	
	if ( numFibers == MAX_FIBERS ) return LF_MAXFIBERS;
	
	/* Create the new stack */
	stack.ss_flags = 0;
	stack.ss_size = FIBER_STACK;
	stack.ss_sp = malloc( FIBER_STACK );
	if ( stack.ss_sp == 0 )
	{
		LF_DEBUG_OUT( "Error: Could not allocate stack." );
		return LF_MALLOCERROR;
	}
	LF_DEBUG_OUT1( "Stack address from malloc = %p", stack.ss_sp );
#ifdef VALGRIND
	/* Sadly, this *still* doesn't fix all warnings. */
	fiberList[numFibers].stackId =
		VALGRIND_STACK_REGISTER(stack.ss_sp, ((char*) stack.ss_sp + FIBER_STACK));
#endif

	/* Install the new stack for the signal handler */
	if ( sigaltstack( &stack, &oldStack ) )
	{
		LF_DEBUG_OUT( "Error: sigaltstack failed." );
		return LF_SIGNALERROR;
	}
	
	/* Install the signal handler */
	/* Sigaction *must* be used so we can specify SA_ONSTACK */
	handler.sa_handler = &usr1handlerCreateStack;
	handler.sa_flags = SA_ONSTACK;
	sigemptyset( &handler.sa_mask );

	if ( sigaction( SIGUSR1, &handler, &oldHandler ) )
	{
		LF_DEBUG_OUT( "Error: sigaction failed." );
		return LF_SIGNALERROR;
	}
	
	/* Call the handler on the new stack */
	if ( raise( SIGUSR1 ) )
	{
		LF_DEBUG_OUT( "Error: raise failed." );
		return LF_SIGNALERROR;
	}
	
	/* Restore the original stack and handler */
	sigaltstack( &oldStack, 0 );
	sigaction( SIGUSR1, &oldHandler, 0 );
	
	/* We now have an additional fiber, ready to roll */
	fiberList[numFibers].active = 1;
	fiberList[numFibers].function = func;
	fiberList[numFibers].stack = stack.ss_sp;

	++ numFibers;
	return LF_NOERROR;
}