void prvSuspendSignalHandler(int sig) { sigset_t xSignals; /* Only interested in the resume signal. */ sigemptyset( &xSignals ); sigaddset( &xSignals, SIG_RESUME ); xSentinel = 1; /* Unlock the Single thread mutex to allow the resumed task to continue. */ if ( 0 != pthread_mutex_unlock( &xSingleThreadMutex ) ) { printf( "Releasing someone else's lock.\n" ); } /* Wait on the resume signal. */ if ( 0 != sigwait( &xSignals, &sig ) ) { printf( "SSH: Sw %d\n", sig ); } /* Will resume here when the SIG_RESUME signal is received. */ /* Need to set the interrupts based on the task's critical nesting. */ if ( uxCriticalNesting == 0 ) { vPortEnableInterrupts(); } else { vPortDisableInterrupts(); } }
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() ) ); }
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 ); } } }
void prvDeleteThread( void *xThreadId ) { portLONG lIndex; for ( lIndex = 0; lIndex < MAX_NUMBER_OF_TASKS; lIndex++ ) { if ( pxThreads[ lIndex ].hThread == ( pthread_t )xThreadId ) { pxThreads[ lIndex ].hThread = (pthread_t)NULL; pxThreads[ lIndex ].hTask = (xTaskHandle)NULL; if ( pxThreads[ lIndex ].uxCriticalNesting > 0 ) { uxCriticalNesting = 0; vPortEnableInterrupts(); } pxThreads[ lIndex ].uxCriticalNesting = 0; break; } } }
void vPortExitCritical( void ) { /* Check for unmatched exits. */ if ( uxCriticalNesting > 0 ) { uxCriticalNesting--; } /* If we have reached 0 then re-enable the interrupts. */ if( uxCriticalNesting == 0 ) { /* Have we missed ticks? This is the equivalent of pending an interrupt. */ if ( pdTRUE == xPendYield ) { xPendYield = pdFALSE; vPortYield(); } vPortEnableInterrupts(); } }