Posix port with pthread cond instead of signals

This commit is contained in:
Alfred Gedeon 2020-09-02 21:55:41 -07:00
parent 82fdc1c3ee
commit fb8820cfc2
3 changed files with 116 additions and 15 deletions

View file

@ -65,6 +65,7 @@
/* Scheduler includes. */ /* Scheduler includes. */
#include "FreeRTOS.h" #include "FreeRTOS.h"
#include "task.h" #include "task.h"
#include "utils/wait_for_event.h"
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#define SIG_RESUME SIGUSR1 #define SIG_RESUME SIGUSR1
@ -75,6 +76,7 @@ typedef struct THREAD
pdTASK_CODE pxCode; pdTASK_CODE pxCode;
void *pvParams; void *pvParams;
BaseType_t xDying; BaseType_t xDying;
struct event *ev;
} Thread_t; } Thread_t;
/* /*
@ -104,9 +106,10 @@ static portBASE_TYPE xSchedulerEnd = pdFALSE;
static void prvSetupSignalsAndSchedulerPolicy( void ); static void prvSetupSignalsAndSchedulerPolicy( void );
static void prvSetupTimerInterrupt( void ); static void prvSetupTimerInterrupt( void );
static void *prvWaitForStart( void * pvParams ); static void *prvWaitForStart( void * pvParams );
static void prvSwitchThread( Thread_t *xThreadToResume, Thread_t *xThreadToSuspend ); static void prvSwitchThread( Thread_t * xThreadToResume,
static void prvSuspendSelf( void ); Thread_t *xThreadToSuspend );
static void prvResumeThread( pthread_t xThreadId ); static void prvSuspendSelf( Thread_t * thread);
static void prvResumeThread( Thread_t * xThreadId );
static void vPortSystemTickHandler( int sig ); static void vPortSystemTickHandler( int sig );
static void vPortStartFirstTask( void ); static void vPortStartFirstTask( void );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -214,6 +217,8 @@ int iRet;
pthread_attr_init( &xThreadAttributes ); pthread_attr_init( &xThreadAttributes );
pthread_attr_setstack( &xThreadAttributes, pxEndOfStack, ulStackSize ); pthread_attr_setstack( &xThreadAttributes, pxEndOfStack, ulStackSize );
thread->ev = event_create();
vPortEnterCritical(); vPortEnterCritical();
iRet = pthread_create( &thread->pthread, &xThreadAttributes, iRet = pthread_create( &thread->pthread, &xThreadAttributes,
@ -234,10 +239,10 @@ void vPortStartFirstTask( void )
Thread_t *pxFirstThread = prvGetThreadFromTask( xTaskGetCurrentTaskHandle() ); Thread_t *pxFirstThread = prvGetThreadFromTask( xTaskGetCurrentTaskHandle() );
/* Start the first task. */ /* Start the first task. */
prvResumeThread( pxFirstThread->pthread ); prvResumeThread( pxFirstThread );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#include <unistd.h>
/* /*
* See header file for description. * See header file for description.
*/ */
@ -261,7 +266,8 @@ sigset_t xSignals;
while ( !xSchedulerEnd ) while ( !xSchedulerEnd )
{ {
sigwait( &xSignals, &iSignal ); //sigwait( &xSignals, &iSignal );
sleep(1);
} }
/* Restore original signal mask. */ /* Restore original signal mask. */
@ -294,7 +300,7 @@ struct sigaction sigtick;
xSchedulerEnd = pdTRUE; xSchedulerEnd = pdTRUE;
(void)pthread_kill( hMainThread, SIG_RESUME ); (void)pthread_kill( hMainThread, SIG_RESUME );
prvSuspendSelf(); //prvSuspendSelf();
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -473,7 +479,7 @@ static void *prvWaitForStart( void * pvParams )
{ {
Thread_t *pxThread = pvParams; Thread_t *pxThread = pvParams;
prvSuspendSelf(); prvSuspendSelf(pxThread);
/* Resumed for the first time, unblocks all signals. */ /* Resumed for the first time, unblocks all signals. */
uxCriticalNesting = 0; uxCriticalNesting = 0;
@ -502,19 +508,19 @@ BaseType_t uxSavedCriticalNesting;
*/ */
uxSavedCriticalNesting = uxCriticalNesting; uxSavedCriticalNesting = uxCriticalNesting;
prvResumeThread( pxThreadToResume->pthread ); prvResumeThread( pxThreadToResume );
if ( pxThreadToSuspend->xDying ) if ( pxThreadToSuspend->xDying )
{ {
pthread_exit( NULL ); pthread_exit( NULL );
} }
prvSuspendSelf(); prvSuspendSelf( pxThreadToSuspend );
uxCriticalNesting = uxSavedCriticalNesting; uxCriticalNesting = uxSavedCriticalNesting;
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvSuspendSelf( void ) static void prvSuspendSelf( Thread_t *thread )
{ {
int iSig; int iSig;
@ -531,16 +537,18 @@ int iSig;
* *
* - A thread with all signals blocked with pthread_sigmask(). * - A thread with all signals blocked with pthread_sigmask().
*/ */
sigwait( &xResumeSignals, &iSig ); event_wait(thread->ev);
//sigwait( &xResumeSignals, &iSig );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvResumeThread( pthread_t xThreadId ) static void prvResumeThread( Thread_t *xThreadId )
{ {
if ( pthread_self() != xThreadId ) if ( pthread_self() != xThreadId->pthread )
{ {
pthread_kill( xThreadId, SIG_RESUME ); //pthread_kill( xThreadId, SIG_RESUME );
event_signal(xThreadId->ev);
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -0,0 +1,75 @@
#include <pthread.h>
#include <stdlib.h>
#include <errno.h>
#include "wait_for_event.h"
struct event
{
pthread_mutex_t mutex;
pthread_cond_t cond;
bool event_triggered;
};
struct event * event_create()
{
struct event * ev = malloc( sizeof( struct event ) );
ev->event_triggered = false;
pthread_mutex_init( &ev->mutex, NULL );
pthread_cond_init( &ev->cond, NULL );
return ev;
}
void event_delete( struct event * ev )
{
pthread_mutex_destroy( &ev->mutex );
pthread_cond_destroy( &ev->cond );
free( ev );
}
bool event_wait( struct event * ev )
{
pthread_mutex_lock( &ev->mutex );
while( ev->event_triggered == false )
{
pthread_cond_wait( &ev->cond, &ev->mutex );
}
pthread_mutex_unlock( &ev->mutex );
return true;
}
bool event_wait_timed( struct event * ev,
time_t ms )
{
struct timespec ts;
int ret = 0;
clock_gettime( CLOCK_REALTIME, &ts );
//ts.tv_sec += ms;
ts.tv_nsec += (ms * 1000000);
pthread_mutex_lock( &ev->mutex );
while( (ev->event_triggered == false) && (ret == 0) )
{
ret = pthread_cond_timedwait( &ev->cond, &ev->mutex, &ts );
if( ( ret == -1 ) && ( errno == ETIMEDOUT ) )
{
return false;
}
}
ev->event_triggered = false;
pthread_mutex_unlock( &ev->mutex );
return true;
}
void event_signal( struct event * ev )
{
pthread_mutex_lock( &ev->mutex );
ev->event_triggered = true;
pthread_cond_signal( &ev->cond );
pthread_mutex_unlock( &ev->mutex );
}

View file

@ -0,0 +1,18 @@
#ifndef _WAIT_FOR_EVENT_H_
#define _WAIT_FOR_EVENT_H_
#include <stdbool.h>
#include <time.h>
struct event;
struct event * event_create();
void event_delete( struct event * );
bool event_wait( struct event * ev );
bool event_wait_timed( struct event * ev,
time_t ms );
void event_signal( struct event * ev );
#endif /* ifndef _WAIT_FOR_EVENT_H_ */