[PATCH 3/3] libcsupport: Use POSIX keys for gxx-wrapper-key-functions.
Gedare Bloom
gedare at rtems.org
Fri Mar 21 12:30:06 UTC 2014
On Fri, Mar 21, 2014 at 5:26 AM, Christian Mauderer
<christian.mauderer at embedded-brains.de> wrote:
> From: Christian Mauderer <Christian.Mauderer at embedded-brains.de>
>
> With this patch C++ applications now eventually need additional POSIX-keys and
> POSIX-key-value-pairs configured.
I'm not sure where, but this fact should be somewhere in user documentation.
> ---
> cpukit/libcsupport/include/rtems/gxx_wrappers.h | 10 +--
> cpukit/libcsupport/src/gxx_wrappers.c | 111 +++++++++++-------------
> testsuites/libtests/gxx01/gxx01.scn | 8 +-
> testsuites/libtests/gxx01/init.c | 29 ++++++-
> testsuites/sptests/spfatal24/spfatal24.doc | 2 +-
> testsuites/sptests/spfatal24/testcase.h | 6 +-
> testsuites/sptests/sptls02/init.cc | 3 +
> 7 files changed, 91 insertions(+), 78 deletions(-)
>
> diff --git a/cpukit/libcsupport/include/rtems/gxx_wrappers.h b/cpukit/libcsupport/include/rtems/gxx_wrappers.h
> index 801223e..0efb341 100644
> --- a/cpukit/libcsupport/include/rtems/gxx_wrappers.h
> +++ b/cpukit/libcsupport/include/rtems/gxx_wrappers.h
> @@ -21,6 +21,8 @@
> #ifndef __GCC_WRAPPERS_h
> #define __GCC_WRAPPERS_h
>
> +#include <pthread.h>
> +
> #ifdef __cplusplus
> extern "C" {
> #endif /* __cplusplus */
> @@ -36,14 +38,8 @@ extern "C" {
> /*
> * These typedefs should match with the ones defined in the file
> * gcc/gthr-rtems.h in the gcc distribution.
> - * FIXME: T.S, 2007/01/31: -> gcc/gthr-rtems.h still declares
> - * void * __gthread_key_t;
> */
> -typedef struct __gthread_key_ {
> - void *val; /* this is switched with the task */
> - void (*dtor)(void*); /* this remains in place for all tasks */
> -} __gthread_key, *__gthread_key_t;
> -
> +typedef void *__gthread_key_t;
> typedef int __gthread_once_t;
> typedef void *__gthread_mutex_t;
> typedef void *__gthread_recursive_mutex_t;
> diff --git a/cpukit/libcsupport/src/gxx_wrappers.c b/cpukit/libcsupport/src/gxx_wrappers.c
> index 0b9cad6..963b712 100644
> --- a/cpukit/libcsupport/src/gxx_wrappers.c
> +++ b/cpukit/libcsupport/src/gxx_wrappers.c
> @@ -31,6 +31,7 @@
> #include <rtems/gxx_wrappers.h>
> #include <rtems/score/onceimpl.h>
>
> +#include <errno.h>
> #include <stdlib.h>
>
> #include <rtems.h>
> @@ -49,82 +50,64 @@ int rtems_gxx_once(__gthread_once_t *once, void (*func) (void))
>
> int rtems_gxx_key_create (__gthread_key_t *key, void (*dtor) (void *))
> {
> - rtems_status_code status;
> -
> - /* Ok, this can be a bit tricky. We are going to return a "key" as a
> - * pointer to the buffer that will hold the value of the key itself.
> - * We have to to this, because the others functions on this interface
> - * deal with the value of the key, as used with the POSIX API.
> - */
> - /* Do not pull your hair, trust me this works. :-) */
> - __gthread_key_t new_key = (__gthread_key_t) malloc( sizeof( *new_key ) );
> - *key = new_key;
> - new_key->val = NULL;
> - new_key->dtor = dtor;
> + int eno;
> + pthread_key_t *pkey;
> +
> + pkey = malloc( sizeof( *pkey ) );
> + *key = pkey;
> + if ( pkey == NULL )
> + {
> + return ENOMEM;
> + }
>
> #ifdef DEBUG_GXX_WRAPPERS
> printk(
> - "gxx_wrappers: create key=%x, dtor=%x, new_key=%x\n", key, dtor, new_key
> + "gxx_wrappers: create key=%x, dtor=%x, pkey=%x\n", key, dtor, pkey
> );
> #endif
>
> - /* register with RTEMS the buffer that will hold the key values */
> - status = rtems_task_variable_add( RTEMS_SELF, (void **)new_key, dtor );
> - if ( status == RTEMS_SUCCESSFUL )
> - return 0;
> + eno = pthread_key_create(pkey, dtor);
> + if ( eno != 0 ) {
> + free( pkey );
> + *key = NULL;
> + }
>
> - free( new_key );
> - return -1;
> + return eno;
> }
>
> int rtems_gxx_key_delete (__gthread_key_t key)
> {
> - rtems_status_code status;
> + int eno = 0;
> + pthread_key_t *pkey = key;
>
> #ifdef DEBUG_GXX_WRAPPERS
> - printk( "gxx_wrappers: delete key=%x\n", key );
> + printk( "gxx_wrappers: delete key=%x\n", pkey );
> #endif
>
> - /* register with RTEMS the buffer that will hold the key values */
> - status = rtems_task_variable_delete( RTEMS_SELF, (void **)key );
> - if ( status == RTEMS_SUCCESSFUL ) {
> - /* Hmm - hopefully all tasks using this key have gone away... */
> - if ( key ) free( *(void **)key );
> - return 0;
> + if ( pkey == NULL ) {
> + return EINVAL;
> }
> - key = NULL;
> - return 0;
> +
> + eno = pthread_key_delete(*pkey);
> + if ( eno == 0 ) {
> + free( pkey );
> + }
> + return eno;
> }
>
> void *rtems_gxx_getspecific(__gthread_key_t key)
> {
> - rtems_status_code status;
> - void *p= 0;
> -
> - /* register with RTEMS the buffer that will hold the key values */
> - status = rtems_task_variable_get( RTEMS_SELF, (void **)key, &p );
> - if ( status == RTEMS_SUCCESSFUL ) {
> - /* We do not have to do this, but what the heck ! */
> - p= key->val;
> - } else {
> - /* fisrt time, always set to zero, it is unknown the value that the others
> - * threads are using at the moment of this call
> - */
> - status = rtems_task_variable_add( RTEMS_SELF, (void **)key, key->dtor );
> - if ( status != RTEMS_SUCCESSFUL ) {
> - _Terminate(
> - INTERNAL_ERROR_CORE,
> - true,
> - INTERNAL_ERROR_GXX_KEY_ADD_FAILED
> - );
> - }
> - key->val = (void *)0;
> + pthread_key_t *pkey = key;
> + void *p = NULL;
> +
> + if ( pkey != NULL ) {
> + p = pthread_getspecific( *pkey );
> }
>
> #ifdef DEBUG_GXX_WRAPPERS
> printk(
> "gxx_wrappers: getspecific key=%x, ptr=%x, id=%x\n",
> - key,
> + pkey,
> p,
> rtems_task_self()
> );
> @@ -134,25 +117,33 @@ void *rtems_gxx_getspecific(__gthread_key_t key)
>
> int rtems_gxx_setspecific(__gthread_key_t key, const void *ptr)
> {
> - rtems_status_code status;
> + pthread_key_t *pkey = key;
> + int eno;
> +
> + if ( pkey == NULL ) {
> + return EINVAL;
> + }
> +
> + eno = pthread_setspecific( *pkey, ptr );
>
> #ifdef DEBUG_GXX_WRAPPERS
> printk(
> "gxx_wrappers: setspecific key=%x, ptr=%x, id=%x\n",
> - key,
> + pkey,
> ptr,
> rtems_task_self()
> );
> #endif
>
> - /* register with RTEMS the buffer that will hold the key values */
> - status = rtems_task_variable_add( RTEMS_SELF, (void **)key, key->dtor );
> - if ( status == RTEMS_SUCCESSFUL ) {
> - /* now let's set the proper value */
> - key->val = (void *)ptr;
> - return 0;
> + if ( eno != 0 ) {
> + _Terminate(
> + INTERNAL_ERROR_CORE,
> + true,
> + INTERNAL_ERROR_GXX_KEY_ADD_FAILED
> + );
> }
> - return -1;
> +
> + return 0;
> }
>
>
> diff --git a/testsuites/libtests/gxx01/gxx01.scn b/testsuites/libtests/gxx01/gxx01.scn
> index cb9f6b5..f831881 100644
> --- a/testsuites/libtests/gxx01/gxx01.scn
> +++ b/testsuites/libtests/gxx01/gxx01.scn
> @@ -22,10 +22,14 @@ Call once method the second time
> rtems_gxx_key_create(&key, NULL) - OK
> rtems_gxx_key_delete(key) - OK
> rtems_gxx_key_create(&key, key_dtor) - OK
> -rtems_gxx_setspecific() - OK
> +rtems_gxx_getspecific(key) not set - OK
> +rtems_gxx_setspecific(key, 0x1234) - OK
> rtems_gxx_getspecific(key) already existing - OK
> rtems_gxx_key_delete(key) - OK
> rtems_gxx_getspecific(key) non-existent - OK
> -rtems_gxx_key_delete(key) - OK
> +rtems_gxx_key_delete(key) - NOT OK
> +rtems_gxx_setspecific(NULL, 0x1234) - NOT OK
> +rtems_gxx_getspecific(NULL) - OK
> +rtems_gxx_key_delete(NULL) - NOT OK
>
> *** END OF TEST GXX 01 ***
> diff --git a/testsuites/libtests/gxx01/init.c b/testsuites/libtests/gxx01/init.c
> index cc704ef..5c7a3c1 100644
> --- a/testsuites/libtests/gxx01/init.c
> +++ b/testsuites/libtests/gxx01/init.c
> @@ -11,6 +11,7 @@
> #include "config.h"
> #endif
>
> +#include <errno.h>
> #include <tmacros.h>
> #include "test_support.h"
> #include <rtems/gxx_wrappers.h>
> @@ -140,7 +141,11 @@ void test_key(void)
> sc = rtems_gxx_key_create(&key, key_dtor);
> rtems_test_assert( sc == 0 );
>
> - puts( "rtems_gxx_setspecific() - OK" );
> + puts( "rtems_gxx_getspecific(key) not set - OK" );
> + p = rtems_gxx_getspecific(key);
> + rtems_test_assert( p == NULL );
> +
> + puts( "rtems_gxx_setspecific(key, 0x1234) - OK" );
> sc = rtems_gxx_setspecific(key, (void *)0x1234);
> rtems_test_assert( sc == 0 );
>
> @@ -151,7 +156,8 @@ void test_key(void)
> puts( "rtems_gxx_key_delete(key) - OK" );
> sc = rtems_gxx_key_delete(key);
> rtems_test_assert( sc == 0 );
> - rtems_test_assert( key_dtor_ran == true );
> + /* pthread_key man-page: the dtor should _not_ be called */
> + rtems_test_assert( key_dtor_ran != true );
>
> key = calloc( 1, sizeof( *key ) );
> rtems_test_assert( key != NULL );
> @@ -160,9 +166,21 @@ void test_key(void)
> p = rtems_gxx_getspecific( key );
> rtems_test_assert( p == NULL );
>
> - puts( "rtems_gxx_key_delete(key) - OK" );
> + puts( "rtems_gxx_key_delete(key) - NOT OK" );
> sc = rtems_gxx_key_delete( key );
> - rtems_test_assert( sc == 0 );
> + rtems_test_assert( sc != 0 );
> +
> + puts( "rtems_gxx_setspecific(NULL, 0x1234) - NOT OK" );
> + sc = rtems_gxx_setspecific( NULL, (void *)0x1234 );
> + rtems_test_assert( sc == EINVAL );
> +
> + puts( "rtems_gxx_getspecific(NULL) - OK" );
> + p = rtems_gxx_getspecific( NULL );
> + rtems_test_assert( p == NULL );
> +
> + puts( "rtems_gxx_key_delete(NULL) - NOT OK" );
> + sc = rtems_gxx_key_delete( NULL );
> + rtems_test_assert( sc == EINVAL );
> }
>
> rtems_task Init(
> @@ -197,6 +215,9 @@ rtems_task Init(
> #define CONFIGURE_MAXIMUM_SEMAPHORES 2
> #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
>
> +#define CONFIGURE_MAXIMUM_POSIX_KEYS 1
> +#define CONFIGURE_MAXIMUM_POSIX_KEY_VALUE_PAIRS 1
> +
> #define CONFIGURE_INIT
>
> #include <rtems/confdefs.h>
> diff --git a/testsuites/sptests/spfatal24/spfatal24.doc b/testsuites/sptests/spfatal24/spfatal24.doc
> index ad6eda5..0ff898d 100644
> --- a/testsuites/sptests/spfatal24/spfatal24.doc
> +++ b/testsuites/sptests/spfatal24/spfatal24.doc
> @@ -12,7 +12,7 @@ test set name: spfatal24
>
> directives:
>
> - rtems_gxx_getspecific();
> + rtems_gxx_setspecific();
>
> concepts:
>
> diff --git a/testsuites/sptests/spfatal24/testcase.h b/testsuites/sptests/spfatal24/testcase.h
> index 6ac8906..226ccc9 100644
> --- a/testsuites/sptests/spfatal24/testcase.h
> +++ b/testsuites/sptests/spfatal24/testcase.h
> @@ -18,9 +18,7 @@
>
> void force_error()
> {
> - __gthread_key key;
> + pthread_key_t key = -1;
>
> - rtems_workspace_greedy_allocate( NULL, 0 );
> -
> - rtems_gxx_getspecific( &key );
> + rtems_gxx_setspecific( &key, NULL );
> }
> diff --git a/testsuites/sptests/sptls02/init.cc b/testsuites/sptests/sptls02/init.cc
> index d704190..2c9e283 100644
> --- a/testsuites/sptests/sptls02/init.cc
> +++ b/testsuites/sptests/sptls02/init.cc
> @@ -251,6 +251,9 @@ extern "C" void Init(rtems_task_argument arg)
>
> #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
>
> +#define CONFIGURE_MAXIMUM_POSIX_KEYS 2
> +#define CONFIGURE_MAXIMUM_POSIX_KEY_VALUE_PAIRS 2
> +
> #define CONFIGURE_INIT
>
> #include <rtems/confdefs.h>
> --
> 1.8.4.5
>
> _______________________________________________
> rtems-devel mailing list
> rtems-devel at rtems.org
> http://www.rtems.org/mailman/listinfo/rtems-devel
More information about the devel
mailing list