summaryrefslogtreecommitdiffstats
path: root/cpukit
diff options
context:
space:
mode:
authorChristian Mauderer <Christian.Mauderer@embedded-brains.de>2014-03-27 14:23:21 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2014-03-27 14:50:36 +0100
commit5c0c0cf2a6a9e3fdbcd1ada3f79399c453b1fbd1 (patch)
treedba573cb48c77127b711bdce1f94816025fdf942 /cpukit
parentprivateenv: Remove sharing of user environment between threads. (diff)
downloadrtems-5c0c0cf2a6a9e3fdbcd1ada3f79399c453b1fbd1.tar.bz2
privateenv: Use POSIX keys instead of task variables.
Diffstat (limited to 'cpukit')
-rw-r--r--cpukit/include/rtems/userenv.h18
-rw-r--r--cpukit/libcsupport/include/rtems/libio_.h5
-rw-r--r--cpukit/libcsupport/src/__usrenv.c2
-rw-r--r--cpukit/libcsupport/src/libio_init.c12
-rw-r--r--cpukit/libcsupport/src/privateenv.c37
-rw-r--r--cpukit/sapi/include/confdefs.h29
6 files changed, 71 insertions, 32 deletions
diff --git a/cpukit/include/rtems/userenv.h b/cpukit/include/rtems/userenv.h
index 8a9a4fcd32..631d773ae5 100644
--- a/cpukit/include/rtems/userenv.h
+++ b/cpukit/include/rtems/userenv.h
@@ -66,8 +66,17 @@ typedef struct {
pid_t pgrp; /* process group id */
} rtems_user_env_t;
-extern rtems_user_env_t * rtems_current_user_env;
-extern rtems_user_env_t rtems_global_user_env;
+extern rtems_user_env_t rtems_global_user_env;
+
+/**
+ * @brief Fetch the pointer to the current user environment.
+ *
+ * If the task has a private user environment the pointer to it will be
+ * returned. Otherwise the pointer to rtems_global_user_env will be returned.
+ */
+rtems_user_env_t * rtems_current_user_env_get(void);
+
+#define rtems_current_user_env rtems_current_user_env_get()
#define rtems_filesystem_current (rtems_current_user_env->current_directory)
#define rtems_filesystem_root (rtems_current_user_env->root_directory)
@@ -86,6 +95,11 @@ extern rtems_user_env_t rtems_global_user_env;
* function must be called from normal thread context and may block on a mutex.
* Thread dispatching is disabled to protect some critical sections.
*
+ * The private environment internally uses a POSIX key. The key is added to the
+ * configuration implicitly. But for each thread that uses a private environment
+ * a key value pair has to be configured by the application. If only the global
+ * environment is used there is no need to configure a key value pair.
+ *
* @retval RTEMS_SUCCESSFUL Successful operation.
* @retval RTEMS_NO_MEMORY Not enough memory.
* @retval RTEMS_UNSATISFIED Cloning of the current environment failed.
diff --git a/cpukit/libcsupport/include/rtems/libio_.h b/cpukit/libcsupport/include/rtems/libio_.h
index 9960288c20..d7f9034e3d 100644
--- a/cpukit/libcsupport/include/rtems/libio_.h
+++ b/cpukit/libcsupport/include/rtems/libio_.h
@@ -24,6 +24,7 @@
#include <sys/uio.h>
#include <errno.h>
#include <limits.h>
+#include <pthread.h>
#include <rtems.h>
#include <rtems/libio.h>
@@ -238,6 +239,10 @@ void rtems_filesystem_location_free( rtems_filesystem_location_info_t *loc );
*/
#include <rtems/userenv.h>
+void rtems_libio_free_user_env( void *env );
+
+extern pthread_key_t rtems_current_user_env_key;
+
static inline void rtems_libio_lock( void )
{
rtems_semaphore_obtain( rtems_libio_semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT );
diff --git a/cpukit/libcsupport/src/__usrenv.c b/cpukit/libcsupport/src/__usrenv.c
index 3ce6a2dfea..71efda9d7f 100644
--- a/cpukit/libcsupport/src/__usrenv.c
+++ b/cpukit/libcsupport/src/__usrenv.c
@@ -257,4 +257,4 @@ rtems_user_env_t rtems_global_user_env = {
.umask = S_IWGRP | S_IWOTH
};
-rtems_user_env_t *rtems_current_user_env = &rtems_global_user_env;
+pthread_key_t rtems_current_user_env_key;
diff --git a/cpukit/libcsupport/src/libio_init.c b/cpukit/libcsupport/src/libio_init.c
index 4d705fb8ee..e64ddd6e3a 100644
--- a/cpukit/libcsupport/src/libio_init.c
+++ b/cpukit/libcsupport/src/libio_init.c
@@ -46,6 +46,7 @@ void rtems_libio_init( void )
rtems_status_code rc;
uint32_t i;
rtems_libio_t *iop;
+ int eno;
if (rtems_libio_number_iops > 0)
{
@@ -61,6 +62,17 @@ void rtems_libio_init( void )
}
/*
+ * Create the posix key for user environment.
+ */
+ eno = pthread_key_create(
+ &rtems_current_user_env_key,
+ rtems_libio_free_user_env
+ );
+ if (eno != 0) {
+ rtems_fatal_error_occurred( RTEMS_UNSATISFIED );
+ }
+
+ /*
* Create the binary semaphore used to provide mutual exclusion
* on the IOP Table.
*/
diff --git a/cpukit/libcsupport/src/privateenv.c b/cpukit/libcsupport/src/privateenv.c
index bee94c117f..60207b0815 100644
--- a/cpukit/libcsupport/src/privateenv.c
+++ b/cpukit/libcsupport/src/privateenv.c
@@ -29,7 +29,16 @@
* Instantiate a private user environment for the calling thread.
*/
-static void free_user_env(void *arg)
+rtems_user_env_t * rtems_current_user_env_get(void)
+{
+ 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;
@@ -44,7 +53,7 @@ static void free_user_env(void *arg)
static void free_user_env_protected(rtems_user_env_t *env)
{
_Thread_Disable_dispatch();
- free_user_env(env);
+ rtems_libio_free_user_env(env);
_Thread_Enable_dispatch();
}
@@ -68,14 +77,13 @@ 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)
) {
- sc = rtems_task_variable_add(
- RTEMS_SELF,
- (void **) &rtems_current_user_env,
- free_user_env
+ int eno = pthread_setspecific(
+ rtems_current_user_env_key,
+ new_env
);
- if (sc == RTEMS_SUCCESSFUL) {
+
+ if (eno == 0) {
free_user_env_protected(old_env);
- rtems_current_user_env = new_env;
} else {
sc = RTEMS_TOO_MANY;
}
@@ -84,7 +92,7 @@ rtems_status_code rtems_libio_set_private_env(void)
}
if (sc != RTEMS_SUCCESSFUL) {
- free_user_env(new_env);
+ rtems_libio_free_user_env(new_env);
}
} else {
sc = RTEMS_NO_MEMORY;
@@ -101,14 +109,7 @@ void rtems_libio_use_global_env(void)
bool uses_private_env = env != &rtems_global_user_env;
if (uses_private_env) {
- sc = rtems_task_variable_delete(
- RTEMS_SELF,
- (void **) &rtems_current_user_env
- );
- if (sc != RTEMS_SUCCESSFUL) {
- rtems_fatal_error_occurred(0xdeadbeef);
- }
-
- rtems_current_user_env = &rtems_global_user_env;
+ free_user_env_protected(env);
+ pthread_setspecific(rtems_current_user_env_key, NULL);
}
}
diff --git a/cpukit/sapi/include/confdefs.h b/cpukit/sapi/include/confdefs.h
index b7317433d9..d8cf2af402 100644
--- a/cpukit/sapi/include/confdefs.h
+++ b/cpukit/sapi/include/confdefs.h
@@ -148,6 +148,11 @@ const rtems_libio_helper rtems_fs_init_helper =
*/
#define CONFIGURE_LIBIO_SEMAPHORES 1
+/**
+ * POSIX key count used by the IO library.
+ */
+#define CONFIGURE_LIBIO_POSIX_KEYS 1
+
#ifdef CONFIGURE_INIT
/**
* When instantiating the configuration tables, this variable is
@@ -1734,16 +1739,18 @@ const rtems_libio_helper rtems_fs_init_helper =
#include <rtems/posix/key.h>
#ifndef CONFIGURE_MAXIMUM_POSIX_KEYS
- #define CONFIGURE_MAXIMUM_POSIX_KEYS 0
- #define CONFIGURE_MAXIMUM_POSIX_KEY_VALUE_PAIRS 0
-#else
- #ifndef CONFIGURE_MAXIMUM_POSIX_KEY_VALUE_PAIRS
- #define CONFIGURE_MAXIMUM_POSIX_KEY_VALUE_PAIRS \
- (CONFIGURE_MAXIMUM_POSIX_KEYS * \
- (CONFIGURE_MAXIMUM_POSIX_THREADS + CONFIGURE_MAXIMUM_TASKS))
- #endif
+ #define CONFIGURE_MAXIMUM_POSIX_KEYS 0
+#endif
+
+#ifndef CONFIGURE_MAXIMUM_POSIX_KEY_VALUE_PAIRS
+ #define CONFIGURE_MAXIMUM_POSIX_KEY_VALUE_PAIRS \
+ (CONFIGURE_MAXIMUM_POSIX_KEYS * \
+ (CONFIGURE_MAXIMUM_POSIX_THREADS + CONFIGURE_MAXIMUM_TASKS))
#endif
+#define CONFIGURE_POSIX_KEYS \
+ (CONFIGURE_MAXIMUM_POSIX_KEYS + CONFIGURE_LIBIO_POSIX_KEYS)
+
#define CONFIGURE_MEMORY_FOR_POSIX_KEYS(_keys, _key_value_pairs) \
(_Configure_Object_RAM(_keys, sizeof(POSIX_Keys_Control) ) \
+ _Configure_From_workspace( \
@@ -2222,7 +2229,7 @@ const rtems_libio_helper rtems_fs_init_helper =
CONFIGURE_TOTAL_TASKS_AND_THREADS, CONFIGURE_TOTAL_TASKS_AND_THREADS) + \
CONFIGURE_MEMORY_FOR_CLASSIC + \
CONFIGURE_MEMORY_FOR_POSIX_KEYS( \
- CONFIGURE_MAXIMUM_POSIX_KEYS, \
+ CONFIGURE_POSIX_KEYS, \
CONFIGURE_MAXIMUM_POSIX_KEY_VALUE_PAIRS ) + \
CONFIGURE_MEMORY_FOR_POSIX + \
CONFIGURE_MEMORY_FOR_STATIC_EXTENSIONS + \
@@ -2397,7 +2404,7 @@ const rtems_libio_helper rtems_fs_init_helper =
CONFIGURE_EXECUTIVE_RAM_SIZE, /* required RTEMS workspace */
CONFIGURE_STACK_SPACE_SIZE, /* required stack space */
CONFIGURE_MAXIMUM_USER_EXTENSIONS, /* maximum dynamic extensions */
- CONFIGURE_MAXIMUM_POSIX_KEYS, /* POSIX keys are always */
+ CONFIGURE_POSIX_KEYS, /* POSIX keys are always */
CONFIGURE_MAXIMUM_POSIX_KEY_VALUE_PAIRS, /* enabled */
CONFIGURE_MICROSECONDS_PER_TICK, /* microseconds per clock tick */
1000 * CONFIGURE_MICROSECONDS_PER_TICK, /* nanoseconds per clock tick */
@@ -2592,7 +2599,7 @@ const rtems_libio_helper rtems_fs_init_helper =
CONFIGURE_MEMORY_FOR_PERIODS(CONFIGURE_MAXIMUM_PERIODS),
CONFIGURE_MEMORY_FOR_BARRIERS(CONFIGURE_BARRIERS),
CONFIGURE_MEMORY_FOR_USER_EXTENSIONS(CONFIGURE_MAXIMUM_USER_EXTENSIONS),
- CONFIGURE_MEMORY_FOR_POSIX_KEYS( CONFIGURE_MAXIMUM_POSIX_KEYS, \
+ CONFIGURE_MEMORY_FOR_POSIX_KEYS( CONFIGURE_POSIX_KEYS, \
CONFIGURE_MAXIMUM_POSIX_KEY_VALUE_PAIRS ),
#ifdef RTEMS_POSIX_API