Esempio n. 1
0
void vPortYield( void )
{
pthread_t xTaskToSuspend;
pthread_t xTaskToResume;

	if ( 0 == pthread_mutex_lock( &xSingleThreadMutex ) )
	{
		xTaskToSuspend = prvGetThreadHandle( xTaskGetCurrentTaskHandle() );

		vTaskSwitchContext();

		xTaskToResume = prvGetThreadHandle( xTaskGetCurrentTaskHandle() );
		if ( xTaskToSuspend != xTaskToResume )
		{
			/* Remember and switch the critical nesting. */
			prvSetTaskCriticalNesting( xTaskToSuspend, uxCriticalNesting );
			uxCriticalNesting = prvGetTaskCriticalNesting( xTaskToResume );
			/* Switch tasks. */
			prvResumeThread( xTaskToResume );
			prvSuspendThread( xTaskToSuspend );
		}
		else
		{
			/* Yielding to self */
			(void)pthread_mutex_unlock( &xSingleThreadMutex );
		}
	}
}
Esempio n. 2
0
void vPortStartFirstTask( void )
{
	/* Initialise the critical nesting count ready for the first task. */
	uxCriticalNesting = 0;

	/* Start the first task. */
	vPortEnableInterrupts();

	/* Start the first task. */
	prvResumeThread( prvGetThreadHandle( xTaskGetCurrentTaskHandle() ) );
}
Esempio n. 3
0
void vPortSystemTickHandler( int sig )
{
pthread_t xTaskToSuspend;
pthread_t xTaskToResume;

    (void)(sig);
	if ( ( pdTRUE == xInterruptsEnabled ) && ( pdTRUE != xServicingTick ) )
	{
		if ( 0 == pthread_mutex_trylock( &xSingleThreadMutex ) )
		{
			xServicingTick = pdTRUE;

			xTaskToSuspend = prvGetThreadHandle( xTaskGetCurrentTaskHandle() );
			/* Tick Increment. */
			xTaskIncrementTick();

			/* Select Next Task. */
#if ( configUSE_PREEMPTION == 1 )
			vTaskSwitchContext();
#endif
			xTaskToResume = prvGetThreadHandle( xTaskGetCurrentTaskHandle() );

			/* The only thread that can process this tick is the running thread. */
			if ( xTaskToSuspend != xTaskToResume )
			{
				/* Remember and switch the critical nesting. */
				prvSetTaskCriticalNesting( xTaskToSuspend, uxCriticalNesting );
				uxCriticalNesting = prvGetTaskCriticalNesting( xTaskToResume );
				/* Resume next task. */
				prvResumeThread( xTaskToResume );
				/* Suspend the current task. */
				prvSuspendThread( xTaskToSuspend );
			}
			else
			{
				/* Release the lock as we are Resuming. */
				(void)pthread_mutex_unlock( &xSingleThreadMutex );
			}
			xServicingTick = pdFALSE;
		}
		else
		{
			xPendYield = pdTRUE;
		}
	}
	else
	{
		xPendYield = pdTRUE;
	}
}
Esempio n. 4
0
void vPortForciblyEndThread( void *pxTaskToDelete )
{
xTaskHandle hTaskToDelete = ( xTaskHandle )pxTaskToDelete;
pthread_t xTaskToDelete;
pthread_t xTaskToResume;
portBASE_TYPE xResult;

	if ( 0 == pthread_mutex_lock( &xSingleThreadMutex ) )
	{
		xTaskToDelete = prvGetThreadHandle( hTaskToDelete );
		xTaskToResume = prvGetThreadHandle( xTaskGetCurrentTaskHandle() );

		if ( xTaskToResume == xTaskToDelete )
		{
			/* This is a suicidal thread, need to select a different task to run. */
			vTaskSwitchContext();
			xTaskToResume = prvGetThreadHandle( xTaskGetCurrentTaskHandle() );
		}

		if ( pthread_self() != xTaskToDelete )
		{
			/* Cancelling a thread that is not me. */
			if ( xTaskToDelete != ( pthread_t )NULL )
			{
				/* Send a signal to wake the task so that it definitely cancels. */
				pthread_testcancel();
				xResult = pthread_cancel( xTaskToDelete );
                if (xResult)
                    printf("pthread_cancel error!\n");
				/* Pthread Clean-up function will note the cancellation. */
			}
			(void)pthread_mutex_unlock( &xSingleThreadMutex );
		}
		else
		{
			/* Resume the other thread. */
			prvResumeThread( xTaskToResume );
			/* Pthread Clean-up function will note the cancellation. */
			/* Release the execution. */
			uxCriticalNesting = 0;
			vPortEnableInterrupts();
			(void)pthread_mutex_unlock( &xSingleThreadMutex );
			/* Commit suicide */
			pthread_exit( (void *)1 );
		}
	}
}