@@ -102,14 +102,15 @@ static inline Thread_t * prvGetThreadFromTask( TaskHandle_t xTask )
102102
103103static pthread_once_t hSigSetupThread = PTHREAD_ONCE_INIT ;
104104static sigset_t xAllSignals ;
105- pthread_t xExternalThread ;
106105static sigset_t xSchedulerOriginalSignalMask ;
107106static pthread_t hMainThread = ( pthread_t ) NULL ;
108107static volatile BaseType_t uxCriticalNesting ;
109108static BaseType_t xSchedulerEnd = pdFALSE ;
110109static pthread_t hTimerTickThread ;
111110static bool xTimerTickThreadShouldRun ;
112111static uint64_t prvStartTimeNs ;
112+ static pthread_mutex_t xThreadMutex = PTHREAD_MUTEX_INITIALIZER ;
113+ static pthread_key_t xThreadKey = 0 ;
113114/*-----------------------------------------------------------*/
114115
115116static void prvSetupSignalsAndSchedulerPolicy ( void );
@@ -124,6 +125,44 @@ static void vPortStartFirstTask( void );
124125static void prvPortYieldFromISR ( void );
125126/*-----------------------------------------------------------*/
126127
128+ void prvThreadKeyDestructor ( void * data )
129+ {
130+ free ( data );
131+ }
132+
133+ static void prvInitThreadKey ()
134+ {
135+ pthread_mutex_lock ( & xThreadMutex );
136+
137+ if ( xThreadKey == 0 )
138+ {
139+ pthread_key_create ( & xThreadKey , prvThreadKeyDestructor );
140+ }
141+
142+ pthread_mutex_unlock ( & xThreadMutex );
143+ }
144+
145+ static void prvMarkAsFreeRTOSThread ( pthread_t thread )
146+ {
147+ prvInitThreadKey ();
148+ uint8_t * thread_data = malloc ( 1 );
149+ * thread_data = 1 ;
150+ pthread_setspecific ( xThreadKey , thread_data );
151+ }
152+
153+ static BaseType_t prvIsFreeRTOSThread ( pthread_t thread )
154+ {
155+ uint8_t * thread_data = ( uint8_t * ) pthread_getspecific ( xThreadKey );
156+
157+ return thread_data != NULL && * thread_data == 1 ;
158+ }
159+
160+ static void prvDestroyThreadKey ()
161+ {
162+ pthread_key_delete ( xThreadKey );
163+ }
164+ /*-----------------------------------------------------------*/
165+
127166static void prvFatalError ( const char * pcCall ,
128167 int iErrno ) __attribute__( ( __noreturn__ ) );
129168
@@ -206,24 +245,27 @@ void vPortStartFirstTask( void )
206245/*
207246 * Clear a signal that is pending for the calling thread.
208247 */
209- void prvClearPendingSignal ( int sig ) {
248+ void prvClearPendingSignal ( int sig )
249+ {
210250 sigset_t set , oldset ;
211251
212252 /* Block the signal */
213- sigemptyset (& set );
214- sigaddset (& set , sig );
215- pthread_sigmask (SIG_BLOCK , & set , & oldset );
253+ sigemptyset ( & set );
254+ sigaddset ( & set , sig );
255+ pthread_sigmask ( SIG_BLOCK , & set , & oldset );
216256
217257 /* Check if signal is pending */
218- sigpending (& set );
219- if (sigismember (& set , sig )) {
258+ sigpending ( & set );
259+
260+ if ( sigismember ( & set , sig ) )
261+ {
220262 int signum ;
221263 /* Wait for and remove signal */
222- sigwait (& set , & signum );
264+ sigwait ( & set , & signum );
223265 }
224266
225267 /* Restore the original signal mask */
226- pthread_sigmask (SIG_SETMASK , & oldset , NULL );
268+ pthread_sigmask ( SIG_SETMASK , & oldset , NULL );
227269}
228270/*-----------------------------------------------------------*/
229271
@@ -267,7 +309,7 @@ BaseType_t xPortStartScheduler( void )
267309 xSchedulerEnd = pdFALSE ;
268310
269311 /* Reset pthread_once_t, needed to restart the scheduler again.
270- * memset the internal struct members for MacOS/Linux Compatability */
312+ * memset the internal struct members for MacOS/Linux Compatibility */
271313 #if __APPLE__
272314 hSigSetupThread .__sig = _PTHREAD_ONCE_SIG_init ;
273315 memset ( ( void * ) & hSigSetupThread .__opaque , 0 , sizeof (hSigSetupThread .__opaque ));
@@ -281,6 +323,8 @@ BaseType_t xPortStartScheduler( void )
281323 /* Restore original signal mask. */
282324 ( void ) pthread_sigmask ( SIG_SETMASK , & xSchedulerOriginalSignalMask , NULL );
283325
326+ prvDestroyThreadKey ();
327+
284328 return 0 ;
285329}
286330/*-----------------------------------------------------------*/
@@ -298,10 +342,12 @@ void vPortEndScheduler( void )
298342 ( void ) pthread_kill ( hMainThread , SIG_RESUME );
299343
300344 /* Waiting to be deleted here. */
301- if ( xExternalThread != pthread_self () ) {
345+ if ( prvIsFreeRTOSThread ( pthread_self () ) == pdTRUE )
346+ {
302347 pxCurrentThread = prvGetThreadFromTask ( xTaskGetCurrentTaskHandle () );
303348 event_wait ( pxCurrentThread -> ev );
304349 }
350+
305351 pthread_testcancel ();
306352}
307353/*-----------------------------------------------------------*/
@@ -354,21 +400,20 @@ void vPortYield( void )
354400}
355401/*-----------------------------------------------------------*/
356402
357- void vPortSetExternalThread (pthread_t externalThread ) {
358- xExternalThread = externalThread ;
359- }
360- /*-----------------------------------------------------------*/
361-
362- void vPortDisableInterrupts (void ) {
363- if (pthread_self () == xExternalThread ) {
403+ void vPortDisableInterrupts ( void )
404+ {
405+ if ( prvIsFreeRTOSThread ( pthread_self () ) == pdFALSE )
406+ {
364407 return ;
365408 }
366409 pthread_sigmask (SIG_BLOCK , & xAllSignals , NULL );
367410}
368411/*-----------------------------------------------------------*/
369412
370- void vPortEnableInterrupts (void ) {
371- if (pthread_self () == xExternalThread ) {
413+ void vPortEnableInterrupts ( void )
414+ {
415+ if ( prvIsFreeRTOSThread ( pthread_self () ) == pdFALSE )
416+ {
372417 return ;
373418 }
374419 pthread_sigmask (SIG_UNBLOCK , & xAllSignals , NULL );
@@ -407,6 +452,8 @@ static void * prvTimerTickHandler( void * arg )
407452{
408453 ( void ) arg ;
409454
455+ prvMarkAsFreeRTOSThread ( pthread_self () );
456+
410457 prvPortSetCurrentThreadName ("Scheduler timer" );
411458
412459 while ( xTimerTickThreadShouldRun )
@@ -439,8 +486,9 @@ void prvSetupTimerInterrupt( void )
439486
440487static void vPortSystemTickHandler ( int sig )
441488{
442- if (pthread_self () == xExternalThread ) {
443- fprintf (stderr , "vPortSystemTickHandler called from non-FreeRTOS thread\n" );
489+ if ( prvIsFreeRTOSThread ( pthread_self () ) == pdFALSE )
490+ {
491+ fprintf ( stderr , "vPortSystemTickHandler called from non-FreeRTOS thread\n" );
444492 return ;
445493 }
446494
@@ -496,6 +544,8 @@ static void * prvWaitForStart( void * pvParams )
496544{
497545 Thread_t * pxThread = pvParams ;
498546
547+ prvMarkAsFreeRTOSThread ( pthread_self () );
548+
499549 prvSuspendSelf ( pxThread );
500550
501551 /* Resumed for the first time, unblocks all signals. */
0 commit comments