On Fri, Mar 21, 2014 at 5:26 AM, Christian Mauderer <christian.maude...@embedded-brains.de> wrote: > From: Christian Mauderer <christian.maude...@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@rtems.org > http://www.rtems.org/mailman/listinfo/rtems-devel _______________________________________________ rtems-devel mailing list rtems-devel@rtems.org http://www.rtems.org/mailman/listinfo/rtems-devel