From 6fad95ae8b5c5c1f2086ebe4a74d172260a42669 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Tue, 22 Feb 2022 15:03:56 -0600 Subject: Add POSIX task and thread restart examples. A POSIX thread must be detached to be able to restart it. --- posix_api/psx_task_restart/Makefile | 20 +++ posix_api/psx_task_restart/psx_task_restart.c | 158 ++++++++++++++++++++++ posix_api/psx_task_restart/rtems_config.c | 48 +++++++ posix_api/psx_task_restart/wscript | 15 ++ posix_api/psx_thread_restart/Makefile | 20 +++ posix_api/psx_thread_restart/psx_thread_restart.c | 3 + posix_api/psx_thread_restart/rtems_config.c | 2 + posix_api/psx_thread_restart/wscript | 15 ++ posix_api/wscript | 2 + 9 files changed, 283 insertions(+) create mode 100644 posix_api/psx_task_restart/Makefile create mode 100644 posix_api/psx_task_restart/psx_task_restart.c create mode 100644 posix_api/psx_task_restart/rtems_config.c create mode 100644 posix_api/psx_task_restart/wscript create mode 100644 posix_api/psx_thread_restart/Makefile create mode 100644 posix_api/psx_thread_restart/psx_thread_restart.c create mode 100644 posix_api/psx_thread_restart/rtems_config.c create mode 100644 posix_api/psx_thread_restart/wscript diff --git a/posix_api/psx_task_restart/Makefile b/posix_api/psx_task_restart/Makefile new file mode 100644 index 0000000..6aa1fed --- /dev/null +++ b/posix_api/psx_task_restart/Makefile @@ -0,0 +1,20 @@ +# +# RTEMS_MAKEFILE_PATH is typically set in an environment variable +# + +PGM=${ARCH}/psx_task_restart.exe + +# C source names +CSRCS = psx_task_restart.c rtems_config.c +COBJS = $(CSRCS:%.c=${ARCH}/%.o) + +include $(RTEMS_MAKEFILE_PATH)/Makefile.inc +include $(RTEMS_CUSTOM) +include $(PROJECT_ROOT)/make/leaf.cfg + +OBJS= $(COBJS) $(CXXOBJS) $(ASOBJS) + +all: ${ARCH} $(PGM) $(PT_PGM) + +$(PGM): $(OBJS) + $(make-exe) diff --git a/posix_api/psx_task_restart/psx_task_restart.c b/posix_api/psx_task_restart/psx_task_restart.c new file mode 100644 index 0000000..35bfa4a --- /dev/null +++ b/posix_api/psx_task_restart/psx_task_restart.c @@ -0,0 +1,158 @@ +/* + * Program to test restarting a POSIX thread + */ + +/* + * Copyright 2021 Joel Sherrill (joel@rtems.org) + * + * This file's license is 2-clause BSD as in this distribution's LICENSE.2 file. + */ + +#include +#include +#include +#include +#include + +#include +#include + +#define HEALTH_EVENT 1 + +pthread_t Health_thread_id; +pthread_t Faulting_thread_id; + +void print_priority(const char *name) +{ + rtems_status_code status; + rtems_task_priority current; + + status = rtems_task_set_priority(RTEMS_SELF, RTEMS_CURRENT_PRIORITY, ¤t); + assert(status == RTEMS_SUCCESSFUL); + + printk("%s priority --> %d\n", name, current); +} + +rtems_task Health_Thread(rtems_task_argument arg) +{ + rtems_status_code status; + rtems_event_set events; + + (void) arg; + + printk("Health Thread entered\n"); + print_priority("Health thread"); + + while (1) { + status = rtems_event_receive( + HEALTH_EVENT, + RTEMS_DEFAULT_OPTIONS, /* block forever */ + RTEMS_NO_TIMEOUT, + &events + ); + assert(status == RTEMS_SUCCESSFUL); + + printk("Health Thread restarting Faulting thread\n"); + status = rtems_task_restart(Faulting_thread_id, 1); + assert(status == RTEMS_SUCCESSFUL); + } + + printk("Health Thread exiting\n"); +} + +void *Faulting_thread(void *arg) +{ + rtems_status_code status; + + printk("Faulting thread entered: %p\n", arg); + print_priority("Faulting thread"); + +#if USE_PTHREADS + int rc; + rc = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); + assert(rc == 0); +#endif + if (arg == (void *) 1) { + printk( "Faulting thread Successfully restarted\n"); + puts( "*** END OF POSIX Thread Restart ***" ); + exit( 0 ); + } else { + printk( "Faulting thread sending health event\n"); + status = rtems_event_send(Health_thread_id, HEALTH_EVENT); + assert(status == RTEMS_SUCCESSFUL); + + printk( "Faulting thread should not be here\n"); + /* Do we get restarted or return to here? */ + while (1) { } + }; + return NULL; +} + +void start_health_thread(void) +{ + rtems_status_code status; + + /* Does not matter is Health thread is higher or lower priority */ + status = rtems_task_create( + rtems_build_name('H','L','T','H'), + 0, + 16 * 1024, + RTEMS_DEFAULT_MODES, + RTEMS_SYSTEM_TASK, + &Health_thread_id + ); + assert(status == RTEMS_SUCCESSFUL); + + status = rtems_task_start(Health_thread_id, Health_Thread, 0); + assert(status == RTEMS_SUCCESSFUL); +} + +void start_faulting_thread(void) +{ + rtems_status_code status; + +#if USE_PTHREADS + int rc; + rtems_task_priority old; + + printk("Main: pthread_create faulting ... \n"); + rc = pthread_create(&Faulting_thread_id, NULL, Faulting_thread, NULL); + assert(rc == 0); + + status = rtems_task_set_priority(Faulting_thread_id, 2, &old); + assert(status == RTEMS_SUCCESSFUL); + +#else + printk("Main: rtems_task_create faulting ... \n"); + + status = rtems_task_create( + rtems_build_name('F','A','L','T'), + 1, + 16 * 1024, + RTEMS_DEFAULT_MODES, + RTEMS_DEFAULT_ATTRIBUTES, + &Faulting_thread_id + ); + assert(status == RTEMS_SUCCESSFUL); + + status = rtems_task_start(Faulting_thread_id, (rtems_task_entry)Faulting_thread, 0); + assert(status == RTEMS_SUCCESSFUL); + +#endif +} + +int main() +{ + puts( "*** POSIX Thread Restart ***" ); + + print_priority("main"); + + start_health_thread(); + + start_faulting_thread(); + + sleep(5); + + printk("main() - Should not get here"); + assert(0); +} diff --git a/posix_api/psx_task_restart/rtems_config.c b/posix_api/psx_task_restart/rtems_config.c new file mode 100644 index 0000000..9ae24cb --- /dev/null +++ b/posix_api/psx_task_restart/rtems_config.c @@ -0,0 +1,48 @@ +/* + * This file contains the RTEMS Configuration for this example. + */ + +/* + * Copyright 2018 Joel Sherrill (joel@rtems.org) + * + * This file's license is 2-clause BSD as in this distribution's LICENSE.2 file. + */ + +#include + +int main(int argc, char **argv); + +static char *argv_list[] = { + "restart", + "" +}; +static void *POSIX_Init(void *arg) +{ + (void) arg; /* deliberately ignored */ + + /* + * Initialize optional services + */ + + /* + * Could get arguments from command line or have a static set. + */ + (void) main(1, argv_list); + + return NULL; +} + +#include /* for device driver prototypes */ + +/* NOTICE: the clock driver is explicitly disabled */ +#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER +#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER + +#define CONFIGURE_POSIX_INIT_THREAD_TABLE + +#define CONFIGURE_UNLIMITED_OBJECTS +#define CONFIGURE_UNIFIED_WORK_AREAS +#define CONFIGURE_MINIMUM_TASK_STACK_SIZE (64 * 1024) + +#define CONFIGURE_INIT +#include diff --git a/posix_api/psx_task_restart/wscript b/posix_api/psx_task_restart/wscript new file mode 100644 index 0000000..2a9dcd8 --- /dev/null +++ b/posix_api/psx_task_restart/wscript @@ -0,0 +1,15 @@ +# Copyright 2013 Gedare Bloom (gedare@rtems.org) +# +# This file's license is 2-clause BSD as in this distribution's LICENSE.2 file. +# + +import rtems_waf.rtems as rtems + +def build(bld): + rtems.build(bld) + + bld(features = 'c cprogram', + target = 'psx_task_restart.exe', + source = ['psx_task_restart.c','rtems_config.c'], + lib = ['c']) + diff --git a/posix_api/psx_thread_restart/Makefile b/posix_api/psx_thread_restart/Makefile new file mode 100644 index 0000000..81765ad --- /dev/null +++ b/posix_api/psx_thread_restart/Makefile @@ -0,0 +1,20 @@ +# +# RTEMS_MAKEFILE_PATH is typically set in an environment variable +# + +PGM=${ARCH}/psx_thread_restart.exe + +# C source names +CSRCS = psx_thread_restart.c rtems_config.c +COBJS = $(CSRCS:%.c=${ARCH}/%.o) + +include $(RTEMS_MAKEFILE_PATH)/Makefile.inc +include $(RTEMS_CUSTOM) +include $(PROJECT_ROOT)/make/leaf.cfg + +OBJS= $(COBJS) $(CXXOBJS) $(ASOBJS) + +all: ${ARCH} $(PGM) $(PT_PGM) + +$(PGM): $(OBJS) + $(make-exe) diff --git a/posix_api/psx_thread_restart/psx_thread_restart.c b/posix_api/psx_thread_restart/psx_thread_restart.c new file mode 100644 index 0000000..471a359 --- /dev/null +++ b/posix_api/psx_thread_restart/psx_thread_restart.c @@ -0,0 +1,3 @@ +#define USE_PTHREADS 1 + +#include "../psx_task_restart/psx_task_restart.c" diff --git a/posix_api/psx_thread_restart/rtems_config.c b/posix_api/psx_thread_restart/rtems_config.c new file mode 100644 index 0000000..7d39c1b --- /dev/null +++ b/posix_api/psx_thread_restart/rtems_config.c @@ -0,0 +1,2 @@ + +#include "../psx_task_restart/rtems_config.c" diff --git a/posix_api/psx_thread_restart/wscript b/posix_api/psx_thread_restart/wscript new file mode 100644 index 0000000..8384b02 --- /dev/null +++ b/posix_api/psx_thread_restart/wscript @@ -0,0 +1,15 @@ +# Copyright 2013 Gedare Bloom (gedare@rtems.org) +# +# This file's license is 2-clause BSD as in this distribution's LICENSE.2 file. +# + +import rtems_waf.rtems as rtems + +def build(bld): + rtems.build(bld) + + bld(features = 'c cprogram', + target = 'psx_task_restart.exe', + source = ['psx_thread_restart.c','rtems_config.c'], + lib = ['c']) + diff --git a/posix_api/wscript b/posix_api/wscript index 19b6e3e..214b441 100644 --- a/posix_api/wscript +++ b/posix_api/wscript @@ -18,4 +18,6 @@ def build(bld): bld.recurse('psx_rwlock_report') bld.recurse('psx_sched_report') bld.recurse('psx_sigint') + bld.recurse('psx_task_restart') + bld.recurse('psx_thread_restart') bld.recurse('livermore') -- cgit v1.2.3