@@ -105,6 +105,8 @@ static BaseType_t xSchedulerEnd = pdFALSE;
105105static pthread_t hTimerTickThread ;
106106static bool xTimerTickThreadShouldRun ;
107107static uint64_t prvStartTimeNs ;
108+ static pthread_mutex_t xThreadMutex = PTHREAD_MUTEX_INITIALIZER ;
109+ static pthread_key_t xThreadKey = 0 ;
108110/*-----------------------------------------------------------*/
109111
110112static void prvSetupSignalsAndSchedulerPolicy ( void );
@@ -119,6 +121,45 @@ static void vPortStartFirstTask( void );
119121static void prvPortYieldFromISR ( void );
120122/*-----------------------------------------------------------*/
121123
124+ void prvThreadKeyDestructor ( void * data )
125+ {
126+ free ( data );
127+ }
128+
129+ static void prvInitThreadKey ()
130+ {
131+ pthread_mutex_lock ( & xThreadMutex );
132+
133+ if ( xThreadKey == 0 )
134+ {
135+ pthread_key_create ( & xThreadKey , prvThreadKeyDestructor );
136+ }
137+
138+ pthread_mutex_unlock ( & xThreadMutex );
139+ }
140+
141+ static void prvMarkAsFreeRTOSThread ( pthread_t thread )
142+ {
143+ prvInitThreadKey ();
144+ uint8_t * thread_data = malloc ( 1 );
145+ configASSERT ( thread_data != NULL );
146+ * thread_data = 1 ;
147+ pthread_setspecific ( xThreadKey , thread_data );
148+ }
149+
150+ static BaseType_t prvIsFreeRTOSThread ( pthread_t thread )
151+ {
152+ uint8_t * thread_data = ( uint8_t * ) pthread_getspecific ( xThreadKey );
153+
154+ return thread_data != NULL && * thread_data == 1 ;
155+ }
156+
157+ static void prvDestroyThreadKey ()
158+ {
159+ pthread_key_delete ( xThreadKey );
160+ }
161+ /*-----------------------------------------------------------*/
162+
122163static void prvFatalError ( const char * pcCall ,
123164 int iErrno ) __attribute__( ( __noreturn__ ) );
124165
@@ -249,6 +290,8 @@ BaseType_t xPortStartScheduler( void )
249290 /* Restore original signal mask. */
250291 ( void ) pthread_sigmask ( SIG_SETMASK , & xSchedulerOriginalSignalMask , NULL );
251292
293+ prvDestroyThreadKey ();
294+
252295 return 0 ;
253296}
254297/*-----------------------------------------------------------*/
@@ -266,8 +309,12 @@ void vPortEndScheduler( void )
266309 ( void ) pthread_kill ( hMainThread , SIG_RESUME );
267310
268311 /* Waiting to be deleted here. */
269- pxCurrentThread = prvGetThreadFromTask ( xTaskGetCurrentTaskHandle () );
270- event_wait ( pxCurrentThread -> ev );
312+ if ( prvIsFreeRTOSThread ( pthread_self () ) == pdTRUE )
313+ {
314+ pxCurrentThread = prvGetThreadFromTask ( xTaskGetCurrentTaskHandle () );
315+ event_wait ( pxCurrentThread -> ev );
316+ }
317+
271318 pthread_testcancel ();
272319}
273320/*-----------------------------------------------------------*/
@@ -322,13 +369,19 @@ void vPortYield( void )
322369
323370void vPortDisableInterrupts ( void )
324371{
325- pthread_sigmask ( SIG_BLOCK , & xAllSignals , NULL );
372+ if ( prvIsFreeRTOSThread ( pthread_self () ) == pdTRUE )
373+ {
374+ pthread_sigmask (SIG_BLOCK , & xAllSignals , NULL );
375+ }
326376}
327377/*-----------------------------------------------------------*/
328378
329379void vPortEnableInterrupts ( void )
330380{
331- pthread_sigmask ( SIG_UNBLOCK , & xAllSignals , NULL );
381+ if ( prvIsFreeRTOSThread ( pthread_self () ) == pdTRUE )
382+ {
383+ pthread_sigmask (SIG_UNBLOCK , & xAllSignals , NULL );
384+ }
332385}
333386/*-----------------------------------------------------------*/
334387
@@ -364,6 +417,8 @@ static void * prvTimerTickHandler( void * arg )
364417{
365418 ( void ) arg ;
366419
420+ prvMarkAsFreeRTOSThread ( pthread_self () );
421+
367422 prvPortSetCurrentThreadName ("Scheduler timer" );
368423
369424 while ( xTimerTickThreadShouldRun )
@@ -396,26 +451,31 @@ void prvSetupTimerInterrupt( void )
396451
397452static void vPortSystemTickHandler ( int sig )
398453{
399- Thread_t * pxThreadToSuspend ;
400- Thread_t * pxThreadToResume ;
454+ if ( prvIsFreeRTOSThread ( pthread_self () ) == pdTRUE )
455+ {
456+ Thread_t * pxThreadToSuspend ;
457+ Thread_t * pxThreadToResume ;
401458
402- ( void ) sig ;
459+ ( void ) sig ;
403460
404- uxCriticalNesting ++ ; /* Signals are blocked in this signal handler. */
461+ uxCriticalNesting ++ ; /* Signals are blocked in this signal handler. */
405462
406- pxThreadToSuspend = prvGetThreadFromTask ( xTaskGetCurrentTaskHandle () );
463+ pxThreadToSuspend = prvGetThreadFromTask ( xTaskGetCurrentTaskHandle () );
407464
408- if ( xTaskIncrementTick () != pdFALSE )
409- {
410- /* Select Next Task. */
411- vTaskSwitchContext ();
465+ if ( xTaskIncrementTick () != pdFALSE )
466+ {
467+ /* Select Next Task. */
468+ vTaskSwitchContext ();
412469
413- pxThreadToResume = prvGetThreadFromTask ( xTaskGetCurrentTaskHandle () );
470+ pxThreadToResume = prvGetThreadFromTask ( xTaskGetCurrentTaskHandle () );
414471
415- prvSwitchThread ( pxThreadToResume , pxThreadToSuspend );
416- }
472+ prvSwitchThread ( pxThreadToResume , pxThreadToSuspend );
473+ }
417474
418- uxCriticalNesting -- ;
475+ uxCriticalNesting -- ;
476+ } else {
477+ fprintf ( stderr , "vPortSystemTickHandler called from non-FreeRTOS thread\n" );
478+ }
419479}
420480/*-----------------------------------------------------------*/
421481
@@ -448,6 +508,8 @@ static void * prvWaitForStart( void * pvParams )
448508{
449509 Thread_t * pxThread = pvParams ;
450510
511+ prvMarkAsFreeRTOSThread ( pthread_self () );
512+
451513 prvSuspendSelf ( pxThread );
452514
453515 /* Resumed for the first time, unblocks all signals. */
0 commit comments