privateenv: Use POSIX keys instead of task variables.

This commit is contained in:
Christian Mauderer
2014-03-27 14:50:36 +01:00
committed by Sebastian Huber
parent 7d5c27e308
commit 5c0c0cf2a6
22 changed files with 173 additions and 37 deletions
+16 -2
View File
@@ -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.
@@ -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 );
+1 -1
View File
@@ -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;
+12
View File
@@ -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)
{
@@ -60,6 +61,17 @@ void rtems_libio_init( void )
iop->data1 = NULL;
}
/*
* 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.
+19 -18
View File
@@ -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);
}
}
+18 -11
View File
@@ -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
+3 -1
View File
@@ -1148,7 +1148,9 @@ cat: /etc/passwd: No such file or directory
This command is included in the default shell command set.
When building a custom command set, define
@code{CONFIGURE_SHELL_COMMAND_CHROOT} to have this
command included.
command included. Additional to that you have to add one
POSIX key value pair for each thread where you want to use
the command.
This command can be excluded from the shell command set by
defining @code{CONFIGURE_SHELL_NO_COMMAND_CHROOT} when all
@@ -41,6 +41,7 @@ test_shutdown_filesystem (void)
#define CONFIGURE_USE_IMFS_AS_BASE_FILESYSTEM
#define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 40
#define CONFIGURE_INIT_TASK_STACK_SIZE (16 * 1024)
#define CONFIGURE_MAXIMUM_POSIX_KEY_VALUE_PAIRS 1
#define CONFIGURE_INIT
#include <rtems/confdefs.h>
@@ -157,6 +157,8 @@ void test_shutdown_filesystem(void)
#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
#define CONFIGURE_MAXIMUM_POSIX_KEY_VALUE_PAIRS 1
#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
#define CONFIGURE_INIT
@@ -91,6 +91,7 @@ void test_shutdown_filesystem(void)
#define CONFIGURE_MAXIMUM_DRIVERS 10
#define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 40
#define CONFIGURE_INIT_TASK_STACK_SIZE (16 * 1024)
#define CONFIGURE_MAXIMUM_POSIX_KEY_VALUE_PAIRS 1
#define CONFIGURE_APPLICATION_NEEDS_LIBBLOCK
@@ -56,6 +56,7 @@ test_shutdown_filesystem (void)
#define CONFIGURE_USE_IMFS_AS_BASE_FILESYSTEM
#define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 40
#define CONFIGURE_INIT_TASK_STACK_SIZE (16 * 1024)
#define CONFIGURE_MAXIMUM_POSIX_KEY_VALUE_PAIRS 1
#define CONFIGURE_INIT
#include <rtems/confdefs.h>
@@ -70,6 +70,7 @@ test_shutdown_filesystem (void)
#define CONFIGURE_MAXIMUM_DRIVERS 10
#define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 40
#define CONFIGURE_INIT_TASK_STACK_SIZE (32 * 1024)
#define CONFIGURE_MAXIMUM_POSIX_KEY_VALUE_PAIRS 1
#define CONFIGURE_APPLICATION_NEEDS_LIBBLOCK
+2
View File
@@ -246,6 +246,8 @@ static rtems_task Init(rtems_task_argument argument)
#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
#define CONFIGURE_MAXIMUM_POSIX_KEY_VALUE_PAIRS 2
#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
#include <rtems/confdefs.h>
+2
View File
@@ -34,6 +34,8 @@ rtems_task Init(
#define CONFIGURE_MAXIMUM_TASKS 1
#define CONFIGURE_MAXIMUM_POSIX_KEY_VALUE_PAIRS 1
#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+2
View File
@@ -36,6 +36,8 @@ rtems_task Init(
#define CONFIGURE_MAXIMUM_TASKS 1
#define CONFIGURE_MAXIMUM_POSIX_KEY_VALUE_PAIRS 1
#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+1 -1
View File
@@ -18,7 +18,7 @@ SUBDIRS = \
spfatal01 spfatal02 spfatal03 spfatal04 spfatal05 spfatal06 spfatal07 \
spfatal08 spfatal09 spfatal10 spfatal11 spfatal12 spfatal13 spfatal14 \
spfatal15 spfatal16 spfatal17 spfatal18 spfatal19 spfatal20 \
spfatal22 spfatal24 spfatal25 \
spfatal22 spfatal24 spfatal25 spfatal27\
spfifo01 spfifo02 spfifo03 spfifo04 spfifo05 \
spfreechain01 \
spintrcritical01 spintrcritical02 spintrcritical03 spintrcritical04 \
+1
View File
@@ -166,6 +166,7 @@ spfatal20/Makefile
spfatal22/Makefile
spfatal24/Makefile
spfatal25/Makefile
spfatal27/Makefile
spfifo01/Makefile
spfifo02/Makefile
spfifo03/Makefile
+21
View File
@@ -0,0 +1,21 @@
rtems_tests_PROGRAMS = spfatal27
spfatal27_SOURCES = ../spfatal_support/init.c \
../spfatal_support/system.h testcase.h
dist_rtems_tests_DATA = spfatal27.scn
dist_rtems_tests_DATA += spfatal27.doc
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
include $(top_srcdir)/../automake/compile.am
include $(top_srcdir)/../automake/leaf.am
AM_CPPFLAGS += -I$(top_srcdir)/../support/include
LINK_OBJS = $(spfatal27_OBJECTS)
LINK_LIBS = $(spfatal27_LDLIBS)
spfatal27$(EXEEXT): $(spfatal27_OBJECTS) $(spfatal27_DEPENDENCIES)
@rm -f spfatal27$(EXEEXT)
$(make-exe)
include $(top_srcdir)/../automake/local.am
@@ -0,0 +1,23 @@
# Copyright (c) 2014 embedded brains GmbH. All rights reserved.
#
# embedded brains GmbH
# Dornierstrasse 4
# 82178 Puchheim
# Germany
# <rtems@embedded-brains.de>
#
# The license and distribution terms for this file may be
# found in the file LICENSE in this distribution or at
# http://www.rtems.org/license/LICENSE.
This file describes the directives and concepts tested by this test set.
test set name: spfatal27
directives:
rtems_libio_init
concepts:
+ Force the fatal error when no POSIX key is left.
@@ -0,0 +1,3 @@
*** BEGIN OF TEST FATAL 27 ***
Fatal error (libio init no posix key left) hit
*** END OF TEST FATAL 27 ***
+27
View File
@@ -0,0 +1,27 @@
/*
* Copyright (c) 2014 embedded brains GmbH. All rights reserved.
*
* embedded brains GmbH
* Dornierstrasse 4
* 82178 Puchheim
* Germany
* <rtems@embedded-brains.de>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#define FATAL_ERROR_TEST_NAME "FATAL 27"
#define FATAL_ERROR_DESCRIPTION "libio init no posix key left"
#define FATAL_ERROR_EXPECTED_SOURCE INTERNAL_ERROR_RTEMS_API
#define FATAL_ERROR_EXPECTED_IS_INTERNAL FALSE
#define FATAL_ERROR_EXPECTED_ERROR RTEMS_UNSATISFIED
#define CONFIGURE_MAXIMUM_POSIX_KEYS (-1)
#define CONFIGURE_MAXIMUM_POSIX_KEY_VALUE_PAIRS (0)
void force_error()
{
/* we should not reach this */
}
+11 -3
View File
@@ -63,14 +63,19 @@ rtems_task Init(
puts( "Init - allocating most of workspace memory" );
opaque = rtems_workspace_greedy_allocate( NULL, 0 );
puts( "Init - attempt to reset env - expect RTEMS_TOO_MANY" );
puts( "Init - attempt to reset env - expect RTEMS_SUCCESSFUL" );
sc = rtems_libio_set_private_env();
rtems_test_assert( sc == RTEMS_TOO_MANY );
rtems_test_assert( sc == RTEMS_SUCCESSFUL );
rtems_test_assert( rtems_current_user_env != &rtems_global_user_env );
puts( "Init - freeing the workspace memory" );
rtems_workspace_greedy_free( opaque );
puts( "Init - Reset to global environment" );
rtems_libio_use_global_env();
rtems_test_assert( rtems_current_user_env == &rtems_global_user_env );
puts( "Init - Attempt to get a private environment" );
sc = rtems_libio_set_private_env();
rtems_test_assert( sc == RTEMS_SUCCESSFUL );
@@ -118,6 +123,9 @@ rtems_task Init(
#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
#define CONFIGURE_MAXIMUM_POSIX_KEYS 1
#define CONFIGURE_MAXIMUM_POSIX_KEY_VALUE_PAIRS 2
#define CONFIGURE_INIT
#include <rtems/confdefs.h>