@@ -105,6 +105,8 @@ static BaseType_t xSchedulerEnd = pdFALSE;
105
105
static pthread_t hTimerTickThread ;
106
106
static bool xTimerTickThreadShouldRun ;
107
107
static uint64_t prvStartTimeNs ;
108
+ static pthread_mutex_t xThreadMutex = PTHREAD_MUTEX_INITIALIZER ;
109
+ static pthread_key_t xThreadKey = 0 ;
108
110
/*-----------------------------------------------------------*/
109
111
110
112
static void prvSetupSignalsAndSchedulerPolicy ( void );
@@ -119,6 +121,45 @@ static void vPortStartFirstTask( void );
119
121
static void prvPortYieldFromISR ( void );
120
122
/*-----------------------------------------------------------*/
121
123
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
+
122
163
static void prvFatalError ( const char * pcCall ,
123
164
int iErrno ) __attribute__( ( __noreturn__ ) );
124
165
@@ -249,6 +290,8 @@ BaseType_t xPortStartScheduler( void )
249
290
/* Restore original signal mask. */
250
291
( void ) pthread_sigmask ( SIG_SETMASK , & xSchedulerOriginalSignalMask , NULL );
251
292
293
+ prvDestroyThreadKey ();
294
+
252
295
return 0 ;
253
296
}
254
297
/*-----------------------------------------------------------*/
@@ -266,8 +309,12 @@ void vPortEndScheduler( void )
266
309
( void ) pthread_kill ( hMainThread , SIG_RESUME );
267
310
268
311
/* 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
+
271
318
pthread_testcancel ();
272
319
}
273
320
/*-----------------------------------------------------------*/
@@ -322,13 +369,19 @@ void vPortYield( void )
322
369
323
370
void vPortDisableInterrupts ( void )
324
371
{
325
- pthread_sigmask ( SIG_BLOCK , & xAllSignals , NULL );
372
+ if ( prvIsFreeRTOSThread ( pthread_self () ) == pdTRUE )
373
+ {
374
+ pthread_sigmask (SIG_BLOCK , & xAllSignals , NULL );
375
+ }
326
376
}
327
377
/*-----------------------------------------------------------*/
328
378
329
379
void vPortEnableInterrupts ( void )
330
380
{
331
- pthread_sigmask ( SIG_UNBLOCK , & xAllSignals , NULL );
381
+ if ( prvIsFreeRTOSThread ( pthread_self () ) == pdTRUE )
382
+ {
383
+ pthread_sigmask (SIG_UNBLOCK , & xAllSignals , NULL );
384
+ }
332
385
}
333
386
/*-----------------------------------------------------------*/
334
387
@@ -364,6 +417,8 @@ static void * prvTimerTickHandler( void * arg )
364
417
{
365
418
( void ) arg ;
366
419
420
+ prvMarkAsFreeRTOSThread ( pthread_self () );
421
+
367
422
prvPortSetCurrentThreadName ("Scheduler timer" );
368
423
369
424
while ( xTimerTickThreadShouldRun )
@@ -396,26 +451,31 @@ void prvSetupTimerInterrupt( void )
396
451
397
452
static void vPortSystemTickHandler ( int sig )
398
453
{
399
- Thread_t * pxThreadToSuspend ;
400
- Thread_t * pxThreadToResume ;
454
+ if ( prvIsFreeRTOSThread ( pthread_self () ) == pdTRUE )
455
+ {
456
+ Thread_t * pxThreadToSuspend ;
457
+ Thread_t * pxThreadToResume ;
401
458
402
- ( void ) sig ;
459
+ ( void ) sig ;
403
460
404
- uxCriticalNesting ++ ; /* Signals are blocked in this signal handler. */
461
+ uxCriticalNesting ++ ; /* Signals are blocked in this signal handler. */
405
462
406
- pxThreadToSuspend = prvGetThreadFromTask ( xTaskGetCurrentTaskHandle () );
463
+ pxThreadToSuspend = prvGetThreadFromTask ( xTaskGetCurrentTaskHandle () );
407
464
408
- if ( xTaskIncrementTick () != pdFALSE )
409
- {
410
- /* Select Next Task. */
411
- vTaskSwitchContext ();
465
+ if ( xTaskIncrementTick () != pdFALSE )
466
+ {
467
+ /* Select Next Task. */
468
+ vTaskSwitchContext ();
412
469
413
- pxThreadToResume = prvGetThreadFromTask ( xTaskGetCurrentTaskHandle () );
470
+ pxThreadToResume = prvGetThreadFromTask ( xTaskGetCurrentTaskHandle () );
414
471
415
- prvSwitchThread ( pxThreadToResume , pxThreadToSuspend );
416
- }
472
+ prvSwitchThread ( pxThreadToResume , pxThreadToSuspend );
473
+ }
417
474
418
- uxCriticalNesting -- ;
475
+ uxCriticalNesting -- ;
476
+ } else {
477
+ fprintf ( stderr , "vPortSystemTickHandler called from non-FreeRTOS thread\n" );
478
+ }
419
479
}
420
480
/*-----------------------------------------------------------*/
421
481
@@ -448,6 +508,8 @@ static void * prvWaitForStart( void * pvParams )
448
508
{
449
509
Thread_t * pxThread = pvParams ;
450
510
511
+ prvMarkAsFreeRTOSThread ( pthread_self () );
512
+
451
513
prvSuspendSelf ( pxThread );
452
514
453
515
/* Resumed for the first time, unblocks all signals. */
0 commit comments