diff options
Diffstat (limited to 'cpukit/libcsupport/src')
-rw-r--r-- | cpukit/libcsupport/src/__usrenv.c | 14 | ||||
-rw-r--r-- | cpukit/libcsupport/src/libio_init.c | 12 | ||||
-rw-r--r-- | cpukit/libcsupport/src/privateenv.c | 67 |
3 files changed, 58 insertions, 35 deletions
diff --git a/cpukit/libcsupport/src/__usrenv.c b/cpukit/libcsupport/src/__usrenv.c index 611e0d7a92..cd191f33ea 100644 --- a/cpukit/libcsupport/src/__usrenv.c +++ b/cpukit/libcsupport/src/__usrenv.c @@ -24,6 +24,8 @@ #include <sys/stat.h> #include <rtems/libio_.h> +#include <rtems/score/percpu.h> +#include <rtems/score/thread.h> static int null_handler_open( rtems_libio_t *iop, @@ -249,4 +251,14 @@ rtems_user_env_t rtems_global_user_env = { .umask = S_IWGRP | S_IWOTH }; -pthread_key_t rtems_current_user_env_key; +rtems_user_env_t *rtems_current_user_env_get(void) +{ + Thread_Control *executing = _Thread_Get_executing(); + rtems_user_env_t *env = executing->user_environment; + + if (env == NULL) { + return &rtems_global_user_env; + } + + return env; +} diff --git a/cpukit/libcsupport/src/libio_init.c b/cpukit/libcsupport/src/libio_init.c index 5b951ef2be..eccd5b2cd7 100644 --- a/cpukit/libcsupport/src/libio_init.c +++ b/cpukit/libcsupport/src/libio_init.c @@ -49,7 +49,6 @@ static void rtems_libio_init( void ) { uint32_t i; rtems_libio_t *iop; - int eno; if (rtems_libio_number_iops > 0) { @@ -59,17 +58,6 @@ static void rtems_libio_init( void ) iop->data1 = NULL; rtems_libio_iop_free_tail = &iop->data1; } - - /* - * Create the posix key for user environment. - */ - eno = pthread_key_create( - &rtems_current_user_env_key, - rtems_libio_free_user_env - ); - if (eno != 0) { - _Internal_error( INTERNAL_ERROR_LIBIO_USER_ENV_KEY_CREATE_FAILED ); - } } RTEMS_SYSINIT_ITEM( diff --git a/cpukit/libcsupport/src/privateenv.c b/cpukit/libcsupport/src/privateenv.c index d7f5090c33..cd0154ba38 100644 --- a/cpukit/libcsupport/src/privateenv.c +++ b/cpukit/libcsupport/src/privateenv.c @@ -24,23 +24,15 @@ #include <rtems/libio_.h> #include <rtems/score/threadimpl.h> +#include <rtems/score/userextimpl.h> +#include <rtems/sysinit.h> /** * Instantiate a private user environment for the calling thread. */ -rtems_user_env_t * rtems_current_user_env_get(void) +static void rtems_libio_free_user_env(rtems_user_env_t *env) { - void *ptr = pthread_getspecific(rtems_current_user_env_key); - if (ptr == NULL) { - ptr = &rtems_global_user_env; - } - return (rtems_user_env_t *) ptr; -} - -void rtems_libio_free_user_env(void *arg) -{ - rtems_user_env_t *env = arg; bool uses_global_env = env == &rtems_global_user_env; if (!uses_global_env) { @@ -72,16 +64,9 @@ rtems_status_code rtems_libio_set_private_env(void) !rtems_filesystem_global_location_is_null(new_env->root_directory) && !rtems_filesystem_global_location_is_null(new_env->current_directory) ) { - int eno = pthread_setspecific( - rtems_current_user_env_key, - new_env - ); - - if (eno == 0) { - rtems_libio_free_user_env(old_env); - } else { - sc = RTEMS_TOO_MANY; - } + Thread_Control *executing = _Thread_Get_executing(); + + executing->user_environment = new_env; } else { sc = RTEMS_UNSATISFIED; } @@ -107,10 +92,48 @@ void rtems_libio_use_global_env(void) if (uses_private_env) { Thread_Life_state life_state = _Thread_Set_life_protection(THREAD_LIFE_PROTECTED); + Thread_Control *executing; rtems_libio_free_user_env(env); - pthread_setspecific(rtems_current_user_env_key, NULL); + executing = _Thread_Get_executing(); + executing->user_environment = NULL; _Thread_Set_life_protection(life_state); } } + +static void rtems_libio_env_thread_terminate(Thread_Control *the_thread) +{ + rtems_user_env_t *env = the_thread->user_environment; + + if (env != NULL) { + rtems_libio_free_user_env(env); + } +} + +static void rtems_libio_env_thread_restart( + Thread_Control *executing, + Thread_Control *the_thread +) +{ + (void) executing; + rtems_libio_env_thread_terminate( the_thread ); +} + +static User_extensions_Control rtems_libio_env_extensions = { + .Callouts = { + .thread_restart = rtems_libio_env_thread_restart, + .thread_terminate = rtems_libio_env_thread_terminate + } +}; + +static void rtems_libio_env_init(void) +{ + _User_extensions_Add_API_set(&rtems_libio_env_extensions); +} + +RTEMS_SYSINIT_ITEM( + rtems_libio_env_init, + RTEMS_SYSINIT_USER_ENVIRONMENT, + RTEMS_SYSINIT_ORDER_MIDDLE +); |