mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-12-07 05:34:59 -05:00
Merge branch 'main' into update-cmm_posix-reinit
This commit is contained in:
commit
7792539a7e
1 changed files with 79 additions and 60 deletions
139
portable/ThirdParty/GCC/Posix/port.c
vendored
139
portable/ThirdParty/GCC/Posix/port.c
vendored
|
|
@ -60,6 +60,7 @@
|
|||
#include <sys/time.h>
|
||||
#include <sys/times.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <mach/mach_vm.h>
|
||||
|
|
@ -68,6 +69,7 @@
|
|||
/* Scheduler includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "list.h"
|
||||
#include "timers.h"
|
||||
#include "utils/wait_for_event.h"
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
@ -81,6 +83,7 @@ typedef struct THREAD
|
|||
void * pvParams;
|
||||
BaseType_t xDying;
|
||||
struct event * ev;
|
||||
ListItem_t xThreadListItem;
|
||||
} Thread_t;
|
||||
|
||||
/*
|
||||
|
|
@ -101,9 +104,11 @@ static sigset_t xAllSignals;
|
|||
static sigset_t xSchedulerOriginalSignalMask;
|
||||
static pthread_t hMainThread = ( pthread_t ) NULL;
|
||||
static volatile BaseType_t uxCriticalNesting;
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static BaseType_t xSchedulerEnd = pdFALSE;
|
||||
static pthread_t hTimerTickThread;
|
||||
static bool xTimerTickThreadShouldRun;
|
||||
static uint64_t prvStartTimeNs;
|
||||
static List_t xThreadList;
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvSetupSignalsAndSchedulerPolicy( void );
|
||||
|
|
@ -127,6 +132,7 @@ void prvFatalError( const char * pcCall,
|
|||
fprintf( stderr, "%s: %s\n", pcCall, strerror( iErrno ) );
|
||||
abort();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* See header file for description.
|
||||
|
|
@ -163,19 +169,27 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
|||
thread->pvParams = pvParameters;
|
||||
thread->xDying = pdFALSE;
|
||||
|
||||
/* Ensure ulStackSize is at least PTHREAD_STACK_MIN */
|
||||
ulStackSize = (ulStackSize < PTHREAD_STACK_MIN) ? PTHREAD_STACK_MIN : ulStackSize;
|
||||
|
||||
pthread_attr_init( &xThreadAttributes );
|
||||
iRet = pthread_attr_setstack( &xThreadAttributes, pxEndOfStack, ulStackSize );
|
||||
iRet = pthread_attr_setstacksize( &xThreadAttributes, ulStackSize );
|
||||
|
||||
if( iRet != 0 )
|
||||
{
|
||||
fprintf( stderr, "[WARN] pthread_attr_setstack failed with return value: %d. Default stack will be used.\n", iRet );
|
||||
fprintf( stderr, "[WARN] Increase the stack size to PTHREAD_STACK_MIN.\n" );
|
||||
fprintf( stderr, "[WARN] pthread_attr_setstacksize failed with return value: %d. Default stack size will be used.\n", iRet );
|
||||
}
|
||||
|
||||
thread->ev = event_create();
|
||||
|
||||
vListInitialiseItem( &thread->xThreadListItem );
|
||||
listSET_LIST_ITEM_OWNER( &thread->xThreadListItem, thread );
|
||||
|
||||
vPortEnterCritical();
|
||||
|
||||
/* Add the new thread in xThreadList. */
|
||||
vListInsertEnd( &xThreadList, &thread->xThreadListItem );
|
||||
|
||||
iRet = pthread_create( &thread->pthread, &xThreadAttributes,
|
||||
prvWaitForStart, thread );
|
||||
|
||||
|
|
@ -206,6 +220,8 @@ BaseType_t xPortStartScheduler( void )
|
|||
{
|
||||
int iSignal;
|
||||
sigset_t xSignals;
|
||||
ListItem_t * pxIterator;
|
||||
const ListItem_t * pxEndMarker;
|
||||
|
||||
hMainThread = pthread_self();
|
||||
|
||||
|
|
@ -231,15 +247,28 @@ BaseType_t xPortStartScheduler( void )
|
|||
sigwait( &xSignals, &iSignal );
|
||||
}
|
||||
|
||||
/* Cancel the Idle task and free its resources */
|
||||
#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 )
|
||||
vPortCancelThread( xTaskGetIdleTaskHandle() );
|
||||
#endif
|
||||
/* Cancel all the running thread. */
|
||||
pxEndMarker = listGET_END_MARKER( &xThreadList );
|
||||
|
||||
#if ( configUSE_TIMERS == 1 )
|
||||
/* Cancel the Timer task and free its resources */
|
||||
vPortCancelThread( xTimerGetTimerDaemonTaskHandle() );
|
||||
#endif /* configUSE_TIMERS */
|
||||
for( pxIterator = listGET_HEAD_ENTRY( &xThreadList ); pxIterator != pxEndMarker; pxIterator = listGET_NEXT( pxIterator ) )
|
||||
{
|
||||
Thread_t * pxThread = ( Thread_t * ) listGET_LIST_ITEM_OWNER( pxIterator );
|
||||
|
||||
pthread_cancel( pxThread->pthread );
|
||||
event_signal( pxThread->ev );
|
||||
pthread_join( pxThread->pthread, NULL );
|
||||
event_delete( pxThread->ev );
|
||||
}
|
||||
|
||||
/*
|
||||
* clear out the variable that is used to end the scheduler, otherwise
|
||||
* subsequent scheduler restarts will end immediately.
|
||||
*/
|
||||
xSchedulerEnd = pdFALSE;
|
||||
|
||||
/* Reset the pthread_once_t structure. This is required if the port
|
||||
* starts the scheduler again. */
|
||||
hSigSetupThread = PTHREAD_ONCE_INIT;
|
||||
|
||||
/* Restore original signal mask. */
|
||||
( void ) pthread_sigmask( SIG_SETMASK, &xSchedulerOriginalSignalMask, NULL );
|
||||
|
|
@ -250,30 +279,15 @@ BaseType_t xPortStartScheduler( void )
|
|||
|
||||
void vPortEndScheduler( void )
|
||||
{
|
||||
struct itimerval itimer;
|
||||
struct sigaction sigtick;
|
||||
Thread_t * xCurrentThread;
|
||||
|
||||
/* Stop the timer and ignore any pending SIGALRMs that would end
|
||||
* up running on the main thread when it is resumed. */
|
||||
itimer.it_value.tv_sec = 0;
|
||||
itimer.it_value.tv_usec = 0;
|
||||
|
||||
itimer.it_interval.tv_sec = 0;
|
||||
itimer.it_interval.tv_usec = 0;
|
||||
( void ) setitimer( ITIMER_REAL, &itimer, NULL );
|
||||
|
||||
sigtick.sa_flags = 0;
|
||||
sigtick.sa_handler = SIG_IGN;
|
||||
sigemptyset( &sigtick.sa_mask );
|
||||
sigaction( SIGALRM, &sigtick, NULL );
|
||||
/* Stop the timer tick thread. */
|
||||
xTimerTickThreadShouldRun = false;
|
||||
pthread_join( hTimerTickThread, NULL );
|
||||
|
||||
/* Signal the scheduler to exit its loop. */
|
||||
xSchedulerEnd = pdTRUE;
|
||||
( void ) pthread_kill( hMainThread, SIG_RESUME );
|
||||
|
||||
xCurrentThread = prvGetThreadFromTask( xTaskGetCurrentTaskHandle() );
|
||||
prvSuspendSelf( xCurrentThread );
|
||||
pthread_exit( NULL );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
|
@ -359,45 +373,39 @@ static uint64_t prvGetTimeNs( void )
|
|||
|
||||
return ( uint64_t ) t.tv_sec * ( uint64_t ) 1000000000UL + ( uint64_t ) t.tv_nsec;
|
||||
}
|
||||
|
||||
static uint64_t prvStartTimeNs;
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* commented as part of the code below in vPortSystemTickHandler,
|
||||
* to adjust timing according to full demo requirements */
|
||||
/* static uint64_t prvTickCount; */
|
||||
|
||||
static void * prvTimerTickHandler( void * arg )
|
||||
{
|
||||
( void ) arg;
|
||||
|
||||
while( xTimerTickThreadShouldRun )
|
||||
{
|
||||
/*
|
||||
* signal to the active task to cause tick handling or
|
||||
* preemption (if enabled)
|
||||
*/
|
||||
Thread_t * thread = prvGetThreadFromTask( xTaskGetCurrentTaskHandle() );
|
||||
pthread_kill( thread->pthread, SIGALRM );
|
||||
usleep( portTICK_RATE_MICROSECONDS );
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Setup the systick timer to generate the tick interrupts at the required
|
||||
* frequency.
|
||||
*/
|
||||
void prvSetupTimerInterrupt( void )
|
||||
{
|
||||
struct itimerval itimer;
|
||||
int iRet;
|
||||
|
||||
/* Initialise the structure with the current timer information. */
|
||||
iRet = getitimer( ITIMER_REAL, &itimer );
|
||||
|
||||
if( iRet == -1 )
|
||||
{
|
||||
prvFatalError( "getitimer", errno );
|
||||
}
|
||||
|
||||
/* Set the interval between timer events. */
|
||||
itimer.it_interval.tv_sec = 0;
|
||||
itimer.it_interval.tv_usec = portTICK_RATE_MICROSECONDS;
|
||||
|
||||
/* Set the current count-down. */
|
||||
itimer.it_value.tv_sec = 0;
|
||||
itimer.it_value.tv_usec = portTICK_RATE_MICROSECONDS;
|
||||
|
||||
/* Set-up the timer interrupt. */
|
||||
iRet = setitimer( ITIMER_REAL, &itimer, NULL );
|
||||
|
||||
if( iRet == -1 )
|
||||
{
|
||||
prvFatalError( "setitimer", errno );
|
||||
}
|
||||
xTimerTickThreadShouldRun = true;
|
||||
pthread_create( &hTimerTickThread, NULL, prvTimerTickHandler, NULL );
|
||||
|
||||
prvStartTimeNs = prvGetTimeNs();
|
||||
}
|
||||
|
|
@ -454,15 +462,22 @@ void vPortThreadDying( void * pxTaskToDelete,
|
|||
|
||||
pxThread->xDying = pdTRUE;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortCancelThread( void * pxTaskToDelete )
|
||||
{
|
||||
Thread_t * pxThreadToCancel = prvGetThreadFromTask( pxTaskToDelete );
|
||||
|
||||
/* Remove the thread from xThreadList. */
|
||||
vPortEnterCritical();
|
||||
uxListRemove( &pxThreadToCancel->xThreadListItem );
|
||||
vPortExitCritical();
|
||||
|
||||
/*
|
||||
* The thread has already been suspended so it can be safely cancelled.
|
||||
*/
|
||||
pthread_cancel( pxThreadToCancel->pthread );
|
||||
event_signal( pxThreadToCancel->ev );
|
||||
pthread_join( pxThreadToCancel->pthread, NULL );
|
||||
event_delete( pxThreadToCancel->ev );
|
||||
}
|
||||
|
|
@ -538,6 +553,7 @@ static void prvSuspendSelf( Thread_t * thread )
|
|||
* - A thread with all signals blocked with pthread_sigmask().
|
||||
*/
|
||||
event_wait( thread->ev );
|
||||
pthread_testcancel();
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
@ -558,6 +574,9 @@ static void prvSetupSignalsAndSchedulerPolicy( void )
|
|||
|
||||
hMainThread = pthread_self();
|
||||
|
||||
/* Setup thread list to record all the task which are not deleted. */
|
||||
vListInitialise( &xThreadList );
|
||||
|
||||
/* Initialise common signal masks. */
|
||||
sigfillset( &xAllSignals );
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue