[PATCH 3/3] posix: Allow pthread_cancel() from within ISRs
Gedare Bloom
gedare at rtems.org
Fri May 21 04:00:11 UTC 2021
These looked ok to me, I skimmed before but forgot to ACK...
On Mon, May 17, 2021 at 7:07 AM Sebastian Huber
<sebastian.huber at embedded-brains.de> wrote:
>
> Close #4413.
> ---
> cpukit/posix/src/cancel.c | 13 ++---
> testsuites/psxtests/psxcancel01/init.c | 72 +++++++++++++++-----------
> 2 files changed, 45 insertions(+), 40 deletions(-)
>
> diff --git a/cpukit/posix/src/cancel.c b/cpukit/posix/src/cancel.c
> index f2636e6a97..aa4a434037 100644
> --- a/cpukit/posix/src/cancel.c
> +++ b/cpukit/posix/src/cancel.c
> @@ -38,14 +38,6 @@ int pthread_cancel( pthread_t thread )
> Thread_Control *executing;
> Per_CPU_Control *cpu_self;
>
> - /*
> - * Don't even think about deleting a resource from an ISR.
> - */
But I really appreciated the irony of removing this comment.
> -
> - if ( _ISR_Is_in_progress() ) {
> - return EPROTO;
> - }
> -
> the_thread = _Thread_Get( thread, &lock_context );
>
> if ( the_thread == NULL ) {
> @@ -55,7 +47,10 @@ int pthread_cancel( pthread_t thread )
> cpu_self = _Per_CPU_Get();
> executing = _Per_CPU_Get_executing( cpu_self );
>
> - if ( the_thread == executing ) {
> + if (
> + the_thread == executing &&
> + !_Per_CPU_Is_ISR_in_progress( cpu_self )
> + ) {
> _ISR_lock_ISR_enable( &lock_context );
> _Thread_Exit( PTHREAD_CANCELED, THREAD_LIFE_TERMINATING );
> } else {
> diff --git a/testsuites/psxtests/psxcancel01/init.c b/testsuites/psxtests/psxcancel01/init.c
> index d87295ccd1..b0da991bad 100644
> --- a/testsuites/psxtests/psxcancel01/init.c
> +++ b/testsuites/psxtests/psxcancel01/init.c
> @@ -18,38 +18,37 @@ const char rtems_test_name[] = "PSXCANCEL 1";
>
> /* forward declarations to avoid warnings */
> void *POSIX_Init(void *argument);
> -rtems_timer_service_routine Cancel_duringISR_TSR(
> - rtems_id ignored_id,
> - void *ignored_address
> -);
> -rtems_timer_service_routine SetState_duringISR_TSR(
> - rtems_id ignored_id,
> - void *ignored_address
> -);
> -rtems_timer_service_routine SetType_duringISR_TSR(
> - rtems_id ignored_id,
> - void *ignored_address
> -);
> -void doit(
> - rtems_timer_service_routine (*TSR)(rtems_id, void *),
> - const char *method
> -);
>
> -volatile int TSR_occurred;
> -volatile int TSR_status;
> +static volatile int TSR_occurred;
> +
> +static volatile int TSR_status;
> +
> +static rtems_id timer_id;
>
> -rtems_id timer_id;
> +static pthread_t thread;
>
> -rtems_timer_service_routine Cancel_duringISR_TSR(
> +static void *suspend_self( void *arg )
> +{
> + rtems_status_code status;
> +
> + (void) arg;
> +
> + status = rtems_task_suspend( RTEMS_SELF);
> + rtems_test_assert( status == RTEMS_SUCCESSFUL );
> +
> + return NULL;
> +}
> +
> +static rtems_timer_service_routine Cancel_duringISR_TSR(
> rtems_id ignored_id,
> void *ignored_address
> )
> {
> - TSR_status = pthread_cancel( pthread_self() );
> + TSR_status = pthread_cancel( thread );
> TSR_occurred = 1;
> }
>
> -rtems_timer_service_routine SetState_duringISR_TSR(
> +static rtems_timer_service_routine SetState_duringISR_TSR(
> rtems_id ignored_id,
> void *ignored_address
> )
> @@ -60,7 +59,7 @@ rtems_timer_service_routine SetState_duringISR_TSR(
> TSR_occurred = 1;
> }
>
> -rtems_timer_service_routine SetType_duringISR_TSR(
> +static rtems_timer_service_routine SetType_duringISR_TSR(
> rtems_id ignored_id,
> void *ignored_address
> )
> @@ -71,9 +70,10 @@ rtems_timer_service_routine SetType_duringISR_TSR(
> TSR_occurred = 1;
> }
>
> -void doit(
> +static void doit(
> rtems_timer_service_routine (*TSR)(rtems_id, void *),
> - const char *method
> + const char *method,
> + int expected_status
> )
> {
> rtems_interval start;
> @@ -97,11 +97,11 @@ void doit(
> printf( "%s did not occur\n", method );
> rtems_test_exit(0);
> }
> - if ( TSR_status != EPROTO ) {
> + if ( TSR_status != expected_status ) {
> printf( "%s returned %s\n", method, strerror(TSR_status) );
> rtems_test_exit(0);
> }
> - printf( "%s - from ISR returns EPROTO - OK\n", method );
> + printf( "%s - from ISR returns expected status - OK\n", method );
>
> }
>
> @@ -110,6 +110,8 @@ void *POSIX_Init(
> )
> {
> rtems_status_code status;
> + int eno;
> + void *value;
>
> TEST_BEGIN();
>
> @@ -119,9 +121,17 @@ void *POSIX_Init(
> );
> rtems_test_assert( !status );
>
> - doit( Cancel_duringISR_TSR, "pthread_cancel" );
> - doit( SetState_duringISR_TSR, "pthread_setcancelstate" );
> - doit( SetType_duringISR_TSR, "pthread_setcanceltype" );
> + eno = pthread_create( &thread, NULL, suspend_self, NULL );
> + rtems_test_assert( eno == 0 );
> +
> + doit( Cancel_duringISR_TSR, "pthread_cancel", 0 );
> + doit( SetState_duringISR_TSR, "pthread_setcancelstate", EPROTO );
> + doit( SetType_duringISR_TSR, "pthread_setcanceltype", EPROTO );
> +
> + value = NULL;
> + eno = pthread_join( thread, &value );
> + rtems_test_assert( eno == 0 );
> + rtems_test_assert( value == PTHREAD_CANCELED );
>
> TEST_END();
> rtems_test_exit(0);
> @@ -137,7 +147,7 @@ void *POSIX_Init(
>
> #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
>
> -#define CONFIGURE_MAXIMUM_POSIX_THREADS 1
> +#define CONFIGURE_MAXIMUM_POSIX_THREADS 2
> #define CONFIGURE_POSIX_INIT_THREAD_TABLE
>
> #define CONFIGURE_INIT
> --
> 2.26.2
>
> _______________________________________________
> devel mailing list
> devel at rtems.org
> http://lists.rtems.org/mailman/listinfo/devel
More information about the devel
mailing list