mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2026-08-26 20:46:58 +08:00
Split key.c into multiple files.
This commit is contained in:
@@ -26,6 +26,9 @@ CONDITION_VARIABLE_C_PIECES= cond condattrdestroy condattrgetpshared \
|
||||
condattrinit condattrsetpshared condbroadcast conddefaultattributes \
|
||||
condmp condsignal condsignalsupp condtimedwait condwait condwaitsupp
|
||||
|
||||
KEY_C_PIECES= key keycreate keydelete keygetspecific keyrundestructors \
|
||||
keysetspecific
|
||||
|
||||
MESSAGE_QUEUE_C_PIECES= mqueue mqueueclose mqueuecreatesupp mqueuedeletesupp \
|
||||
mqueuegetattr mqueuenametoid mqueuenotify mqueueopen mqueuereceive \
|
||||
mqueuerecvsupp mqueuesend mqueuesendsupp mqueuesetattr \
|
||||
@@ -67,7 +70,7 @@ TIME_C_PIECES= time posixtimespecsubtract posixtimespectointerval \
|
||||
clockgetres clockgettime clocksetenableattr clocksettime nanosleep
|
||||
|
||||
C_PIECES = adasupp $(CONDITION_VARIABLE_C_PIECES) \
|
||||
getpid key $(MESSAGE_QUEUE_C_PIECES) \
|
||||
getpid $(KEY_C_PIECES) $(MESSAGE_QUEUE_C_PIECES) \
|
||||
$(MUTEX_C_PIECES) $(PTHREAD_C_PIECES) \
|
||||
$(PSIGNAL_C_PIECES) ptimer sched $(SEMAPHORE_C_PIECES) \
|
||||
$(TIME_C_PIECES) types unistd $(ENOSYS_C_PIECES) \
|
||||
|
||||
@@ -35,228 +35,3 @@ void _POSIX_Key_Manager_initialization(
|
||||
FALSE
|
||||
);
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* 17.1.1 Thread-Specific Data Key Create, P1003.1c/Draft 10, p. 163
|
||||
*/
|
||||
|
||||
int pthread_key_create(
|
||||
pthread_key_t *key,
|
||||
void (*destructor)( void * )
|
||||
)
|
||||
{
|
||||
POSIX_Keys_Control *the_key;
|
||||
void *table;
|
||||
unsigned32 the_class;
|
||||
unsigned32 bytes_to_allocate;
|
||||
|
||||
|
||||
_Thread_Disable_dispatch();
|
||||
|
||||
the_key = _POSIX_Keys_Allocate();
|
||||
|
||||
if ( !the_key ) {
|
||||
_Thread_Enable_dispatch();
|
||||
return EAGAIN;
|
||||
}
|
||||
|
||||
the_key->destructor = destructor;
|
||||
|
||||
for ( the_class = OBJECTS_CLASSES_FIRST_THREAD_CLASS;
|
||||
the_class <= OBJECTS_CLASSES_LAST_THREAD_CLASS;
|
||||
the_class++ ) {
|
||||
|
||||
bytes_to_allocate =
|
||||
(_Objects_Information_table[ the_class ]->maximum + 1) * sizeof( void * );
|
||||
|
||||
table = _Workspace_Allocate( bytes_to_allocate );
|
||||
|
||||
if ( !table ) {
|
||||
for ( --the_class;
|
||||
the_class >= OBJECTS_CLASSES_FIRST_THREAD_CLASS;
|
||||
the_class-- )
|
||||
_Workspace_Free( the_key->Values[ the_class ] );
|
||||
|
||||
_POSIX_Keys_Free( the_key );
|
||||
_Thread_Enable_dispatch();
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
the_key->Values[ the_class ] = table;
|
||||
memset( table, '\0', bytes_to_allocate );
|
||||
}
|
||||
|
||||
the_key->is_active = TRUE;
|
||||
|
||||
_Objects_Open( &_POSIX_Keys_Information, &the_key->Object, 0 );
|
||||
|
||||
*key = the_key->Object.id;
|
||||
|
||||
_Thread_Enable_dispatch();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* 17.1.2 Thread-Specific Data Management, P1003.1c/Draft 10, p. 165
|
||||
*/
|
||||
|
||||
int pthread_setspecific(
|
||||
pthread_key_t key,
|
||||
const void *value
|
||||
)
|
||||
{
|
||||
register POSIX_Keys_Control *the_key;
|
||||
unsigned32 index;
|
||||
unsigned32 class;
|
||||
Objects_Locations location;
|
||||
|
||||
the_key = _POSIX_Keys_Get( key, &location );
|
||||
switch ( location ) {
|
||||
case OBJECTS_ERROR:
|
||||
case OBJECTS_REMOTE: /* should never happen */
|
||||
return EINVAL;
|
||||
case OBJECTS_LOCAL:
|
||||
index = _Objects_Get_index( _Thread_Executing->Object.id );
|
||||
class = _Objects_Get_class( _Thread_Executing->Object.id );
|
||||
the_key->Values[ class ][ index ] = (void *) value;
|
||||
_Thread_Enable_dispatch();
|
||||
return 0;
|
||||
}
|
||||
return POSIX_BOTTOM_REACHED();
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* 17.1.2 Thread-Specific Data Management, P1003.1c/Draft 10, p. 165
|
||||
*/
|
||||
|
||||
void *pthread_getspecific(
|
||||
pthread_key_t key
|
||||
)
|
||||
{
|
||||
register POSIX_Keys_Control *the_key;
|
||||
unsigned32 index;
|
||||
unsigned32 class;
|
||||
Objects_Locations location;
|
||||
void *key_data;
|
||||
|
||||
the_key = _POSIX_Keys_Get( key, &location );
|
||||
switch ( location ) {
|
||||
case OBJECTS_ERROR:
|
||||
case OBJECTS_REMOTE: /* should never happen */
|
||||
return NULL;
|
||||
case OBJECTS_LOCAL:
|
||||
index = _Objects_Get_index( _Thread_Executing->Object.id );
|
||||
class = _Objects_Get_class( _Thread_Executing->Object.id );
|
||||
key_data = (void *) the_key->Values[ class ][ index ];
|
||||
_Thread_Enable_dispatch();
|
||||
return key_data;
|
||||
}
|
||||
return (void *) POSIX_BOTTOM_REACHED();
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* 17.1.3 Thread-Specific Data Key Deletion, P1003.1c/Draft 10, p. 167
|
||||
*/
|
||||
|
||||
int pthread_key_delete(
|
||||
pthread_key_t key
|
||||
)
|
||||
{
|
||||
register POSIX_Keys_Control *the_key;
|
||||
Objects_Locations location;
|
||||
unsigned32 the_class;
|
||||
|
||||
the_key = _POSIX_Keys_Get( key, &location );
|
||||
switch ( location ) {
|
||||
case OBJECTS_ERROR:
|
||||
case OBJECTS_REMOTE: /* should never happen */
|
||||
return EINVAL;
|
||||
case OBJECTS_LOCAL:
|
||||
_Objects_Close( &_POSIX_Keys_Information, &the_key->Object );
|
||||
|
||||
the_key->is_active = FALSE;
|
||||
|
||||
for ( the_class = OBJECTS_CLASSES_FIRST_THREAD_CLASS;
|
||||
the_class <= OBJECTS_CLASSES_LAST_THREAD_CLASS;
|
||||
the_class++ )
|
||||
_Workspace_Free( the_key->Values[ the_class ] );
|
||||
|
||||
/*
|
||||
* NOTE: The destructor is not called and it is the responsibility
|
||||
* of the application to free the memory.
|
||||
*/
|
||||
|
||||
_POSIX_Keys_Free( the_key );
|
||||
_Thread_Enable_dispatch();
|
||||
return 0;
|
||||
}
|
||||
return POSIX_BOTTOM_REACHED();
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _POSIX_Keys_Run_destructors
|
||||
*
|
||||
* 17.1.1 Thread-Specific Data Key Create, P1003.1c/Draft 10, p. 163
|
||||
*
|
||||
* NOTE: This is the routine executed when a thread exits to
|
||||
* run through all the keys and do the destructor action.
|
||||
*/
|
||||
|
||||
void _POSIX_Keys_Run_destructors(
|
||||
Thread_Control *thread
|
||||
)
|
||||
{
|
||||
unsigned32 index;
|
||||
unsigned32 pthread_index;
|
||||
unsigned32 pthread_class;
|
||||
unsigned32 iterations;
|
||||
boolean are_all_null;
|
||||
POSIX_Keys_Control *the_key;
|
||||
void *value;
|
||||
|
||||
pthread_index = _Objects_Get_index( thread->Object.id );
|
||||
pthread_class = _Objects_Get_class( thread->Object.id );
|
||||
|
||||
iterations = 0;
|
||||
|
||||
for ( ; ; ) {
|
||||
|
||||
are_all_null = TRUE;
|
||||
|
||||
for ( index=1 ; index <= _POSIX_Keys_Information.maximum ; index++ ) {
|
||||
|
||||
the_key = (POSIX_Keys_Control *)
|
||||
_POSIX_Keys_Information.local_table[ index ];
|
||||
|
||||
if ( the_key && the_key->is_active && the_key->destructor ) {
|
||||
value = the_key->Values[ pthread_class ][ pthread_index ];
|
||||
if ( value ) {
|
||||
(*the_key->destructor)( value );
|
||||
if ( the_key->Values[ pthread_class ][ pthread_index ] )
|
||||
are_all_null = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( are_all_null == TRUE )
|
||||
return;
|
||||
|
||||
iterations++;
|
||||
|
||||
/*
|
||||
* The standard allows one to not do this and thus go into an infinite
|
||||
* loop. It seems rude to unnecessarily lock up a system.
|
||||
*
|
||||
* Reference: 17.1.1.2 P1003.1c/Draft 10, p. 163, line 99.
|
||||
*/
|
||||
|
||||
if ( iterations >= PTHREAD_DESTRUCTOR_ITERATIONS )
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <pthread.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <rtems/system.h>
|
||||
#include <rtems/score/thread.h>
|
||||
#include <rtems/score/wkspace.h>
|
||||
#include <rtems/posix/key.h>
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* 17.1.1 Thread-Specific Data Key Create, P1003.1c/Draft 10, p. 163
|
||||
*/
|
||||
|
||||
int pthread_key_create(
|
||||
pthread_key_t *key,
|
||||
void (*destructor)( void * )
|
||||
)
|
||||
{
|
||||
POSIX_Keys_Control *the_key;
|
||||
void *table;
|
||||
unsigned32 the_class;
|
||||
unsigned32 bytes_to_allocate;
|
||||
|
||||
|
||||
_Thread_Disable_dispatch();
|
||||
|
||||
the_key = _POSIX_Keys_Allocate();
|
||||
|
||||
if ( !the_key ) {
|
||||
_Thread_Enable_dispatch();
|
||||
return EAGAIN;
|
||||
}
|
||||
|
||||
the_key->destructor = destructor;
|
||||
|
||||
for ( the_class = OBJECTS_CLASSES_FIRST_THREAD_CLASS;
|
||||
the_class <= OBJECTS_CLASSES_LAST_THREAD_CLASS;
|
||||
the_class++ ) {
|
||||
|
||||
bytes_to_allocate =
|
||||
(_Objects_Information_table[ the_class ]->maximum + 1) * sizeof( void * );
|
||||
|
||||
table = _Workspace_Allocate( bytes_to_allocate );
|
||||
|
||||
if ( !table ) {
|
||||
for ( --the_class;
|
||||
the_class >= OBJECTS_CLASSES_FIRST_THREAD_CLASS;
|
||||
the_class-- )
|
||||
_Workspace_Free( the_key->Values[ the_class ] );
|
||||
|
||||
_POSIX_Keys_Free( the_key );
|
||||
_Thread_Enable_dispatch();
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
the_key->Values[ the_class ] = table;
|
||||
memset( table, '\0', bytes_to_allocate );
|
||||
}
|
||||
|
||||
the_key->is_active = TRUE;
|
||||
|
||||
_Objects_Open( &_POSIX_Keys_Information, &the_key->Object, 0 );
|
||||
|
||||
*key = the_key->Object.id;
|
||||
|
||||
_Thread_Enable_dispatch();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <pthread.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <rtems/system.h>
|
||||
#include <rtems/score/thread.h>
|
||||
#include <rtems/score/wkspace.h>
|
||||
#include <rtems/posix/key.h>
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* 17.1.3 Thread-Specific Data Key Deletion, P1003.1c/Draft 10, p. 167
|
||||
*/
|
||||
|
||||
int pthread_key_delete(
|
||||
pthread_key_t key
|
||||
)
|
||||
{
|
||||
register POSIX_Keys_Control *the_key;
|
||||
Objects_Locations location;
|
||||
unsigned32 the_class;
|
||||
|
||||
the_key = _POSIX_Keys_Get( key, &location );
|
||||
switch ( location ) {
|
||||
case OBJECTS_ERROR:
|
||||
case OBJECTS_REMOTE: /* should never happen */
|
||||
return EINVAL;
|
||||
case OBJECTS_LOCAL:
|
||||
_Objects_Close( &_POSIX_Keys_Information, &the_key->Object );
|
||||
|
||||
the_key->is_active = FALSE;
|
||||
|
||||
for ( the_class = OBJECTS_CLASSES_FIRST_THREAD_CLASS;
|
||||
the_class <= OBJECTS_CLASSES_LAST_THREAD_CLASS;
|
||||
the_class++ )
|
||||
_Workspace_Free( the_key->Values[ the_class ] );
|
||||
|
||||
/*
|
||||
* NOTE: The destructor is not called and it is the responsibility
|
||||
* of the application to free the memory.
|
||||
*/
|
||||
|
||||
_POSIX_Keys_Free( the_key );
|
||||
_Thread_Enable_dispatch();
|
||||
return 0;
|
||||
}
|
||||
return POSIX_BOTTOM_REACHED();
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <pthread.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <rtems/system.h>
|
||||
#include <rtems/score/thread.h>
|
||||
#include <rtems/score/wkspace.h>
|
||||
#include <rtems/posix/key.h>
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* 17.1.2 Thread-Specific Data Management, P1003.1c/Draft 10, p. 165
|
||||
*/
|
||||
|
||||
void *pthread_getspecific(
|
||||
pthread_key_t key
|
||||
)
|
||||
{
|
||||
register POSIX_Keys_Control *the_key;
|
||||
unsigned32 index;
|
||||
unsigned32 class;
|
||||
Objects_Locations location;
|
||||
void *key_data;
|
||||
|
||||
the_key = _POSIX_Keys_Get( key, &location );
|
||||
switch ( location ) {
|
||||
case OBJECTS_ERROR:
|
||||
case OBJECTS_REMOTE: /* should never happen */
|
||||
return NULL;
|
||||
case OBJECTS_LOCAL:
|
||||
index = _Objects_Get_index( _Thread_Executing->Object.id );
|
||||
class = _Objects_Get_class( _Thread_Executing->Object.id );
|
||||
key_data = (void *) the_key->Values[ class ][ index ];
|
||||
_Thread_Enable_dispatch();
|
||||
return key_data;
|
||||
}
|
||||
return (void *) POSIX_BOTTOM_REACHED();
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <pthread.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <rtems/system.h>
|
||||
#include <rtems/score/thread.h>
|
||||
#include <rtems/score/wkspace.h>
|
||||
#include <rtems/posix/key.h>
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _POSIX_Keys_Run_destructors
|
||||
*
|
||||
* 17.1.1 Thread-Specific Data Key Create, P1003.1c/Draft 10, p. 163
|
||||
*
|
||||
* NOTE: This is the routine executed when a thread exits to
|
||||
* run through all the keys and do the destructor action.
|
||||
*/
|
||||
|
||||
void _POSIX_Keys_Run_destructors(
|
||||
Thread_Control *thread
|
||||
)
|
||||
{
|
||||
unsigned32 index;
|
||||
unsigned32 pthread_index;
|
||||
unsigned32 pthread_class;
|
||||
unsigned32 iterations;
|
||||
boolean are_all_null;
|
||||
POSIX_Keys_Control *the_key;
|
||||
void *value;
|
||||
|
||||
pthread_index = _Objects_Get_index( thread->Object.id );
|
||||
pthread_class = _Objects_Get_class( thread->Object.id );
|
||||
|
||||
iterations = 0;
|
||||
|
||||
for ( ; ; ) {
|
||||
|
||||
are_all_null = TRUE;
|
||||
|
||||
for ( index=1 ; index <= _POSIX_Keys_Information.maximum ; index++ ) {
|
||||
|
||||
the_key = (POSIX_Keys_Control *)
|
||||
_POSIX_Keys_Information.local_table[ index ];
|
||||
|
||||
if ( the_key && the_key->is_active && the_key->destructor ) {
|
||||
value = the_key->Values[ pthread_class ][ pthread_index ];
|
||||
if ( value ) {
|
||||
(*the_key->destructor)( value );
|
||||
if ( the_key->Values[ pthread_class ][ pthread_index ] )
|
||||
are_all_null = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( are_all_null == TRUE )
|
||||
return;
|
||||
|
||||
iterations++;
|
||||
|
||||
/*
|
||||
* The standard allows one to not do this and thus go into an infinite
|
||||
* loop. It seems rude to unnecessarily lock up a system.
|
||||
*
|
||||
* Reference: 17.1.1.2 P1003.1c/Draft 10, p. 163, line 99.
|
||||
*/
|
||||
|
||||
if ( iterations >= PTHREAD_DESTRUCTOR_ITERATIONS )
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <pthread.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <rtems/system.h>
|
||||
#include <rtems/score/thread.h>
|
||||
#include <rtems/score/wkspace.h>
|
||||
#include <rtems/posix/key.h>
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* 17.1.2 Thread-Specific Data Management, P1003.1c/Draft 10, p. 165
|
||||
*/
|
||||
|
||||
int pthread_setspecific(
|
||||
pthread_key_t key,
|
||||
const void *value
|
||||
)
|
||||
{
|
||||
register POSIX_Keys_Control *the_key;
|
||||
unsigned32 index;
|
||||
unsigned32 class;
|
||||
Objects_Locations location;
|
||||
|
||||
the_key = _POSIX_Keys_Get( key, &location );
|
||||
switch ( location ) {
|
||||
case OBJECTS_ERROR:
|
||||
case OBJECTS_REMOTE: /* should never happen */
|
||||
return EINVAL;
|
||||
case OBJECTS_LOCAL:
|
||||
index = _Objects_Get_index( _Thread_Executing->Object.id );
|
||||
class = _Objects_Get_class( _Thread_Executing->Object.id );
|
||||
the_key->Values[ class ][ index ] = (void *) value;
|
||||
_Thread_Enable_dispatch();
|
||||
return 0;
|
||||
}
|
||||
return POSIX_BOTTOM_REACHED();
|
||||
}
|
||||
@@ -35,228 +35,3 @@ void _POSIX_Key_Manager_initialization(
|
||||
FALSE
|
||||
);
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* 17.1.1 Thread-Specific Data Key Create, P1003.1c/Draft 10, p. 163
|
||||
*/
|
||||
|
||||
int pthread_key_create(
|
||||
pthread_key_t *key,
|
||||
void (*destructor)( void * )
|
||||
)
|
||||
{
|
||||
POSIX_Keys_Control *the_key;
|
||||
void *table;
|
||||
unsigned32 the_class;
|
||||
unsigned32 bytes_to_allocate;
|
||||
|
||||
|
||||
_Thread_Disable_dispatch();
|
||||
|
||||
the_key = _POSIX_Keys_Allocate();
|
||||
|
||||
if ( !the_key ) {
|
||||
_Thread_Enable_dispatch();
|
||||
return EAGAIN;
|
||||
}
|
||||
|
||||
the_key->destructor = destructor;
|
||||
|
||||
for ( the_class = OBJECTS_CLASSES_FIRST_THREAD_CLASS;
|
||||
the_class <= OBJECTS_CLASSES_LAST_THREAD_CLASS;
|
||||
the_class++ ) {
|
||||
|
||||
bytes_to_allocate =
|
||||
(_Objects_Information_table[ the_class ]->maximum + 1) * sizeof( void * );
|
||||
|
||||
table = _Workspace_Allocate( bytes_to_allocate );
|
||||
|
||||
if ( !table ) {
|
||||
for ( --the_class;
|
||||
the_class >= OBJECTS_CLASSES_FIRST_THREAD_CLASS;
|
||||
the_class-- )
|
||||
_Workspace_Free( the_key->Values[ the_class ] );
|
||||
|
||||
_POSIX_Keys_Free( the_key );
|
||||
_Thread_Enable_dispatch();
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
the_key->Values[ the_class ] = table;
|
||||
memset( table, '\0', bytes_to_allocate );
|
||||
}
|
||||
|
||||
the_key->is_active = TRUE;
|
||||
|
||||
_Objects_Open( &_POSIX_Keys_Information, &the_key->Object, 0 );
|
||||
|
||||
*key = the_key->Object.id;
|
||||
|
||||
_Thread_Enable_dispatch();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* 17.1.2 Thread-Specific Data Management, P1003.1c/Draft 10, p. 165
|
||||
*/
|
||||
|
||||
int pthread_setspecific(
|
||||
pthread_key_t key,
|
||||
const void *value
|
||||
)
|
||||
{
|
||||
register POSIX_Keys_Control *the_key;
|
||||
unsigned32 index;
|
||||
unsigned32 class;
|
||||
Objects_Locations location;
|
||||
|
||||
the_key = _POSIX_Keys_Get( key, &location );
|
||||
switch ( location ) {
|
||||
case OBJECTS_ERROR:
|
||||
case OBJECTS_REMOTE: /* should never happen */
|
||||
return EINVAL;
|
||||
case OBJECTS_LOCAL:
|
||||
index = _Objects_Get_index( _Thread_Executing->Object.id );
|
||||
class = _Objects_Get_class( _Thread_Executing->Object.id );
|
||||
the_key->Values[ class ][ index ] = (void *) value;
|
||||
_Thread_Enable_dispatch();
|
||||
return 0;
|
||||
}
|
||||
return POSIX_BOTTOM_REACHED();
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* 17.1.2 Thread-Specific Data Management, P1003.1c/Draft 10, p. 165
|
||||
*/
|
||||
|
||||
void *pthread_getspecific(
|
||||
pthread_key_t key
|
||||
)
|
||||
{
|
||||
register POSIX_Keys_Control *the_key;
|
||||
unsigned32 index;
|
||||
unsigned32 class;
|
||||
Objects_Locations location;
|
||||
void *key_data;
|
||||
|
||||
the_key = _POSIX_Keys_Get( key, &location );
|
||||
switch ( location ) {
|
||||
case OBJECTS_ERROR:
|
||||
case OBJECTS_REMOTE: /* should never happen */
|
||||
return NULL;
|
||||
case OBJECTS_LOCAL:
|
||||
index = _Objects_Get_index( _Thread_Executing->Object.id );
|
||||
class = _Objects_Get_class( _Thread_Executing->Object.id );
|
||||
key_data = (void *) the_key->Values[ class ][ index ];
|
||||
_Thread_Enable_dispatch();
|
||||
return key_data;
|
||||
}
|
||||
return (void *) POSIX_BOTTOM_REACHED();
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* 17.1.3 Thread-Specific Data Key Deletion, P1003.1c/Draft 10, p. 167
|
||||
*/
|
||||
|
||||
int pthread_key_delete(
|
||||
pthread_key_t key
|
||||
)
|
||||
{
|
||||
register POSIX_Keys_Control *the_key;
|
||||
Objects_Locations location;
|
||||
unsigned32 the_class;
|
||||
|
||||
the_key = _POSIX_Keys_Get( key, &location );
|
||||
switch ( location ) {
|
||||
case OBJECTS_ERROR:
|
||||
case OBJECTS_REMOTE: /* should never happen */
|
||||
return EINVAL;
|
||||
case OBJECTS_LOCAL:
|
||||
_Objects_Close( &_POSIX_Keys_Information, &the_key->Object );
|
||||
|
||||
the_key->is_active = FALSE;
|
||||
|
||||
for ( the_class = OBJECTS_CLASSES_FIRST_THREAD_CLASS;
|
||||
the_class <= OBJECTS_CLASSES_LAST_THREAD_CLASS;
|
||||
the_class++ )
|
||||
_Workspace_Free( the_key->Values[ the_class ] );
|
||||
|
||||
/*
|
||||
* NOTE: The destructor is not called and it is the responsibility
|
||||
* of the application to free the memory.
|
||||
*/
|
||||
|
||||
_POSIX_Keys_Free( the_key );
|
||||
_Thread_Enable_dispatch();
|
||||
return 0;
|
||||
}
|
||||
return POSIX_BOTTOM_REACHED();
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _POSIX_Keys_Run_destructors
|
||||
*
|
||||
* 17.1.1 Thread-Specific Data Key Create, P1003.1c/Draft 10, p. 163
|
||||
*
|
||||
* NOTE: This is the routine executed when a thread exits to
|
||||
* run through all the keys and do the destructor action.
|
||||
*/
|
||||
|
||||
void _POSIX_Keys_Run_destructors(
|
||||
Thread_Control *thread
|
||||
)
|
||||
{
|
||||
unsigned32 index;
|
||||
unsigned32 pthread_index;
|
||||
unsigned32 pthread_class;
|
||||
unsigned32 iterations;
|
||||
boolean are_all_null;
|
||||
POSIX_Keys_Control *the_key;
|
||||
void *value;
|
||||
|
||||
pthread_index = _Objects_Get_index( thread->Object.id );
|
||||
pthread_class = _Objects_Get_class( thread->Object.id );
|
||||
|
||||
iterations = 0;
|
||||
|
||||
for ( ; ; ) {
|
||||
|
||||
are_all_null = TRUE;
|
||||
|
||||
for ( index=1 ; index <= _POSIX_Keys_Information.maximum ; index++ ) {
|
||||
|
||||
the_key = (POSIX_Keys_Control *)
|
||||
_POSIX_Keys_Information.local_table[ index ];
|
||||
|
||||
if ( the_key && the_key->is_active && the_key->destructor ) {
|
||||
value = the_key->Values[ pthread_class ][ pthread_index ];
|
||||
if ( value ) {
|
||||
(*the_key->destructor)( value );
|
||||
if ( the_key->Values[ pthread_class ][ pthread_index ] )
|
||||
are_all_null = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( are_all_null == TRUE )
|
||||
return;
|
||||
|
||||
iterations++;
|
||||
|
||||
/*
|
||||
* The standard allows one to not do this and thus go into an infinite
|
||||
* loop. It seems rude to unnecessarily lock up a system.
|
||||
*
|
||||
* Reference: 17.1.1.2 P1003.1c/Draft 10, p. 163, line 99.
|
||||
*/
|
||||
|
||||
if ( iterations >= PTHREAD_DESTRUCTOR_ITERATIONS )
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <pthread.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <rtems/system.h>
|
||||
#include <rtems/score/thread.h>
|
||||
#include <rtems/score/wkspace.h>
|
||||
#include <rtems/posix/key.h>
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* 17.1.1 Thread-Specific Data Key Create, P1003.1c/Draft 10, p. 163
|
||||
*/
|
||||
|
||||
int pthread_key_create(
|
||||
pthread_key_t *key,
|
||||
void (*destructor)( void * )
|
||||
)
|
||||
{
|
||||
POSIX_Keys_Control *the_key;
|
||||
void *table;
|
||||
unsigned32 the_class;
|
||||
unsigned32 bytes_to_allocate;
|
||||
|
||||
|
||||
_Thread_Disable_dispatch();
|
||||
|
||||
the_key = _POSIX_Keys_Allocate();
|
||||
|
||||
if ( !the_key ) {
|
||||
_Thread_Enable_dispatch();
|
||||
return EAGAIN;
|
||||
}
|
||||
|
||||
the_key->destructor = destructor;
|
||||
|
||||
for ( the_class = OBJECTS_CLASSES_FIRST_THREAD_CLASS;
|
||||
the_class <= OBJECTS_CLASSES_LAST_THREAD_CLASS;
|
||||
the_class++ ) {
|
||||
|
||||
bytes_to_allocate =
|
||||
(_Objects_Information_table[ the_class ]->maximum + 1) * sizeof( void * );
|
||||
|
||||
table = _Workspace_Allocate( bytes_to_allocate );
|
||||
|
||||
if ( !table ) {
|
||||
for ( --the_class;
|
||||
the_class >= OBJECTS_CLASSES_FIRST_THREAD_CLASS;
|
||||
the_class-- )
|
||||
_Workspace_Free( the_key->Values[ the_class ] );
|
||||
|
||||
_POSIX_Keys_Free( the_key );
|
||||
_Thread_Enable_dispatch();
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
the_key->Values[ the_class ] = table;
|
||||
memset( table, '\0', bytes_to_allocate );
|
||||
}
|
||||
|
||||
the_key->is_active = TRUE;
|
||||
|
||||
_Objects_Open( &_POSIX_Keys_Information, &the_key->Object, 0 );
|
||||
|
||||
*key = the_key->Object.id;
|
||||
|
||||
_Thread_Enable_dispatch();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <pthread.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <rtems/system.h>
|
||||
#include <rtems/score/thread.h>
|
||||
#include <rtems/score/wkspace.h>
|
||||
#include <rtems/posix/key.h>
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* 17.1.3 Thread-Specific Data Key Deletion, P1003.1c/Draft 10, p. 167
|
||||
*/
|
||||
|
||||
int pthread_key_delete(
|
||||
pthread_key_t key
|
||||
)
|
||||
{
|
||||
register POSIX_Keys_Control *the_key;
|
||||
Objects_Locations location;
|
||||
unsigned32 the_class;
|
||||
|
||||
the_key = _POSIX_Keys_Get( key, &location );
|
||||
switch ( location ) {
|
||||
case OBJECTS_ERROR:
|
||||
case OBJECTS_REMOTE: /* should never happen */
|
||||
return EINVAL;
|
||||
case OBJECTS_LOCAL:
|
||||
_Objects_Close( &_POSIX_Keys_Information, &the_key->Object );
|
||||
|
||||
the_key->is_active = FALSE;
|
||||
|
||||
for ( the_class = OBJECTS_CLASSES_FIRST_THREAD_CLASS;
|
||||
the_class <= OBJECTS_CLASSES_LAST_THREAD_CLASS;
|
||||
the_class++ )
|
||||
_Workspace_Free( the_key->Values[ the_class ] );
|
||||
|
||||
/*
|
||||
* NOTE: The destructor is not called and it is the responsibility
|
||||
* of the application to free the memory.
|
||||
*/
|
||||
|
||||
_POSIX_Keys_Free( the_key );
|
||||
_Thread_Enable_dispatch();
|
||||
return 0;
|
||||
}
|
||||
return POSIX_BOTTOM_REACHED();
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <pthread.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <rtems/system.h>
|
||||
#include <rtems/score/thread.h>
|
||||
#include <rtems/score/wkspace.h>
|
||||
#include <rtems/posix/key.h>
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* 17.1.2 Thread-Specific Data Management, P1003.1c/Draft 10, p. 165
|
||||
*/
|
||||
|
||||
void *pthread_getspecific(
|
||||
pthread_key_t key
|
||||
)
|
||||
{
|
||||
register POSIX_Keys_Control *the_key;
|
||||
unsigned32 index;
|
||||
unsigned32 class;
|
||||
Objects_Locations location;
|
||||
void *key_data;
|
||||
|
||||
the_key = _POSIX_Keys_Get( key, &location );
|
||||
switch ( location ) {
|
||||
case OBJECTS_ERROR:
|
||||
case OBJECTS_REMOTE: /* should never happen */
|
||||
return NULL;
|
||||
case OBJECTS_LOCAL:
|
||||
index = _Objects_Get_index( _Thread_Executing->Object.id );
|
||||
class = _Objects_Get_class( _Thread_Executing->Object.id );
|
||||
key_data = (void *) the_key->Values[ class ][ index ];
|
||||
_Thread_Enable_dispatch();
|
||||
return key_data;
|
||||
}
|
||||
return (void *) POSIX_BOTTOM_REACHED();
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <pthread.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <rtems/system.h>
|
||||
#include <rtems/score/thread.h>
|
||||
#include <rtems/score/wkspace.h>
|
||||
#include <rtems/posix/key.h>
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _POSIX_Keys_Run_destructors
|
||||
*
|
||||
* 17.1.1 Thread-Specific Data Key Create, P1003.1c/Draft 10, p. 163
|
||||
*
|
||||
* NOTE: This is the routine executed when a thread exits to
|
||||
* run through all the keys and do the destructor action.
|
||||
*/
|
||||
|
||||
void _POSIX_Keys_Run_destructors(
|
||||
Thread_Control *thread
|
||||
)
|
||||
{
|
||||
unsigned32 index;
|
||||
unsigned32 pthread_index;
|
||||
unsigned32 pthread_class;
|
||||
unsigned32 iterations;
|
||||
boolean are_all_null;
|
||||
POSIX_Keys_Control *the_key;
|
||||
void *value;
|
||||
|
||||
pthread_index = _Objects_Get_index( thread->Object.id );
|
||||
pthread_class = _Objects_Get_class( thread->Object.id );
|
||||
|
||||
iterations = 0;
|
||||
|
||||
for ( ; ; ) {
|
||||
|
||||
are_all_null = TRUE;
|
||||
|
||||
for ( index=1 ; index <= _POSIX_Keys_Information.maximum ; index++ ) {
|
||||
|
||||
the_key = (POSIX_Keys_Control *)
|
||||
_POSIX_Keys_Information.local_table[ index ];
|
||||
|
||||
if ( the_key && the_key->is_active && the_key->destructor ) {
|
||||
value = the_key->Values[ pthread_class ][ pthread_index ];
|
||||
if ( value ) {
|
||||
(*the_key->destructor)( value );
|
||||
if ( the_key->Values[ pthread_class ][ pthread_index ] )
|
||||
are_all_null = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( are_all_null == TRUE )
|
||||
return;
|
||||
|
||||
iterations++;
|
||||
|
||||
/*
|
||||
* The standard allows one to not do this and thus go into an infinite
|
||||
* loop. It seems rude to unnecessarily lock up a system.
|
||||
*
|
||||
* Reference: 17.1.1.2 P1003.1c/Draft 10, p. 163, line 99.
|
||||
*/
|
||||
|
||||
if ( iterations >= PTHREAD_DESTRUCTOR_ITERATIONS )
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <pthread.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <rtems/system.h>
|
||||
#include <rtems/score/thread.h>
|
||||
#include <rtems/score/wkspace.h>
|
||||
#include <rtems/posix/key.h>
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* 17.1.2 Thread-Specific Data Management, P1003.1c/Draft 10, p. 165
|
||||
*/
|
||||
|
||||
int pthread_setspecific(
|
||||
pthread_key_t key,
|
||||
const void *value
|
||||
)
|
||||
{
|
||||
register POSIX_Keys_Control *the_key;
|
||||
unsigned32 index;
|
||||
unsigned32 class;
|
||||
Objects_Locations location;
|
||||
|
||||
the_key = _POSIX_Keys_Get( key, &location );
|
||||
switch ( location ) {
|
||||
case OBJECTS_ERROR:
|
||||
case OBJECTS_REMOTE: /* should never happen */
|
||||
return EINVAL;
|
||||
case OBJECTS_LOCAL:
|
||||
index = _Objects_Get_index( _Thread_Executing->Object.id );
|
||||
class = _Objects_Get_class( _Thread_Executing->Object.id );
|
||||
the_key->Values[ class ][ index ] = (void *) value;
|
||||
_Thread_Enable_dispatch();
|
||||
return 0;
|
||||
}
|
||||
return POSIX_BOTTOM_REACHED();
|
||||
}
|
||||
Reference in New Issue
Block a user