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