1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-02-21 11:54:15 +01:00

Pretty major rewrite which can either run with thread monitoring (windows) or with conditional waits. Definitions in file set mode, but robust for all modes on OSX, now for windows testing

git-svn-id: svn://svn.openpilot.org/OpenPilot/trunk@1054 ebee16cc-31ac-478f-84a7-5cbb03baadba
This commit is contained in:
peabody124 2010-07-10 06:25:33 +00:00 committed by peabody124
parent d23ac909db
commit db1dde5d8c

View File

@ -76,8 +76,9 @@
#define MAX_NUMBER_OF_TASKS ( _POSIX_THREAD_THREADS_MAX ) #define MAX_NUMBER_OF_TASKS ( _POSIX_THREAD_THREADS_MAX )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#define DB_P(x) // x //#define COND_SIGNALING
#define CHECK_TASK_RESUMES
//#define RUNNING_THREAD_MUTEX
/* Parameters to pass to the newly created pthread. */ /* Parameters to pass to the newly created pthread. */
typedef struct XPARAMS typedef struct XPARAMS
@ -90,9 +91,10 @@ typedef struct XPARAMS
typedef struct THREAD_SUSPENSIONS typedef struct THREAD_SUSPENSIONS
{ {
pthread_t hThread; pthread_t hThread;
pthread_cond_t hCond; pthread_cond_t * hCond;
pthread_mutex_t hMutex; pthread_mutex_t * hMutex;
xTaskHandle hTask; xTaskHandle hTask;
portBASE_TYPE xThreadState;
unsigned portBASE_TYPE uxCriticalNesting; unsigned portBASE_TYPE uxCriticalNesting;
} xThreadState; } xThreadState;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -100,16 +102,21 @@ typedef struct THREAD_SUSPENSIONS
static xThreadState *pxThreads; static xThreadState *pxThreads;
static pthread_once_t hSigSetupThread = PTHREAD_ONCE_INIT; static pthread_once_t hSigSetupThread = PTHREAD_ONCE_INIT;
static pthread_attr_t xThreadAttributes; static pthread_attr_t xThreadAttributes;
#ifdef RUNNING_THREAD_MUTEX
static pthread_mutex_t xRunningThread = PTHREAD_MUTEX_INITIALIZER;
#endif
static pthread_mutex_t xSuspendResumeThreadMutex = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t xSuspendResumeThreadMutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t xSingleThreadMutex = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t xSwappingThreadMutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_t hMainThread = ( pthread_t )NULL; static pthread_t hMainThread = ( pthread_t )NULL;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static volatile portBASE_TYPE xSentinel = 0; static volatile portBASE_TYPE xSentinel = 0;
static volatile portBASE_TYPE xRunning = pdFALSE;
static volatile portBASE_TYPE xSuspended = pdFALSE;
static volatile portBASE_TYPE xStarted = pdFALSE;
static volatile portBASE_TYPE xHandover = 0; static volatile portBASE_TYPE xHandover = 0;
static volatile portBASE_TYPE xSchedulerEnd = pdFALSE; static volatile portBASE_TYPE xSchedulerEnd = pdFALSE;
static volatile portBASE_TYPE xInterruptsEnabled = pdTRUE; static volatile portBASE_TYPE xInterruptsEnabled = pdTRUE;
static volatile portBASE_TYPE xInterruptsCurrent = pdTRUE;
static volatile portBASE_TYPE xServicingTick = pdFALSE; static volatile portBASE_TYPE xServicingTick = pdFALSE;
static volatile portBASE_TYPE xPendYield = pdFALSE; static volatile portBASE_TYPE xPendYield = pdFALSE;
static volatile portLONG lIndexOfLastAddedTask = 0; static volatile portLONG lIndexOfLastAddedTask = 0;
@ -121,34 +128,38 @@ static volatile unsigned portBASE_TYPE uxCriticalNesting;
*/ */
static void *prvWaitForStart( void * pvParams ); static void *prvWaitForStart( void * pvParams );
static void prvSuspendSignalHandler(int sig); static void prvSuspendSignalHandler(int sig);
//static void prvResumeSignalHandler(int sig);
static void prvSetupSignalsAndSchedulerPolicy( void ); static void prvSetupSignalsAndSchedulerPolicy( void );
static void prvSuspendThread( pthread_t xThreadId ); static void pauseThread( portBASE_TYPE pauseMode );
static void pauseThread();
//static void prvResumeThread( pthread_t xThreadId );
static pthread_t prvGetThreadHandle( xTaskHandle hTask ); static pthread_t prvGetThreadHandle( xTaskHandle hTask );
static pthread_cond_t prvGetThreadCondition( xTaskHandle hTask ); #ifdef COND_SIGNALING
static pthread_mutex_t prvGetThreadMutex( xTaskHandle hTask ); static pthread_cond_t * prvGetConditionHandle( xTaskHandle hTask );
static xTaskHandle prvGetThreadTask( pthread_t hThread ); static pthread_mutex_t * prvGetMutexHandle( xTaskHandle hTask );
#endif
static xTaskHandle prvGetTaskHandle( pthread_t hThread );
static portLONG prvGetFreeThreadState( void ); static portLONG prvGetFreeThreadState( void );
static void prvSetTaskCriticalNesting( pthread_t xThreadId, unsigned portBASE_TYPE uxNesting ); static void prvSetTaskCriticalNesting( pthread_t xThreadId, unsigned portBASE_TYPE uxNesting );
static unsigned portBASE_TYPE prvGetTaskCriticalNesting( pthread_t xThreadId ); static unsigned portBASE_TYPE prvGetTaskCriticalNesting( pthread_t xThreadId );
static void prvDeleteThread( void *xThreadId ); static void prvDeleteThread( void *xThreadId );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* /*
* Exception handlers. * Exception handlers.
*/ */
void vPortYield( void ); void vPortYield( void );
void vPortSystemTickHandler( int sig ); void vPortSystemTickHandler( int sig );
#define THREAD_STATE_PAUSED 0
#define THREAD_STATE_PAUSE 1
#define THREAD_PAUSE_CREATED 0
#define THREAD_PAUSE_YIELD 1
#define THREAD_PAUSE_INTERRUPT 2
//#define DEBUG_OUTPUT //#define DEBUG_OUTPUT
// static pthread_mutex_t xPrintfMutex = PTHREAD_MUTEX_INITIALIZER; //#define ERROR_OUTPUT
#ifdef DEBUG_OUTPUT #ifdef DEBUG_OUTPUT
static pthread_mutex_t xPrintfMutex = PTHREAD_MUTEX_INITIALIZER;
#define debug_printf(...) ( (real_pthread_mutex_lock( &xPrintfMutex )|1)?( \ #define debug_printf(...) ( (real_pthread_mutex_lock( &xPrintfMutex )|1)?( \
( \ ( \
@ -170,24 +181,30 @@ void vPortSystemTickHandler( int sig );
#define pthread_mutex_lock(...) ( (debug_printf(" -!- pthread_mutex_lock(%s)\n",#__VA_ARGS__)|1)?pthread_mutex_lock(__VA_ARGS__):0 ) #define pthread_mutex_lock(...) ( (debug_printf(" -!- pthread_mutex_lock(%s)\n",#__VA_ARGS__)|1)?pthread_mutex_lock(__VA_ARGS__):0 )
#define pthread_mutex_unlock(...) ( (debug_printf(" -=- pthread_mutex_unlock(%s)\n",#__VA_ARGS__)|1)?pthread_mutex_unlock(__VA_ARGS__):0 ) #define pthread_mutex_unlock(...) ( (debug_printf(" -=- pthread_mutex_unlock(%s)\n",#__VA_ARGS__)|1)?pthread_mutex_unlock(__VA_ARGS__):0 )
#define pthread_kill(thread,signal) ( (debug_printf("Sending signal %i to thread %li!\n",(int)signal,(long)thread)|1)?pthread_kill(thread,signal):0 ) #define pthread_kill(thread,signal) ( (debug_printf("Sending signal %i to thread %li!\n",(int)signal,(long)thread)|1)?pthread_kill(thread,signal):0 )
#else #define pthread_cond_signal( hCond ) (debug_printf( "pthread_cond_signals(%li)\r\n", *((long int *) hCond) ) ? 1 : pthread_cond_signal( hCond ) )
#define debug_error(...) ( (pthread_mutex_lock( &xPrintfMutex )|1)?( \ #define pthread_cond_timedwait( hCond, hMutex, it ) (debug_printf( "pthread_cond_timedwait(%li,%li)\r\n", *((long int *) hCond), *((long int *) hMutex )) ? 1 : pthread_cond_timedwait( hCond, hMutex, it ) )
( \ #define pthread_sigmask( how, set, out ) (debug_printf( "pthread_sigmask( %i, %li )\r\n", how, *((long int*) set) ) ? 1 : pthread_sigmask( how, set, out ) )
(NULL != (debug_task_handle = prvGetTaskHandle(pthread_self())) )? \
(fprintf( stderr, "%20s(%li)\t%20s\t%i: ",debug_task_handle->pcTaskName,(long)pthread_self(),__func__,__LINE__)): \
(fprintf( stderr, "%20s(%li)\t%20s\t%i: ","__unknown__",(long)pthread_self(),__func__,__LINE__)) \
|1)?( \
((fprintf( stderr, __VA_ARGS__ )|1)?pthread_mutex_unlock( &xPrintfMutex ):0) \
):0 ):0 )
#define debug_printf(...) #else
#ifdef ERROR_OUTPUT
static pthread_mutex_t xPrintfMutex = PTHREAD_MUTEX_INITIALIZER;
#define debug_error(...) ( (pthread_mutex_lock( &xPrintfMutex )|1)?( \
( \
(NULL != (debug_task_handle = prvGetTaskHandle(pthread_self())) )? \
(fprintf( stderr, "%20s(%li)\t%20s\t%i: ",debug_task_handle->pcTaskName,(long)pthread_self(),__func__,__LINE__)): \
(fprintf( stderr, "%20s(%li)\t%20s\t%i: ","__unknown__",(long)pthread_self(),__func__,__LINE__)) \
|1)?( \
((fprintf( stderr, __VA_ARGS__ )|1)?pthread_mutex_unlock( &xPrintfMutex ):0) \
):0 ):0 )
#define debug_printf(...)
#else
#define debug_printf(...)
#define debug_error(...)
#endif
#endif #endif
//#define debug_printf(...) fprintf( stderr, __VA_ARGS__ );
/* /*
* Start first task is a separate function so it can be tested in isolation. * Start first task is a separate function so it can be tested in isolation.
*/ */
@ -236,22 +253,6 @@ typedef struct tskTaskControlBlock
} tskTCB; } tskTCB;
tskTCB *debug_task_handle; tskTCB *debug_task_handle;
tskTCB * prvGetTaskHandle( pthread_t hThread )
{
portLONG lIndex;
if (pxThreads==NULL) return NULL;
for ( lIndex = 0; lIndex < MAX_NUMBER_OF_TASKS; lIndex++ )
{
if ( pxThreads[ lIndex ].hThread == hThread )
{
return pxThreads[ lIndex ].hTask;
}
}
return NULL;
}
/* /*
* See header file for description. * See header file for description.
@ -268,13 +269,7 @@ xParams *pxThisThreadParams = pvPortMalloc( sizeof( xParams ) );
if ( (pthread_t)NULL == hMainThread ) if ( (pthread_t)NULL == hMainThread )
{ {
hMainThread = pthread_self(); hMainThread = pthread_self();
} /*else { }
sigset_t xSignals;
sigemptyset( &xSignals );
sigaddset( &xSignals, SIG_TICK );
pthread_sigmask( SIG_BLOCK, &xSignals, NULL );
} */
/* No need to join the threads. */ /* No need to join the threads. */
pthread_attr_init( &xThreadAttributes ); pthread_attr_init( &xThreadAttributes );
@ -288,22 +283,26 @@ xParams *pxThisThreadParams = pvPortMalloc( sizeof( xParams ) );
lIndexOfLastAddedTask = prvGetFreeThreadState(); lIndexOfLastAddedTask = prvGetFreeThreadState();
debug_printf( "Got index for new task %i\r\n", lIndexOfLastAddedTask );
/* Create a condition signal for this thread */ /* Create a condition signal for this thread */
pthread_condattr_t condAttr; pthread_condattr_t condAttr;
assert( 0 == pthread_condattr_init(&condAttr) ); assert( 0 == pthread_condattr_init( &condAttr ) );
assert( 0 == pthread_cond_init( &( pxThreads[ lIndexOfLastAddedTask ].hCond ), &condAttr ) ); pxThreads[ lIndexOfLastAddedTask ].hCond = ( pthread_cond_t *) malloc( sizeof( pthread_cond_t ) );
assert( 0 == pthread_cond_init( pxThreads[ lIndexOfLastAddedTask ].hCond , &condAttr ) );
debug_printf("Cond: %li\r\n", *( (long int *) &pxThreads[ lIndexOfLastAddedTask ].hCond) );
/* Create a condition mutex for this thread */ /* Create a condition mutex for this thread */
pthread_mutexattr_t mutexAttr; pthread_mutexattr_t mutexAttr;
assert( 0 == pthread_mutexattr_init( &mutexAttr ) ); assert( 0 == pthread_mutexattr_init( &mutexAttr ) );
assert( 0 == pthread_mutexattr_settype( &mutexAttr, PTHREAD_MUTEX_ERRORCHECK ) ); assert( 0 == pthread_mutexattr_settype( &mutexAttr, PTHREAD_MUTEX_ERRORCHECK ) );
assert( 0 == pthread_mutex_init( &( pxThreads[ lIndexOfLastAddedTask ].hMutex ), &mutexAttr ) ); pxThreads[ lIndexOfLastAddedTask ].hMutex = ( pthread_mutex_t *) malloc( sizeof( pthread_mutex_t ) );
assert( 0 == pthread_mutex_init( pxThreads[ lIndexOfLastAddedTask ].hMutex, &mutexAttr ) );
debug_printf("Mutex: %li\r\n", *( (long int *) &pxThreads[ lIndexOfLastAddedTask ].hMutex) );
/* Create a thread and store it's handle number */ /* Create a thread and store it's handle number */
xSentinel = 0; xSentinel = 0;
assert( 0 == pthread_create( &( pxThreads[ lIndexOfLastAddedTask ].hThread ), &xThreadAttributes, prvWaitForStart, (void *)pxThisThreadParams ) ); assert( 0 == pthread_create( &( pxThreads[ lIndexOfLastAddedTask ].hThread ), &xThreadAttributes, prvWaitForStart, (void *)pxThisThreadParams ) );
/* Wait until the task suspends. */ /* Wait until the task suspends. */
while ( xSentinel == 0 ); while ( xSentinel == 0 );
@ -322,16 +321,13 @@ void vPortStartFirstTask( void )
/* Start the first task. */ /* Start the first task. */
vPortEnableInterrupts(); vPortEnableInterrupts();
xRunning = 1;
/* Start the first task. */ /* Start the first task. */
//prvResumeThread( prvGetThreadHandle( xTaskGetCurrentTaskHandle() ) ); #ifdef COND_SIGNALING
pthread_cond_t * hCond = prvGetConditionHandle( xTaskGetCurrentTaskHandle() );
debug_printf( "Sending resume signal to %li\r\n", (long int) prvGetThreadHandle( xTaskGetCurrentTaskHandle() ) ); assert( pthread_cond_signal( hCond ) == 0 );
// pthread_kill( prvGetThreadHandle( xTaskGetCurrentTaskHandle() ), SIG_RESUME ); #endif
// Set resume condition for specific thread
pthread_cond_t hCond = prvGetThreadCondition( xTaskGetCurrentTaskHandle() );
assert( pthread_cond_signal( &hCond ) == 0 );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -341,9 +337,7 @@ void vPortStartFirstTask( void )
portBASE_TYPE xPortStartScheduler( void ) portBASE_TYPE xPortStartScheduler( void )
{ {
portBASE_TYPE xResult; portBASE_TYPE xResult;
sigset_t xSignals;
sigset_t xSignalToBlock; sigset_t xSignalToBlock;
sigset_t xSignalsBlocked;
portLONG lIndex; portLONG lIndex;
debug_printf( "xPortStartScheduler\r\n" ); debug_printf( "xPortStartScheduler\r\n" );
@ -351,41 +345,32 @@ portLONG lIndex;
/* Establish the signals to block before they are needed. */ /* Establish the signals to block before they are needed. */
sigfillset( &xSignalToBlock ); sigfillset( &xSignalToBlock );
sigaddset( &xSignalToBlock, SIG_SUSPEND ); sigaddset( &xSignalToBlock, SIG_SUSPEND );
/* sigaddset( &xSignalToBlock, SIG_RESUME );
sigaddset( &xSignalToBlock, SIG_TICK ); */
/* Block until the end */ /* Block until the end */
(void)pthread_sigmask( SIG_SETMASK, &xSignalToBlock, &xSignalsBlocked ); (void)pthread_sigmask( SIG_SETMASK, &xSignalToBlock, NULL );
for ( lIndex = 0; lIndex < MAX_NUMBER_OF_TASKS; lIndex++ ) for ( lIndex = 0; lIndex < MAX_NUMBER_OF_TASKS; lIndex++ )
{ {
pxThreads[ lIndex ].uxCriticalNesting = 0; pxThreads[ lIndex ].uxCriticalNesting = 0;
} }
/* Start the timer that generates the tick ISR. Interrupts are disabled
here already. */
// prvSetupTimerInterrupt();
/* Start the first task. Will not return unless all threads are killed. */ /* Start the first task. Will not return unless all threads are killed. */
vPortStartFirstTask(); vPortStartFirstTask();
/* This is the end signal we are looking for. */ struct timespec x;
sigemptyset( &xSignals ); usleep(1000000);
sigaddset( &xSignals, SIG_RESUME );
while( pdTRUE != xSchedulerEnd ) { while( pdTRUE != xSchedulerEnd ) {
struct timespec x;
x.tv_sec=0; x.tv_sec=0;
x.tv_nsec=1000000; x.tv_nsec=portTICK_RATE_MICROSECONDS * 1000;
nanosleep(&x,NULL); nanosleep(&x,NULL);
//printf("."); fflush(stdout);
vPortSystemTickHandler(SIG_TICK); vPortSystemTickHandler(SIG_TICK);
} }
debug_printf( "Cleaning Up, Exiting.\n" ); debug_printf( "Cleaning Up, Exiting.\n" );
/* Cleanup the mutexes */ /* Cleanup the mutexes */
xResult = pthread_mutex_destroy( &xSuspendResumeThreadMutex ); xResult = pthread_mutex_destroy( &xSuspendResumeThreadMutex );
xResult = pthread_mutex_destroy( &xSingleThreadMutex ); xResult = pthread_mutex_destroy( &xSwappingThreadMutex );
vPortFree( (void *)pxThreads ); vPortFree( (void *)pxThreads );
/* Should not get here! */ /* Should not get here! */
@ -398,7 +383,6 @@ void vPortEndScheduler( void )
portBASE_TYPE xNumberOfThreads; portBASE_TYPE xNumberOfThreads;
portBASE_TYPE xResult; portBASE_TYPE xResult;
DB_P("vPortEndScheduler\r\n");
for ( xNumberOfThreads = 0; xNumberOfThreads < MAX_NUMBER_OF_TASKS; xNumberOfThreads++ ) for ( xNumberOfThreads = 0; xNumberOfThreads < MAX_NUMBER_OF_TASKS; xNumberOfThreads++ )
{ {
@ -418,20 +402,16 @@ portBASE_TYPE xResult;
void vPortYieldFromISR( void ) void vPortYieldFromISR( void )
{ {
/* Calling Yield from a Interrupt/Signal handler often doesn't work because the /* Calling Yield from a Interrupt/Signal handler often doesn't work because the
* xSingleThreadMutex is already owned by an original call to Yield. Therefore, * xSwappingThreadMutex is already owned by an original call to Yield. Therefore,
* simply indicate that a yield is required soon. * simply indicate that a yield is required soon.
*/ */
DB_P("vPortYieldFromISR\r\n");
xPendYield = pdTRUE; xPendYield = pdTRUE;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vPortEnterCritical( void ) void vPortEnterCritical( void )
{ {
DB_P("vPortEnterCritical\r\n");
vPortDisableInterrupts(); vPortDisableInterrupts();
uxCriticalNesting++; uxCriticalNesting++;
} }
@ -439,7 +419,6 @@ void vPortEnterCritical( void )
void vPortExitCritical( void ) void vPortExitCritical( void )
{ {
DB_P("vPortExitCritical\r\n");
/* Check for unmatched exits. */ /* Check for unmatched exits. */
if ( uxCriticalNesting > 0 ) if ( uxCriticalNesting > 0 )
{ {
@ -464,52 +443,86 @@ void vPortYield( void )
{ {
pthread_t xTaskToSuspend; pthread_t xTaskToSuspend;
pthread_t xTaskToResume; pthread_t xTaskToResume;
sigset_t xSignals;
tskTCB * oldTask, * newTask; tskTCB * oldTask, * newTask;
sigset_t xSignals;
/* We must mask the suspend signal here, because otherwise there can be an */
/* interrupt while in pthread_mutex_lock and that will cause the next thread */
/* to deadlock when it tries to get this mutex */
debug_printf( "Entering\r\n" );
sigemptyset( &xSignals ); sigemptyset( &xSignals );
sigaddset( &xSignals, SIG_TICK ); sigaddset( &xSignals, SIG_SUSPEND );
pthread_sigmask( SIG_BLOCK, &xSignals, NULL ); pthread_sigmask( SIG_SETMASK, &xSignals, NULL );
assert( pthread_mutex_lock( &xSwappingThreadMutex ) == 0);
oldTask = xTaskGetCurrentTaskHandle(); oldTask = xTaskGetCurrentTaskHandle();
xTaskToSuspend = prvGetThreadHandle( oldTask ); //xTaskGetCurrentTaskHandle() ); xTaskToSuspend = prvGetThreadHandle( xTaskGetCurrentTaskHandle() );
if(xTaskToSuspend != pthread_self() ) { if(xTaskToSuspend != pthread_self() ) {
printf( "Called from different thread (%li) than what it will suspend (%li(%s)). Probably reflects bad state\r\n", (long int) pthread_self(), (long int) xTaskToSuspend, oldTask->pcTaskName ); /* This means between masking the interrupt and getting the lock, there was an interrupt */
kill(getpid(), SIGKILL ); /* and this task should suspend. Release the lock, then unmask interrupts to go ahead and */
/* service the signal */
assert( 0 == pthread_mutex_unlock( &xSwappingThreadMutex ) );
debug_printf( "The current task isn't even us, letting interrupt happen. Watch for swap.\r\n" );
/* Now we are resuming, want to be able to catch this interrupt again */
sigemptyset( &xSignals );
pthread_sigmask( SIG_SETMASK, &xSignals, NULL);
return;
} }
xStarted = pdFALSE;
/* Get new task then release the task switching mutex */
vTaskSwitchContext(); vTaskSwitchContext();
newTask = xTaskGetCurrentTaskHandle(); newTask = xTaskGetCurrentTaskHandle();
xTaskToResume = prvGetThreadHandle( newTask ) ; //xTaskGetCurrentTaskHandle() ); xTaskToResume = prvGetThreadHandle( xTaskGetCurrentTaskHandle() );
if ( xTaskToSuspend != xTaskToResume ) if ( pthread_self() != xTaskToResume )
{ {
/* Remember and switch the critical nesting. */ /* Remember and switch the critical nesting. */
prvSetTaskCriticalNesting( xTaskToSuspend, uxCriticalNesting ); prvSetTaskCriticalNesting( xTaskToSuspend, uxCriticalNesting );
uxCriticalNesting = prvGetTaskCriticalNesting( xTaskToResume ); uxCriticalNesting = prvGetTaskCriticalNesting( xTaskToResume );
debug_error( "Swapping From %li(%s) to %li(%s)\r\n", (long int) xTaskToSuspend, oldTask->pcTaskName, (long int) xTaskToResume, newTask->pcTaskName);
/* Switch tasks. */ #ifdef COND_SIGNALING
debug_printf( "Yielding %li: From %li(%s) to %li(%s)\r\n",(long int) pthread_self(), (long int) xTaskToSuspend, oldTask->pcTaskName, (long int) xTaskToResume, newTask->pcTaskName); /* Set resume condition for specific thread */
prvSuspendThread( xTaskToSuspend ); pthread_cond_t * hCond = prvGetConditionHandle( xTaskGetCurrentTaskHandle() );
debug_printf( "Yielded %li: From %li(%s) to %li(%s)\r\n",(long int) pthread_self(), (long int) xTaskToSuspend, oldTask->pcTaskName, (long int) xTaskToResume, newTask->pcTaskName); assert( pthread_cond_signal( hCond ) == 0 );
#endif
#ifdef CHECK_TASK_RESUMES
while( xStarted == pdFALSE )
debug_printf( "Waiting for task to resume\r\n" );
#endif
debug_printf( "Detected task resuming. Pausing this task\r\n" );
/* Release swapping thread mutex and pause self */
assert( pthread_mutex_unlock( &xSwappingThreadMutex ) == 0);
pauseThread( THREAD_PAUSE_YIELD );
} }
else {
pthread_sigmask( SIG_UNBLOCK, &xSignals, NULL ); assert( pthread_mutex_unlock( &xSwappingThreadMutex ) == 0);
}
/* Now we are resuming, want to be able to catch this interrupt again */
sigemptyset( &xSignals );
pthread_sigmask( SIG_SETMASK, &xSignals, NULL);
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vPortDisableInterrupts( void ) void vPortDisableInterrupts( void )
{ {
DB_P("vPortDisableInterrupts\r\n"); //debug_printf("\r\n");
xInterruptsEnabled = pdFALSE; xInterruptsEnabled = pdFALSE;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vPortEnableInterrupts( void ) void vPortEnableInterrupts( void )
{ {
DB_P("vPortEnableInterrupts\r\n"); //debug_printf("\r\n");
xInterruptsEnabled = pdTRUE; xInterruptsEnabled = pdTRUE;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -517,7 +530,7 @@ void vPortEnableInterrupts( void )
portBASE_TYPE xPortSetInterruptMask( void ) portBASE_TYPE xPortSetInterruptMask( void )
{ {
portBASE_TYPE xReturn = xInterruptsEnabled; portBASE_TYPE xReturn = xInterruptsEnabled;
DB_P("vPortsetInterruptMask\r\n"); debug_printf("\r\n");
xInterruptsEnabled = pdFALSE; xInterruptsEnabled = pdFALSE;
return xReturn; return xReturn;
} }
@ -525,7 +538,7 @@ portBASE_TYPE xReturn = xInterruptsEnabled;
void vPortClearInterruptMask( portBASE_TYPE xMask ) void vPortClearInterruptMask( portBASE_TYPE xMask )
{ {
DB_P("vPortClearInterruptMask\r\n"); debug_printf("\r\n");
xInterruptsEnabled = xMask; xInterruptsEnabled = xMask;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -535,26 +548,21 @@ void vPortSystemTickHandler( int sig )
{ {
pthread_t xTaskToSuspend; pthread_t xTaskToSuspend;
pthread_t xTaskToResume; pthread_t xTaskToResume;
portBASE_TYPE xInterruptValue;
tskTCB * oldTask, * newTask; tskTCB * oldTask, * newTask;
int lockResult;
DB_P("vPortSystemTickHandler");
xInterruptValue = xInterruptsEnabled;
debug_printf( "\r\n\r\n" ); debug_printf( "\r\n\r\n" );
debug_printf( "(xInterruptsEnabled = %i, xServicingTick = %i)\r\n", (int) xInterruptValue != 0, (int) xServicingTick != 0); debug_printf( "(xInterruptsEnabled = %i, xServicingTick = %i)\r\n", (int) xInterruptsEnabled != 0, (int) xServicingTick != 0);
if ( ( pdTRUE == xInterruptValue ) && ( pdTRUE != xServicingTick ) ) if ( ( pdTRUE == xInterruptsEnabled ) && ( pdTRUE != xServicingTick ) )
{ {
// debug_printf( "Checking for lock ...\r\n" ); // debug_printf( "Checking for lock ...\r\n" );
// lockResult = pthread_mutex_trylock( &xSingleThreadMutex ); if ( 0 == pthread_mutex_trylock( &xSwappingThreadMutex ) )
lockResult = 0;
// debug_printf( "Done\r\n" );
if ( 0 == lockResult)
{ {
debug_printf( "Handling\r\n"); debug_printf( "Handling\r\n");
xServicingTick = pdTRUE; xServicingTick = pdTRUE;
oldTask = xTaskGetCurrentTaskHandle(); oldTask = xTaskGetCurrentTaskHandle();
xTaskToSuspend = prvGetThreadHandle( xTaskGetCurrentTaskHandle() ); xTaskToSuspend = prvGetThreadHandle( xTaskGetCurrentTaskHandle() );
/* Tick Increment. */ /* Tick Increment. */
vTaskIncrementTick(); vTaskIncrementTick();
@ -562,35 +570,62 @@ int lockResult;
#if ( configUSE_PREEMPTION == 1 ) #if ( configUSE_PREEMPTION == 1 )
vTaskSwitchContext(); vTaskSwitchContext();
#endif #endif
newTask = xTaskGetCurrentTaskHandle(); newTask = xTaskGetCurrentTaskHandle();
xTaskToResume = prvGetThreadHandle( xTaskGetCurrentTaskHandle() ); xTaskToResume = prvGetThreadHandle( xTaskGetCurrentTaskHandle() );
debug_printf( "Want %s running\r\n", newTask->pcTaskName );
/* The only thread that can process this tick is the running thread. */ /* The only thread that can process this tick is the running thread. */
if ( xTaskToSuspend != xTaskToResume ) if ( xTaskToSuspend != xTaskToResume )
{ {
xSuspended = pdFALSE;
xStarted = pdFALSE;
/* Remember and switch the critical nesting. */ /* Remember and switch the critical nesting. */
prvSetTaskCriticalNesting( xTaskToSuspend, uxCriticalNesting ); prvSetTaskCriticalNesting( xTaskToSuspend, uxCriticalNesting );
uxCriticalNesting = prvGetTaskCriticalNesting( xTaskToResume ); uxCriticalNesting = prvGetTaskCriticalNesting( xTaskToResume );
debug_printf( "Swapping From %li(%s) to %li(%s)\r\n", (long int) xTaskToSuspend, oldTask->pcTaskName, (long int) xTaskToResume, newTask->pcTaskName);
#ifdef CHECK_TASK_RESUMES
/* It shouldn't be possible for a second task swap to happen while waiting for this because */
/* they can't get the xSwappingThreadMutex */
while( xSuspended == pdFALSE )
#endif
{
assert( pthread_kill( xTaskToSuspend, SIG_SUSPEND ) == 0);
sched_yield();
}
debug_printf( "Swapping From %li(%s) to %li(%s)\r\n", (long int) xTaskToSuspend, oldTask->pcTaskName, (long int) xTaskToResume, newTask->pcTaskName); #ifdef CHECK_TASK_RESUMES
// prvResumeThread( xTaskToResume ); /* Resume next task. */ while( xStarted == pdFALSE)
prvSuspendThread( xTaskToSuspend ); /* Suspend the current task. */ #endif
debug_printf( "Swapped From %li(%s) to %li(%s)\r\n", (long int) xTaskToSuspend, oldTask->pcTaskName, (long int) xTaskToResume, newTask->pcTaskName); {
}
#ifdef COND_SIGNALING
// Set resume condition for specific thread
pthread_cond_t * hCond = prvGetConditionHandle( xTaskGetCurrentTaskHandle() );
assert( pthread_cond_signal( hCond ) == 0 );
#endif
assert( pthread_kill( xTaskToSuspend, SIG_SUSPEND ) == 0);
sched_yield();
}
debug_printf( "Swapped From %li(%s) to %li(%s)\r\n", (long int) xTaskToSuspend, oldTask->pcTaskName, (long int) xTaskToResume, newTask->pcTaskName); }
else else
{ {
debug_printf( "Resuming previous task\r\n" ); // debug_error ("Want %s running \r\n", newTask->pcTaskName );
/* Release the lock as we are Resuming. */
// (void)pthread_mutex_unlock( &xSingleThreadMutex );
} }
xServicingTick = pdFALSE; xServicingTick = pdFALSE;
(void)pthread_mutex_unlock( &xSwappingThreadMutex );
} }
else else
{ {
debug_printf( "Pending yield here (portYield has lock - hopefully)\r\n" ); debug_error( "Pending yield here (portYield has lock - hopefully)\r\n" );
xPendYield = pdTRUE; xPendYield = pdTRUE;
} }
} }
else else
{ {
@ -609,7 +644,7 @@ portBASE_TYPE xResult;
printf("vPortForciblyEndThread\r\n"); printf("vPortForciblyEndThread\r\n");
if ( 0 == pthread_mutex_lock( &xSingleThreadMutex ) ) if ( 0 == pthread_mutex_lock( &xSwappingThreadMutex ) )
{ {
xTaskToDelete = prvGetThreadHandle( hTaskToDelete ); xTaskToDelete = prvGetThreadHandle( hTaskToDelete );
xTaskToResume = prvGetThreadHandle( xTaskGetCurrentTaskHandle() ); xTaskToResume = prvGetThreadHandle( xTaskGetCurrentTaskHandle() );
@ -631,19 +666,19 @@ portBASE_TYPE xResult;
xResult = pthread_cancel( xTaskToDelete ); xResult = pthread_cancel( xTaskToDelete );
/* Pthread Clean-up function will note the cancellation. */ /* Pthread Clean-up function will note the cancellation. */
} }
(void)pthread_mutex_unlock( &xSingleThreadMutex ); (void)pthread_mutex_unlock( &xSwappingThreadMutex );
} }
else else
{ {
/* Resume the other thread. */ /* Resume the other thread. */
//prvResumeThread( xTaskToResume ); /* Assert zero - I never fixed this functionality */
assert( 0 ); assert( 0 );
/* Pthread Clean-up function will note the cancellation. */ /* Pthread Clean-up function will note the cancellation. */
/* Release the execution. */ /* Release the execution. */
uxCriticalNesting = 0; uxCriticalNesting = 0;
vPortEnableInterrupts(); vPortEnableInterrupts();
(void)pthread_mutex_unlock( &xSingleThreadMutex ); (void)pthread_mutex_unlock( &xSwappingThreadMutex );
/* Commit suicide */ /* Commit suicide */
pthread_exit( (void *)1 ); pthread_exit( (void *)1 );
} }
@ -659,8 +694,6 @@ void * pParams = pxParams->pvParams;
vPortFree( pvParams ); vPortFree( pvParams );
pthread_cleanup_push( prvDeleteThread, (void *)pthread_self() ); pthread_cleanup_push( prvDeleteThread, (void *)pthread_self() );
xSentinel = 1; // tell creating block to resume
/* want to block suspend when not the active thread */ /* want to block suspend when not the active thread */
sigset_t xSignals; sigset_t xSignals;
@ -668,18 +701,28 @@ void * pParams = pxParams->pvParams;
sigaddset( &xSignals, SIG_SUSPEND ); sigaddset( &xSignals, SIG_SUSPEND );
assert( pthread_sigmask( SIG_BLOCK, &xSignals, NULL ) == 0); assert( pthread_sigmask( SIG_BLOCK, &xSignals, NULL ) == 0);
/* Because the FreeRTOS creates the TCB stack, which in this implementation */
/* creates a thread, we need to wait until the task handle is added before */
/* trying to pause. Must set xSentinel high so the creating task knows we're */
/* here */
debug_printf("Thread started, waiting till handle is added\r\n");
xSentinel = 1;
while( prvGetTaskHandle( pthread_self() ) == NULL ){
sched_yield();
}
debug_printf("Handle added, pausing\r\n");
// wait for resume signal /* Want to delay briefly until we have explicit resume signal as otherwise the */
debug_printf("Pausing newly created thread for SIG_RESUME\r\n"); /* current task variable might be in the wrong state */
pauseThread(); pauseThread( THREAD_PAUSE_CREATED );
// no longer want to block any signals
sigemptyset( &xSignals );
assert( pthread_sigmask( SIG_SETMASK, &xSignals, NULL ) == 0);
debug_printf("Starting first run\r\n"); debug_printf("Starting first run\r\n");
//xHandover = 1; sigemptyset( &xSignals );
//assert ( 0 == pthread_mutex_lock( &xSingleThreadMutex ) ) assert( pthread_sigmask( SIG_SETMASK, &xSignals, NULL ) == 0);
pvCode( pParams ); pvCode( pParams );
@ -688,38 +731,96 @@ void * pParams = pxParams->pvParams;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void pauseThread() void pauseThread( portBASE_TYPE pauseMode )
{ {
printf("HERE\r\n"); debug_printf( "Pausing thread %li. Set xSuspended false\r\n", (long int) pthread_self() );
xTaskHandle hTask = prvGetThreadTask( pthread_self() );
pthread_cond_t hCond = prvGetThreadCondition( hTask ); #ifdef RUNNING_THREAD_MUTEX
pthread_mutex_t hMutex = prvGetThreadMutex( hTask ); if( pauseMode != THREAD_PAUSE_CREATED )
// while( !shouldResume ) { assert( 0 == pthread_mutex_unlock( &xRunningThread ) );
pthread_cond_wait( &hCond, &hMutex ); #endif
// }
#ifdef COND_SIGNALING
int xResult;
xTaskHandle hTask = prvGetTaskHandle( pthread_self() );
pthread_cond_t * hCond = prvGetConditionHandle( hTask );
pthread_mutex_t * hMutex = prvGetMutexHandle( hTask );
debug_printf("Cond: %li\r\n", *( (long int *) hCond) );
debug_printf("Mutex: %li\r\n", *( (long int *) hMutex) );
struct timeval tv;
struct timespec ts;
gettimeofday( &tv, NULL );
ts.tv_sec = tv.tv_sec + 0;
#endif
xSuspended = pdTRUE;
while (1) {
if( pthread_self() == prvGetThreadHandle(xTaskGetCurrentTaskHandle() ) && xRunning )
{
xStarted = pdTRUE;
#ifdef RUNNING_THREAD_MUTEX
assert( 0 == pthread_mutex_lock( &xRunningThread ) );
#endif
debug_error("Resuming\r\n");
return;
}
else {
#ifdef COND_SIGNALING
gettimeofday( &tv, NULL );
ts.tv_sec = ts.tv_sec + 1;
ts.tv_nsec = 0;
xResult = pthread_cond_timedwait( hCond, hMutex, &ts );
assert( xResult != EINVAL );
#else
/* For windows where conditional signaling is buggy */
/* It would be wonderful to put a nanosleep here, but since its not reentrant safe */
/* and there may be a sleep in the main code (this can be called from an ISR) we must */
/* check this */
if( pauseMode != THREAD_PAUSE_INTERRUPT )
usleep(100);
sched_yield();
#endif
// debug_error( "Checked my status\r\n" );
}
}
} }
void prvSuspendSignalHandler(int sig) void prvSuspendSignalHandler(int sig)
{ {
sigset_t xBlockSignals; sigset_t xBlockSignals;
/* This signal is set here instead of pauseThread because it is checked by the tick handler */
/* which means if there were a swap it should result in a suspend interrupt */
debug_error( "Caught signal %i\r\n", sig );
/* Check that we aren't suspending when we should be running. This bug would need tracking down */ /* Check that we aren't suspending when we should be running. This bug would need tracking down */
assert( pthread_self() != prvGetThreadHandle(xTaskGetCurrentTaskHandle() ) ); //assert( pthread_self() != prvGetThreadHandle(xTaskGetCurrentTaskHandle() ) );
if( pthread_self() == prvGetThreadHandle( xTaskGetCurrentTaskHandle() ) )
{
debug_printf( "Suspend ISR called while this thread still marked active. Reflects buggy behavior in scheduler\r\n" );
return;
}
/* Block further suspend signals. They need to go to their thread */ /* Block further suspend signals. They need to go to their thread */
sigemptyset( &xBlockSignals ); sigemptyset( &xBlockSignals );
sigaddset( &xBlockSignals, SIG_SUSPEND ); sigaddset( &xBlockSignals, SIG_SUSPEND );
assert( pthread_sigmask( SIG_BLOCK, &xBlockSignals, NULL ) == 0); assert( pthread_sigmask( SIG_BLOCK, &xBlockSignals, NULL ) == 0);
/* Unlock the Single thread mutex to allow the resumed task to continue. */
//assert ( 0 == pthread_mutex_unlock( &xSingleThreadMutex ) );
// Set resume condition for specific thread
pthread_cond_t hCond = prvGetThreadCondition( xTaskGetCurrentTaskHandle() );
assert( pthread_cond_signal( &hCond ) == 0 );
pauseThread();
pauseThread( THREAD_PAUSE_INTERRUPT );
assert( pthread_self() == prvGetThreadHandle( xTaskGetCurrentTaskHandle() ) );
while( pthread_self() != prvGetThreadHandle( xTaskGetCurrentTaskHandle() ) )
{
debug_printf( "Incorrectly woke up. Repausing\r\n" );
pauseThread( THREAD_PAUSE_INTERRUPT );
}
/* Make sure the right thread is resuming */ /* Make sure the right thread is resuming */
assert( pthread_self() == prvGetThreadHandle(xTaskGetCurrentTaskHandle() ) ); assert( pthread_self() == prvGetThreadHandle(xTaskGetCurrentTaskHandle() ) );
@ -745,69 +846,7 @@ sigset_t xBlockSignals;
} }
debug_printf("Exit\r\n"); debug_printf("Exit\r\n");
} }
/*-----------------------------------------------------------*/
void prvSuspendThread( pthread_t xThreadId )
{
debug_printf( "Suspending %li\r\n", (long int) xThreadId);
/* Set-up for the Suspend Signal handler? */
xSentinel = 0;
debug_printf( "About to kill %li\r\n", (long int) xThreadId );
assert( pthread_kill( xThreadId, SIG_SUSPEND ) == 0);
debug_printf( "Killed %li\r\n", (long int) xThreadId );
while ( ( xSentinel == 0 ) && ( pdTRUE != xServicingTick ) )
{
debug_printf( "sched_yield()\r\n" );
sched_yield();
}
}
/*-----------------------------------------------------------*/
/*void prvResumeSignalHandler(int sig)
{
DB_P("prvResumeSignalHandler\r\n");
debug_printf( "prvResumeSignalHandler getLock");
while(1);
// Yield the Scheduler to ensure that the yielding thread completes.
if ( 0 == pthread_mutex_lock( &xSingleThreadMutex ) )
{
debug_printf( "prvResumeSignalHandler: unlocking xSingleThreadMutex (%li)\r\n", (long int) pthread_self());
(void)pthread_mutex_unlock( &xSingleThreadMutex );
}
}*/
/*-----------------------------------------------------------*/
/*void prvResumeThread( pthread_t xThreadId )
{
portBASE_TYPE xResult;
DB_P("prvResumeThread\r\n");
debug_printf( "getLock\r\n" );
if ( 0 == pthread_mutex_lock( &xSuspendResumeThreadMutex ) )
{
debug_printf( "Resuming %li\r\n", (long int) xThreadId );
if ( pthread_self() != xThreadId )
{
//xResult = pthread_kill( xThreadId, SIG_RESUME );
debug_printf( "No longer doing anything. Suspend handler for previous thread should start %li\r\n", (long int) xThreadId );
}
else {
debug_printf( "Thread attempting to resume itself. This is not expected behavior\r\n" );
kill( getpid(), SIGKILL );
}
xResult = pthread_mutex_unlock( &xSuspendResumeThreadMutex );
}
else {
debug_printf("Error getting lock to resume thread\r\n");
kill( getpid(), SIGKILL );
}
} */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void prvSetupSignalsAndSchedulerPolicy( void ) void prvSetupSignalsAndSchedulerPolicy( void )
@ -839,17 +878,13 @@ portLONG lIndex;
sigsuspendself.sa_handler = prvSuspendSignalHandler; sigsuspendself.sa_handler = prvSuspendSignalHandler;
sigfillset( &sigsuspendself.sa_mask ); sigfillset( &sigsuspendself.sa_mask );
if ( 0 != sigaction( SIG_SUSPEND, &sigsuspendself, NULL ) ) assert ( 0 == sigaction( SIG_SUSPEND, &sigsuspendself, NULL ) );
{
printf( "Problem installing SIG_SUSPEND_SELF\n" );
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
pthread_mutex_t prvGetThreadMutex( xTaskHandle hTask ) pthread_mutex_t * prvGetMutexHandle( xTaskHandle hTask )
{ {
pthread_mutex_t hMutex; pthread_mutex_t * hMutex;
portLONG lIndex; portLONG lIndex;
for ( lIndex = 0; lIndex < MAX_NUMBER_OF_TASKS; lIndex++ ) for ( lIndex = 0; lIndex < MAX_NUMBER_OF_TASKS; lIndex++ )
@ -864,11 +899,14 @@ portLONG lIndex;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
xTaskHandle prvGetThreadTask( pthread_t hThread ) xTaskHandle prvGetTaskHandle( pthread_t hThread )
{ {
xTaskHandle hTask; xTaskHandle hTask = NULL;
portLONG lIndex; portLONG lIndex;
/* If not initialized yet */
if( pxThreads == NULL ) return NULL;
for ( lIndex = 0; lIndex < MAX_NUMBER_OF_TASKS; lIndex++ ) for ( lIndex = 0; lIndex < MAX_NUMBER_OF_TASKS; lIndex++ )
{ {
if ( pxThreads[ lIndex ].hThread == hThread ) if ( pxThreads[ lIndex ].hThread == hThread )
@ -878,22 +916,26 @@ portLONG lIndex;
} }
} }
return hTask; return hTask;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
pthread_cond_t prvGetThreadCondition( xTaskHandle hTask ) pthread_cond_t * prvGetConditionHandle( xTaskHandle hTask )
{ {
pthread_cond_t hCond; pthread_cond_t * hCond;
portLONG lIndex; portLONG lIndex;
for ( lIndex = 0; lIndex < MAX_NUMBER_OF_TASKS; lIndex++ ) for ( lIndex = 0; lIndex < MAX_NUMBER_OF_TASKS; lIndex++ )
{ {
if ( pxThreads[ lIndex ].hTask == hTask ) if ( pxThreads[ lIndex ].hTask == hTask )
{ {
hCond = pxThreads[ lIndex ].hCond; debug_printf( "Found condition on %i task\r\n", lIndex );
return pxThreads[ lIndex ].hCond;
break; break;
} }
} }
printf( "Failed to get handle, pausing then recursing\r\n" );
usleep(1000);
return prvGetConditionHandle( hTask );
assert(0);
return hCond; return hCond;
} }
@ -903,8 +945,6 @@ pthread_t prvGetThreadHandle( xTaskHandle hTask )
pthread_t hThread = ( pthread_t )NULL; pthread_t hThread = ( pthread_t )NULL;
portLONG lIndex; portLONG lIndex;
DB_P("prvGetThreadHandle\r\n");
for ( lIndex = 0; lIndex < MAX_NUMBER_OF_TASKS; lIndex++ ) for ( lIndex = 0; lIndex < MAX_NUMBER_OF_TASKS; lIndex++ )
{ {
if ( pxThreads[ lIndex ].hTask == hTask ) if ( pxThreads[ lIndex ].hTask == hTask )
@ -921,8 +961,6 @@ portLONG prvGetFreeThreadState( void )
{ {
portLONG lIndex; portLONG lIndex;
DB_P("prvGetFreeThreadState\r\n");
for ( lIndex = 0; lIndex < MAX_NUMBER_OF_TASKS; lIndex++ ) for ( lIndex = 0; lIndex < MAX_NUMBER_OF_TASKS; lIndex++ )
{ {
if ( pxThreads[ lIndex ].hThread == ( pthread_t )NULL ) if ( pxThreads[ lIndex ].hThread == ( pthread_t )NULL )
@ -945,7 +983,7 @@ portLONG lIndex;
void prvSetTaskCriticalNesting( pthread_t xThreadId, unsigned portBASE_TYPE uxNesting ) void prvSetTaskCriticalNesting( pthread_t xThreadId, unsigned portBASE_TYPE uxNesting )
{ {
portLONG lIndex; portLONG lIndex;
DB_P("prvSetTaskCriticalNesting\r\n");
for ( lIndex = 0; lIndex < MAX_NUMBER_OF_TASKS; lIndex++ ) for ( lIndex = 0; lIndex < MAX_NUMBER_OF_TASKS; lIndex++ )
{ {
if ( pxThreads[ lIndex ].hThread == xThreadId ) if ( pxThreads[ lIndex ].hThread == xThreadId )
@ -962,8 +1000,6 @@ unsigned portBASE_TYPE prvGetTaskCriticalNesting( pthread_t xThreadId )
unsigned portBASE_TYPE uxNesting = 0; unsigned portBASE_TYPE uxNesting = 0;
portLONG lIndex; portLONG lIndex;
DB_P("prvGetTaskCriticalNesting\r\n");
for ( lIndex = 0; lIndex < MAX_NUMBER_OF_TASKS; lIndex++ ) for ( lIndex = 0; lIndex < MAX_NUMBER_OF_TASKS; lIndex++ )
{ {
if ( pxThreads[ lIndex ].hThread == xThreadId ) if ( pxThreads[ lIndex ].hThread == xThreadId )
@ -980,8 +1016,6 @@ void prvDeleteThread( void *xThreadId )
{ {
portLONG lIndex; portLONG lIndex;
DB_P("prvDeleteThread\r\n");
for ( lIndex = 0; lIndex < MAX_NUMBER_OF_TASKS; lIndex++ ) for ( lIndex = 0; lIndex < MAX_NUMBER_OF_TASKS; lIndex++ )
{ {
if ( pxThreads[ lIndex ].hThread == ( pthread_t )xThreadId ) if ( pxThreads[ lIndex ].hThread == ( pthread_t )xThreadId )
@ -1019,16 +1053,16 @@ portLONG lIndex;
} }
} }
} }
usleep(10000);
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vPortFindTicksPerSecond( void ) void vPortFindTicksPerSecond( void )
{ {
DB_P("vPortFindTicksPerSecond\r\n");
/* Needs to be reasonably high for accuracy. */ /* Needs to be reasonably high for accuracy. */
//unsigned long ulTicksPerSecond = sysconf(_SC_CLK_TCK); unsigned long ulTicksPerSecond = sysconf(_SC_CLK_TCK);
//printf( "Timer Resolution for Run TimeStats is %ld ticks per second.\n", ulTicksPerSecond ); printf( "Timer Resolution for Run TimeStats is %ld ticks per second.\n", ulTicksPerSecond );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -1036,8 +1070,6 @@ unsigned long ulPortGetTimerValue( void )
{ {
struct tms xTimes; struct tms xTimes;
DB_P("ulPortGetTimerValue\r\n");
unsigned long ulTotalTime = times( &xTimes ); unsigned long ulTotalTime = times( &xTimes );
/* Return the application code times. /* Return the application code times.
* The timer only increases when the application code is actually running * The timer only increases when the application code is actually running