diff options
44 files changed, 1740 insertions, 175 deletions
diff --git a/cpukit/posix/include/rtems/posix/config.h b/cpukit/posix/include/rtems/posix/config.h index 104bd84046..a842f7a453 100644 --- a/cpukit/posix/include/rtems/posix/config.h +++ b/cpukit/posix/include/rtems/posix/config.h @@ -51,6 +51,7 @@ typedef struct { uint32_t maximum_mutexes; uint32_t maximum_condition_variables; uint32_t maximum_keys; + uint32_t maximum_key_value_pairs; uint32_t maximum_timers; uint32_t maximum_queued_signals; uint32_t maximum_message_queues; diff --git a/cpukit/posix/include/rtems/posix/key.h b/cpukit/posix/include/rtems/posix/key.h index 6d2ebff6fd..ee5b573c9b 100644 --- a/cpukit/posix/include/rtems/posix/key.h +++ b/cpukit/posix/include/rtems/posix/key.h @@ -1,6 +1,6 @@ /** * @file - * + * * @brief POSIX Key Private Support * * This include file contains all the private support information for @@ -8,24 +8,28 @@ */ /* - * COPYRIGHT (c) 1989-2011. - * On-Line Applications Research Corporation (OAR). + * Copyright (c) 2012 Zhongwei Yao. + * COPYRIGHT (c) 1989-2011. + * On-Line Applications Research Corporation (OAR). * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.com/license/LICENSE. + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. */ #ifndef _RTEMS_POSIX_KEY_H #define _RTEMS_POSIX_KEY_H +#include <rtems/score/rbtree.h> +#include <rtems/score/chainimpl.h> +#include <rtems/score/freechain.h> #include <rtems/score/objectimpl.h> /** * @defgroup POSIX_KEY POSIX Key * * @ingroup POSIXAPI - * + * */ /**@{**/ @@ -34,40 +38,86 @@ extern "C" { #endif /** - * This is the data Structure used to manage a POSIX key. - * - * NOTE: The Values is a table indexed by the index portion of the - * ID of the currently executing thread. + * @brief The rbtree node used to manage a POSIX key and value. + */ +typedef struct { + /** This field is the chain node structure. */ + Chain_Node Key_values_per_thread_node; + /** This field is the rbtree node structure. */ + RBTree_Node Key_value_lookup_node; + /** This field is the POSIX key used as an rbtree key */ + pthread_key_t key; + /** This field is the Thread id also used as an rbtree key */ + Objects_Id thread_id; + /** This field points to the POSIX key value of specific thread */ + void *value; +} POSIX_Keys_Key_value_pair; + +/** + * @brief POSIX_Keys_Freechain is used in Freechain structure + */ +typedef struct { + Freechain_Control super_fc; + size_t bump_count; +} POSIX_Keys_Freechain; + +/** + * @brief The data structure used to manage a POSIX key. */ typedef struct { /** This field is the Object control structure. */ Objects_Control Object; - /** This field points to the optional destructor method. */ - void (*destructor)( void * ); - /** This field points to the values per thread. */ - void **Values[ OBJECTS_APIS_LAST + 1 ]; -} POSIX_Keys_Control; + /** This field is the data destructor. */ + void (*destructor) (void *); + } POSIX_Keys_Control; /** - * The following defines the information control block used to manage - * this class of objects. + * @brief The information control block used to manage this class of objects. */ POSIX_EXTERN Objects_Information _POSIX_Keys_Information; /** - * @brief POSIX keys manager initialization. + * @brief The rbtree control block used to manage all key values + */ +POSIX_EXTERN RBTree_Control _POSIX_Keys_Key_value_lookup_tree; + +/** + * @brief This freechain is used as a memory pool for POSIX_Keys_Key_value_pair. + */ +POSIX_EXTERN POSIX_Keys_Freechain _POSIX_Keys_Keypool; + +/** + * @brief POSIX key manager initialization. * * This routine performs the initialization necessary for this manager. */ void _POSIX_Key_Manager_initialization(void); /** + * @brief POSIX key Freechain extend handle + * + * This routine extend freechain node, which is called in freechain_get + * automatically. + */ +bool _POSIX_Keys_Freechain_extend(Freechain_Control *freechain); + +/** + * @brief POSIX keys Red-Black tree node comparison. + * + * This routine compares the rbtree node + */ +int _POSIX_Keys_Key_value_lookup_tree_compare_function( + const RBTree_Node *node1, + const RBTree_Node *node2 +); + +/** * @brief Create thread-specific data POSIX key. * * This function executes all the destructors associated with the thread's * keys. This function will execute until all values have been set to NULL. * - * @param[in] thread is a pointer to the thread whose keys should have + * @param[in] thread is a pointer to the thread whose keys should have * all their destructors run. * * NOTE: This is the routine executed when a thread exits to diff --git a/cpukit/posix/include/rtems/posix/threadsup.h b/cpukit/posix/include/rtems/posix/threadsup.h index 414b46fd83..7bd1f934ad 100644 --- a/cpukit/posix/include/rtems/posix/threadsup.h +++ b/cpukit/posix/include/rtems/posix/threadsup.h @@ -83,6 +83,15 @@ typedef struct { /** This is the set of cancelation handlers. */ Chain_Control Cancellation_Handlers; + /** + * This is the thread key value chain's control, which is used + * to track all key value for specific thread, and when thread + * exits, we can remove all key value for specific thread by + * iterating this chain, or we have to search a whole rbtree, + * which is inefficient. + */ + Chain_Control Key_Chain; + } POSIX_API_Control; /** diff --git a/cpukit/posix/src/key.c b/cpukit/posix/src/key.c index 6eace26eed..2bb415c4d5 100644 --- a/cpukit/posix/src/key.c +++ b/cpukit/posix/src/key.c @@ -6,12 +6,13 @@ */ /* - * COPYRIGHT (c) 1989-2008. - * On-Line Applications Research Corporation (OAR). + * Copyright (c) 2012 Zhongwei Yao. + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.com/license/LICENSE. + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. */ #if HAVE_CONFIG_H @@ -29,19 +30,115 @@ #include <rtems/score/thread.h> #include <rtems/score/wkspace.h> #include <rtems/posix/key.h> +#include <rtems/score/rbtree.h> +#include <rtems/score/chain.h> +#include <rtems/score/freechain.h> -/* - * _POSIX_Key_Manager_initialization - * - * DESCRIPTION: - * - * This routine performs the initialization necessary for this manager. +/* forward declarations to avoid warnings */ +void _POSIX_Keys_Keypool_init(void); +void _POSIX_Keys_Freechain_init(Freechain_Control *freechain); + +/** + * @brief This routine compares the rbtree node by comparing POSIX key first + * and comparing thread id second. * - * Input parameters: NONE + * if either of the input nodes's thread_id member is 0, then it will only + * compare the pthread_key_t member. That is when we pass thread_id = 0 node + * as a search node, the search is done only by pthread_key_t. * - * Output parameters: NONE + * @param[in] node1 The node to be compared + * @param[in] node2 The node to be compared + * @retval positive if first node has higher key than second + * @retval negative if lower + * @retval 0 if equal,and for all the thread id is unique, then return 0 is + * impossible */ +int _POSIX_Keys_Key_value_lookup_tree_compare_function( + const RBTree_Node *node1, + const RBTree_Node *node2 +) +{ + POSIX_Keys_Key_value_pair *n1; + POSIX_Keys_Key_value_pair *n2; + Objects_Id thread_id1, thread_id2; + int diff; + + n1 = _RBTree_Container_of( node1, POSIX_Keys_Key_value_pair, Key_value_lookup_node ); + n2 = _RBTree_Container_of( node2, POSIX_Keys_Key_value_pair, Key_value_lookup_node ); + + diff = n1->key - n2->key; + if ( diff ) + return diff; + + thread_id1 = n1->thread_id; + thread_id2 = n2->thread_id; + + /** + * if thread_id1 or thread_id2 equals to 0, only key1 and key2 is valued. + * it enables us search node only by pthread_key_t type key. + */ + if ( thread_id1 && thread_id2 ) + return thread_id1 - thread_id2; + return 0; +} + +/** + * @brief This routine does keypool initialize, keypool contains all + * POSIX_Keys_Key_value_pair + */ + +void _POSIX_Keys_Keypool_init(void) +{ + _Freechain_Initialize((Freechain_Control *)&_POSIX_Keys_Keypool, + &_POSIX_Keys_Freechain_extend); + + _POSIX_Keys_Freechain_init((Freechain_Control *)&_POSIX_Keys_Keypool); +} + +/** + * @brief This routine does user side freechain initialization + */ +void _POSIX_Keys_Freechain_init(Freechain_Control *freechain) +{ + POSIX_Keys_Freechain *psx_freechain_p = (POSIX_Keys_Freechain *)freechain; + psx_freechain_p->bump_count = + Configuration_POSIX_API.maximum_key_value_pairs & 0x7FFFFFFF; + size_t size = psx_freechain_p->bump_count * sizeof(POSIX_Keys_Key_value_pair); + POSIX_Keys_Key_value_pair *nodes = _Workspace_Allocate(size); + + _Chain_Initialize( + &freechain->Freechain, + nodes, + psx_freechain_p->bump_count, + sizeof(POSIX_Keys_Key_value_pair) + ); +} + +/** + * @brief This routine is user defined freechain extension handle + */ +bool _POSIX_Keys_Freechain_extend(Freechain_Control *freechain) +{ + POSIX_Keys_Freechain *psx_freechain_p = (POSIX_Keys_Freechain *)freechain; + size_t node_size = sizeof(POSIX_Keys_Key_value_pair); + size_t size = psx_freechain_p->bump_count * node_size; + int i; + POSIX_Keys_Key_value_pair *nodes = _Workspace_Allocate(size); + + if (!nodes) + return false; + + for ( i = 0; i < psx_freechain_p->bump_count; i++ ) { + _Freechain_Put(freechain, + nodes + i); + } + return true; +} + +/** + * @brief This routine performs the initialization necessary for this manager. + */ void _POSIX_Key_Manager_initialization(void) { _Objects_Initialize_information( @@ -60,4 +157,12 @@ void _POSIX_Key_Manager_initialization(void) NULL /* Proxy extraction support callout */ #endif ); + + _RBTree_Initialize_empty( + &_POSIX_Keys_Key_value_lookup_tree, + _POSIX_Keys_Key_value_lookup_tree_compare_function, + true + ); + + _POSIX_Keys_Keypool_init(); } diff --git a/cpukit/posix/src/keycreate.c b/cpukit/posix/src/keycreate.c index b41b59017e..349e88378a 100644 --- a/cpukit/posix/src/keycreate.c +++ b/cpukit/posix/src/keycreate.c @@ -1,17 +1,17 @@ /** - * @file + * @file * - * @brief Thread-Specific Data Key Create - * @ingroup POSIXAPI + * @brief Thread-Specific Data Key Create + * @ingroup POSIXAPI */ /* - * COPYRIGHT (c) 1989-2010. - * On-Line Applications Research Corporation (OAR). + * COPYRIGHT (c) 1989-2010. + * On-Line Applications Research Corporation (OAR). * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.com/license/LICENSE. + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. */ #if HAVE_CONFIG_H @@ -37,10 +37,6 @@ int pthread_key_create( ) { POSIX_Keys_Control *the_key; - void *table; - uint32_t the_api; - uint32_t bytes_to_allocate; - _Thread_Disable_dispatch(); @@ -52,50 +48,6 @@ int pthread_key_create( } the_key->destructor = destructor; - - /* - * This is a bit more complex than one might initially expect because - * APIs are optional. - * - * NOTE: Currently RTEMS Classic API tasks are always enabled. - */ - for ( the_api = 1; the_api <= OBJECTS_APIS_LAST; the_api++ ) { - the_key->Values[ the_api ] = NULL; - - #if defined(RTEMS_DEBUG) - /* - * Since the removal of ITRON, this cannot occur. - */ - if ( !_Objects_Information_table[ the_api ] ) - continue; - - /* - * Currently all managers are installed if the API is installed. - * This would be a horrible implementation error. - */ - if (_Objects_Information_table[ the_api ][ 1 ] == NULL ) - _Internal_error_Occurred( - INTERNAL_ERROR_CORE, - true, - INTERNAL_ERROR_IMPLEMENTATION_KEY_CREATE_INCONSISTENCY - ); - #endif - - bytes_to_allocate = sizeof( void * ) * - (_Objects_Information_table[ the_api ][ 1 ]->maximum + 1); - table = _Workspace_Allocate( bytes_to_allocate ); - if ( !table ) { - _POSIX_Keys_Free_memory( the_key ); - - _POSIX_Keys_Free( the_key ); - _Thread_Enable_dispatch(); - return ENOMEM; - } - - the_key->Values[ the_api ] = table; - memset( table, '\0', bytes_to_allocate ); - } - _Objects_Open_u32( &_POSIX_Keys_Information, &the_key->Object, 0 ); *key = the_key->Object.id; _Thread_Enable_dispatch(); diff --git a/cpukit/posix/src/keydelete.c b/cpukit/posix/src/keydelete.c index 8f96ca36fe..c3d3da1a3b 100644 --- a/cpukit/posix/src/keydelete.c +++ b/cpukit/posix/src/keydelete.c @@ -6,12 +6,12 @@ */ /* - * COPYRIGHT (c) 1989-2007. - * On-Line Applications Research Corporation (OAR). + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.com/license/LICENSE. + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. */ #if HAVE_CONFIG_H @@ -42,8 +42,6 @@ int pthread_key_delete( switch ( location ) { case OBJECTS_LOCAL: - _Objects_Close( &_POSIX_Keys_Information, &the_key->Object ); - _POSIX_Keys_Free_memory( the_key ); /* @@ -51,7 +49,7 @@ int pthread_key_delete( * of the application to free the memory. */ _POSIX_Keys_Free( the_key ); - _Objects_Put( &the_key->Object ); + _Objects_Put(&the_key->Object); return 0; #if defined(RTEMS_MULTIPROCESSING) diff --git a/cpukit/posix/src/keyfreememory.c b/cpukit/posix/src/keyfreememory.c index f71af4f327..c42616dcb0 100644 --- a/cpukit/posix/src/keyfreememory.c +++ b/cpukit/posix/src/keyfreememory.c @@ -1,17 +1,18 @@ /** * @file * - * @brief POSIX Function Keys Free Memory + * @brief POSIX Function Keys Free Memory * @ingroup POSIXAPI */ /* - * COPYRIGHT (c) 1989-2010. - * On-Line Applications Research Corporation (OAR). + * Copyright (c) 2012 Zhongwei Yao. + * COPYRIGHT (c) 1989-2010. + * On-Line Applications Research Corporation (OAR). * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.com/license/LICENSE. + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. */ #if HAVE_CONFIG_H @@ -21,14 +22,45 @@ #include <rtems/system.h> #include <rtems/score/thread.h> #include <rtems/score/wkspace.h> +#include <rtems/score/rbtree.h> #include <rtems/posix/key.h> void _POSIX_Keys_Free_memory( POSIX_Keys_Control *the_key ) { - uint32_t the_api; + POSIX_Keys_Key_value_pair search_node; + POSIX_Keys_Key_value_pair *p; + RBTree_Node *iter, *next; - for ( the_api = 1; the_api <= OBJECTS_APIS_LAST; the_api++ ) - _Workspace_Free( the_key->Values[ the_api ] ); + search_node.key = the_key->Object.id; + search_node.thread_id = 0; + iter = _RBTree_Find_unprotected( &_POSIX_Keys_Key_value_lookup_tree, &search_node.Key_value_lookup_node ); + if ( !iter ) + return; + /** + * find the smallest thread_id node in the rbtree. + */ + next = _RBTree_Next_unprotected( iter, RBT_LEFT ); + p = _RBTree_Container_of( next, POSIX_Keys_Key_value_pair, Key_value_lookup_node ); + while ( p->key == the_key->Object.id) { + iter = next; + next = _RBTree_Next_unprotected( iter, RBT_LEFT ); + p = _RBTree_Container_of( next, POSIX_Keys_Key_value_pair, Key_value_lookup_node ); + } + + /** + * delete all nodes belongs to the_key from the rbtree and chain. + */ + p = _RBTree_Container_of( iter, POSIX_Keys_Key_value_pair, Key_value_lookup_node ); + while ( p->key == the_key->Object.id ) { + next = _RBTree_Next_unprotected( iter, RBT_RIGHT ); + _RBTree_Extract_unprotected( &_POSIX_Keys_Key_value_lookup_tree, iter ); + _Chain_Extract_unprotected( &p->Key_values_per_thread_node ); + /* append the node to _POSIX_Keys_Keypool */ + _Freechain_Put( &_POSIX_Keys_Keypool.super_fc, + ( void * )p); + iter = next; + p = _RBTree_Container_of( iter, POSIX_Keys_Key_value_pair, Key_value_lookup_node ); + } } diff --git a/cpukit/posix/src/keygetspecific.c b/cpukit/posix/src/keygetspecific.c index 0e8bbcdec8..88e084ee96 100644 --- a/cpukit/posix/src/keygetspecific.c +++ b/cpukit/posix/src/keygetspecific.c @@ -6,12 +6,13 @@ */ /* - * COPYRIGHT (c) 1989-2007. - * On-Line Applications Research Corporation (OAR). + * Copyright (c) 2012 Zhongwei Yao. + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.com/license/LICENSE. + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. */ #if HAVE_CONFIG_H @@ -26,6 +27,7 @@ #include <rtems/system.h> #include <rtems/score/thread.h> #include <rtems/score/wkspace.h> +#include <rtems/score/rbtree.h> #include <rtems/posix/key.h> /* @@ -36,20 +38,31 @@ void *pthread_getspecific( pthread_key_t key ) { - register POSIX_Keys_Control *the_key; - uint32_t api; - uint32_t index; Objects_Locations location; + POSIX_Keys_Key_value_pair search_node; + RBTree_Node *p; void *key_data; + POSIX_Keys_Key_value_pair *value_pair_p; - the_key = _POSIX_Keys_Get( key, &location ); + _POSIX_Keys_Get( key, &location ); switch ( location ) { case OBJECTS_LOCAL: - api = _Objects_Get_API( _Thread_Executing->Object.id ); - index = _Objects_Get_index( _Thread_Executing->Object.id ); - key_data = (void *) the_key->Values[ api ][ index ]; - _Objects_Put( &the_key->Object ); + search_node.key = key; + search_node.thread_id = _Thread_Executing->Object.id; + p = _RBTree_Find_unprotected( &_POSIX_Keys_Key_value_lookup_tree, + &search_node.Key_value_lookup_node ); + key_data = NULL; + if ( p ) { + value_pair_p = _RBTree_Container_of( p, + POSIX_Keys_Key_value_pair, + Key_value_lookup_node ); + /* key_data = _RBTree_Container_of( p, */ + /* POSIX_Keys_Key_value_pair, */ + /* Key_value_lookup_node )->value; */ + key_data = value_pair_p->value; + } + _Thread_Enable_dispatch(); return key_data; #if defined(RTEMS_MULTIPROCESSING) diff --git a/cpukit/posix/src/keyrundestructors.c b/cpukit/posix/src/keyrundestructors.c index eb692e0dc9..7e3c88fdb6 100644 --- a/cpukit/posix/src/keyrundestructors.c +++ b/cpukit/posix/src/keyrundestructors.c @@ -6,14 +6,15 @@ */ /* - * Copyright (c) 2010 embedded brains GmbH. + * Copyright (c) 2012 Zhongwei Yao. + * Copyright (c) 2010 embedded brains GmbH. * - * COPYRIGHT (c) 1989-2007. - * On-Line Applications Research Corporation (OAR). + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.com/license/LICENSE. + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. */ #if HAVE_CONFIG_H @@ -22,7 +23,10 @@ #include <rtems/system.h> #include <rtems/score/thread.h> +#include <rtems/score/wkspace.h> +#include <rtems/score/chain.h> #include <rtems/posix/key.h> +#include <rtems/posix/threadsup.h> /* * _POSIX_Keys_Run_destructors @@ -32,41 +36,60 @@ * 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 ) { - Objects_Maximum thread_index = _Objects_Get_index( thread->Object.id ); - Objects_APIs thread_api = _Objects_Get_API( thread->Object.id ); - bool done = false; + Chain_Control *chain; + Chain_Node *iter, *next; + void *value; + void (*destructor) (void *); + POSIX_Keys_Control *the_key; + Objects_Locations location; - /* - * The standard allows one to avoid a potential infinite loop and limit the - * number of iterations. An infinite loop may happen if destructors set - * thread specific data. This can be considered dubious. - * - * Reference: 17.1.1.2 P1003.1c/Draft 10, p. 163, line 99. - */ - while ( !done ) { - Objects_Maximum index = 0; - Objects_Maximum max = _POSIX_Keys_Information.maximum; + _Thread_Disable_dispatch(); - done = true; + chain = &( + (POSIX_API_Control *)thread->API_Extensions[ THREAD_API_POSIX ] + )->Key_Chain; + iter = _Chain_First( chain ); + while ( !_Chain_Is_tail( chain, iter ) ) { + next = _Chain_Next( iter ); + /** + * remove key from rbtree and chain. + * here Chain_Node *iter can be convert to POSIX_Keys_Key_value_pair *, + * because Chain_Node is the first member of POSIX_Keys_Key_value_pair + * structure. + */ + _RBTree_Extract_unprotected( + &_POSIX_Keys_Key_value_lookup_tree, + &((POSIX_Keys_Key_value_pair *)iter)->Key_value_lookup_node + ); + _Chain_Extract_unprotected( iter ); - for ( index = 1 ; index <= max ; ++index ) { - POSIX_Keys_Control *key = (POSIX_Keys_Control *) - _POSIX_Keys_Information.local_table [ index ]; + /** + * run key value's destructor if destructor and value are both non-null. + */ + the_key = _POSIX_Keys_Get( + ((POSIX_Keys_Key_value_pair *)iter)->key, + &location + ); + destructor = the_key->destructor; + value = ((POSIX_Keys_Key_value_pair *)iter)->value; + if ( destructor != NULL && value != NULL ) + (*destructor)( value ); + /** + * disable dispatch is nested here + */ + _Thread_Enable_dispatch(); - if ( key != NULL && key->destructor != NULL ) { - void *value = key->Values [ thread_api ][ thread_index ]; + /** + * put back this node to keypool + */ + _Freechain_Put( &_POSIX_Keys_Keypool.super_fc, + (void *)iter ); - if ( value != NULL ) { - key->Values [ thread_api ][ thread_index ] = NULL; - (*key->destructor)( value ); - done = false; - } - } - } + iter = next; } + _Thread_Enable_dispatch(); } diff --git a/cpukit/posix/src/keysetspecific.c b/cpukit/posix/src/keysetspecific.c index 22eb8eb643..f527fe1ee4 100644 --- a/cpukit/posix/src/keysetspecific.c +++ b/cpukit/posix/src/keysetspecific.c @@ -6,12 +6,13 @@ */ /* - * COPYRIGHT (c) 1989-2007. - * On-Line Applications Research Corporation (OAR). + * Copyright (c) 2012 Zhongwei Yao. + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.com/license/LICENSE. + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. */ #if HAVE_CONFIG_H @@ -22,11 +23,14 @@ #include <limits.h> #include <pthread.h> #include <string.h> +#include <stddef.h> #include <rtems/system.h> #include <rtems/score/thread.h> #include <rtems/score/wkspace.h> +#include <rtems/score/rbtree.h> #include <rtems/posix/key.h> +#include <rtems/posix/threadsup.h> /* * 17.1.2 Thread-Specific Data Management, P1003.1c/Draft 10, p. 165 @@ -37,19 +41,38 @@ int pthread_setspecific( const void *value ) { - register POSIX_Keys_Control *the_key; - uint32_t api; - uint32_t index; Objects_Locations location; + POSIX_Keys_Key_value_pair *value_pair_ptr; + POSIX_API_Control *api; - the_key = _POSIX_Keys_Get( key, &location ); + _POSIX_Keys_Get( key, &location ); switch ( location ) { case OBJECTS_LOCAL: - api = _Objects_Get_API( _Thread_Executing->Object.id ); - index = _Objects_Get_index( _Thread_Executing->Object.id ); - the_key->Values[ api ][ index ] = (void *) value; - _Objects_Put( &the_key->Object ); + value_pair_ptr = ( POSIX_Keys_Key_value_pair * ) + _Freechain_Get( &_POSIX_Keys_Keypool.super_fc ); + if ( !value_pair_ptr ) { + _Thread_Enable_dispatch(); + return ENOMEM; + } + + value_pair_ptr->key = key; + value_pair_ptr->thread_id = _Thread_Executing->Object.id; + value_pair_ptr->value = value; + if ( _RBTree_Insert_unprotected( &_POSIX_Keys_Key_value_lookup_tree, + &(value_pair_ptr->Key_value_lookup_node) ) ) { + _Freechain_Put( (Freechain_Control *)&_POSIX_Keys_Keypool, + (void *) value_pair_ptr ); + _Thread_Enable_dispatch(); + return EAGAIN; + } + + /** append rb_node to the thread API extension's chain */ + api = (POSIX_API_Control *)\ + (_Thread_Executing->API_Extensions[THREAD_API_POSIX]); + _Chain_Append_unprotected( &api->Key_Chain, &value_pair_ptr->Key_values_per_thread_node ); + + _Thread_Enable_dispatch(); return 0; #if defined(RTEMS_MULTIPROCESSING) diff --git a/cpukit/posix/src/pthread.c b/cpukit/posix/src/pthread.c index 121b0874e7..13f7525c75 100644 --- a/cpukit/posix/src/pthread.c +++ b/cpukit/posix/src/pthread.c @@ -236,6 +236,9 @@ static bool _POSIX_Threads_Create_extension( created ); + /** initialize thread's key vaule node chain */ + _Chain_Initialize_empty( &api->Key_Chain ); + return true; } diff --git a/cpukit/sapi/include/confdefs.h b/cpukit/sapi/include/confdefs.h index ed1385a3c9..50db8779af 100644 --- a/cpukit/sapi/include/confdefs.h +++ b/cpukit/sapi/include/confdefs.h @@ -1728,11 +1728,17 @@ const rtems_libio_helper rtems_fs_init_helper = #ifndef CONFIGURE_MAXIMUM_POSIX_KEYS #define CONFIGURE_MAXIMUM_POSIX_KEYS 0 - #define CONFIGURE_MEMORY_FOR_POSIX_KEYS(_keys) 0 + #define CONFIGURE_MAXIMUM_POSIX_KEY_VALUE_PAIRS 0 + #define CONFIGURE_MEMORY_FOR_POSIX_KEYS(_keys, _key_value_pairs) 0 #else - #define CONFIGURE_MEMORY_FOR_POSIX_KEYS(_keys) \ + #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_MEMORY_FOR_POSIX_KEYS(_keys, _key_value_pairs) \ (_Configure_Object_RAM(_keys, sizeof(POSIX_Keys_Control) ) \ - + (_keys) * 3 * _Configure_From_workspace(sizeof(void *) * 2)) + + _Configure_From_workspace(_key_value_pairs * sizeof(POSIX_Keys_Key_value_pair))) #endif #ifndef CONFIGURE_MAXIMUM_POSIX_TIMERS @@ -1854,7 +1860,8 @@ const rtems_libio_helper rtems_fs_init_helper = CONFIGURE_MEMORY_FOR_POSIX_CONDITION_VARIABLES( \ CONFIGURE_MAXIMUM_POSIX_CONDITION_VARIABLES + \ CONFIGURE_MAXIMUM_GO_CHANNELS + CONFIGURE_GO_INIT_CONDITION_VARIABLES) + \ - CONFIGURE_MEMORY_FOR_POSIX_KEYS( CONFIGURE_MAXIMUM_POSIX_KEYS ) + \ + CONFIGURE_MEMORY_FOR_POSIX_KEYS( CONFIGURE_MAXIMUM_POSIX_KEYS, \ + CONFIGURE_MAXIMUM_POSIX_KEY_VALUE_PAIRS ) + \ CONFIGURE_MEMORY_FOR_POSIX_QUEUED_SIGNALS( \ CONFIGURE_MAXIMUM_POSIX_QUEUED_SIGNALS ) + \ CONFIGURE_MEMORY_FOR_POSIX_MESSAGE_QUEUES( \ @@ -2303,6 +2310,7 @@ const rtems_libio_helper rtems_fs_init_helper = CONFIGURE_MAXIMUM_ADA_TASKS + CONFIGURE_MAXIMUM_FAKE_ADA_TASKS + CONFIGURE_GO_INIT_CONDITION_VARIABLES + CONFIGURE_MAXIMUM_GO_CHANNELS, CONFIGURE_MAXIMUM_POSIX_KEYS, + CONFIGURE_MAXIMUM_POSIX_KEY_VALUE_PAIRS, CONFIGURE_MAXIMUM_POSIX_TIMERS, CONFIGURE_MAXIMUM_POSIX_QUEUED_SIGNALS, CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES, @@ -2545,7 +2553,8 @@ const rtems_libio_helper rtems_fs_init_helper = CONFIGURE_MEMORY_FOR_POSIX_CONDITION_VARIABLES( CONFIGURE_MAXIMUM_POSIX_CONDITION_VARIABLES + CONFIGURE_MAXIMUM_GO_CHANNELS + CONFIGURE_GO_INIT_CONDITION_VARIABLES), - CONFIGURE_MEMORY_FOR_POSIX_KEYS( CONFIGURE_MAXIMUM_POSIX_KEYS ), + CONFIGURE_MEMORY_FOR_POSIX_KEYS( CONFIGURE_MAXIMUM_POSIX_KEYS, \ + CONFIGURE_MAXIMUM_POSIX_KEY_VALUE_PAIRS ), CONFIGURE_MEMORY_FOR_POSIX_QUEUED_SIGNALS( CONFIGURE_MAXIMUM_POSIX_QUEUED_SIGNALS ), CONFIGURE_MEMORY_FOR_POSIX_MESSAGE_QUEUES( @@ -2616,6 +2625,7 @@ const rtems_libio_helper rtems_fs_init_helper = (CONFIGURE_MAXIMUM_POSIX_MUTEXES != 0) || \ (CONFIGURE_MAXIMUM_POSIX_CONDITION_VARIABLES != 0) || \ (CONFIGURE_MAXIMUM_POSIX_KEYS != 0) || \ + (CONFIGURE_MAXIMUM_POSIX_KEY_VALUE_PAIRS != 0) || \ (CONFIGURE_MAXIMUM_POSIX_TIMERS != 0) || \ (CONFIGURE_MAXIMUM_POSIX_QUEUED_SIGNALS != 0) || \ (CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES != 0) || \ @@ -2697,5 +2707,19 @@ const rtems_libio_helper rtems_fs_init_helper = #error "Fewer POSIX Message Queue descriptors than Queues!" #endif +/* + * POSIX Key pair shouldn't be less than POSIX Key, which is highly + * likely to be error. + */ +#if defined(RTEMS_POSIX_API) + #if (CONFIGURE_MAXIMUM_POSIX_KEYS != 0) && \ + (CONFIGURE_MAXIMUM_POSIX_KEY_VALUE_PAIRS != 0) + #if (CONFIGURE_MAXIMUM_POSIX_KEY_VALUE_PAIRS < \ + CONFIGURE_MAXIMUM_POSIX_KEYS) + #error "Fewer POSIX Key pairs than POSIX Key!" + #endif + #endif +#endif + #endif /* end of include file */ diff --git a/testsuites/psxtests/Makefile.am b/testsuites/psxtests/Makefile.am index 0e8a3e805b..423cf07043 100644 --- a/testsuites/psxtests/Makefile.am +++ b/testsuites/psxtests/Makefile.am @@ -7,7 +7,8 @@ SUBDIRS += psxhdrs psx01 psx02 psx03 psx04 psx05 psx06 psx07 psx08 psx09 \ psxaio01 psxaio02 psxaio03 \ psxalarm01 psxautoinit01 psxautoinit02 psxbarrier01 \ psxcancel psxcancel01 psxclassic01 psxcleanup psxcleanup01 \ - psxcond01 psxconfig01 psxenosys psxkey01 psxkey02 psxkey03 \ + psxcond01 psxconfig01 psxenosys psxkey01 psxkey02 psxkey03 psxkey04 \ + psxkey05 psxkey06 psxkey07 psxkey08 psxkey09 psxkey10 \ psxitimer psxmsgq01 psxmsgq02 psxmsgq03 psxmsgq04 \ psxmutexattr01 psxobj01 psxrwlock01 psxsem01 psxsignal01 psxsignal02 \ psxsignal03 psxsignal04 psxsignal05 psxsignal06 \ diff --git a/testsuites/psxtests/configure.ac b/testsuites/psxtests/configure.ac index a04fc5ec65..8e0a2384cd 100644 --- a/testsuites/psxtests/configure.ac +++ b/testsuites/psxtests/configure.ac @@ -122,6 +122,13 @@ psxitimer/Makefile psxkey01/Makefile psxkey02/Makefile psxkey03/Makefile +psxkey04/Makefile +psxkey05/Makefile +psxkey06/Makefile +psxkey07/Makefile +psxkey08/Makefile +psxkey09/Makefile +psxkey10/Makefile psxmount/Makefile psxmsgq01/Makefile psxmsgq02/Makefile diff --git a/testsuites/psxtests/psxkey01/init.c b/testsuites/psxtests/psxkey01/init.c index 3383c8da3c..e63407cda8 100644 --- a/testsuites/psxtests/psxkey01/init.c +++ b/testsuites/psxtests/psxkey01/init.c @@ -43,10 +43,10 @@ void *POSIX_Init( rtems_workspace_greedy_allocate( NULL, 0 ); - puts("Init: pthread_key_create - ENOMEM (Workspace not available)"); + puts("Init: pthread_key_create - OK"); empty_line(); status = pthread_key_create( &Key_id[0], Key_destructor ); - fatal_directive_check_status_only( status, ENOMEM, "no workspace available" ); + fatal_directive_check_status_only( status, 0, "OK" ); puts( "*** END OF POSIX KEY 01 TEST ***" ); rtems_test_exit( 0 ); diff --git a/testsuites/psxtests/psxkey01/psxkey01.scn b/testsuites/psxtests/psxkey01/psxkey01.scn index 597b0f8e23..e1a747c8ab 100644 --- a/testsuites/psxtests/psxkey01/psxkey01.scn +++ b/testsuites/psxtests/psxkey01/psxkey01.scn @@ -1,5 +1,5 @@ *** POSIX KEY 01 TEST *** Init's ID is 0x0b010001 -Allocate_majority_of_workspace: -Init: pthread_key_create - ENOMEM (Workspace not available) +Init: pthread_key_create - OK + *** END OF POSIX KEY 01 TEST *** diff --git a/testsuites/psxtests/psxkey04/Makefile.am b/testsuites/psxtests/psxkey04/Makefile.am new file mode 100644 index 0000000000..cd5f2bb8c1 --- /dev/null +++ b/testsuites/psxtests/psxkey04/Makefile.am @@ -0,0 +1,23 @@ + +rtems_tests_PROGRAMS = psxkey04 +psxkey04_SOURCES = init.c + +dist_rtems_tests_DATA = psxkey04.scn +dist_rtems_tests_DATA += psxkey04.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)/include +AM_CPPFLAGS += -I$(top_srcdir)/../support/include + +LINK_OBJS = $(psxkey04_OBJECTS) +LINK_LIBS = $(psxkey04_LDLIBS) + +psxkey04$(EXEEXT): $(psxkey04_OBJECTS) $(psxkey04_DEPENDENCIES) + @rm -f psxkey04$(EXEEXT) + $(make-exe) + +include $(top_srcdir)/../automake/local.am diff --git a/testsuites/psxtests/psxkey04/init.c b/testsuites/psxtests/psxkey04/init.c new file mode 100644 index 0000000000..76540dd76f --- /dev/null +++ b/testsuites/psxtests/psxkey04/init.c @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2012 Zhongwei Yao. + * COPYRIGHT (c) 1989-2012. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> +#include "tmacros.h" +#include "pmacros.h" + +/* forward declarations to avoid warnings */ +void *POSIX_Init(void *argument); +void *Test_Thread1(void *argument); +void *Test_Thread2(void *argument); + +int Data_array[2] = {1, 2}; +pthread_t thread1, thread2; + +pthread_key_t Key; + +void *Test_Thread1( + void *argument +) +{ + int sc; + int *value; + struct timespec delay_request; + /* + * Detach ourselves so we don't wait for a join that won't happen. + */ + pthread_detach( pthread_self() ); + + puts( "Test_Thread 1 - pthread_setspecific - OK" ); + sc = pthread_setspecific( Key, &Data_array[0] ); + rtems_test_assert( !sc ); + + puts( "Test_Thread 1 - sleep - let thread 2 run - OK" ); + delay_request.tv_sec = 0; + delay_request.tv_nsec = 4 * 100000000; + sc = nanosleep( &delay_request, NULL ); + rtems_test_assert( !sc ); + + puts( "Test_Thread 1 - pthread_getspecific - OK" ); + value = pthread_getspecific( Key ); + rtems_test_assert( *value == Data_array[0] ); + + return NULL; +} + +void *Test_Thread2( + void *argument +) +{ + int sc; + int *value; + /* + * Detach ourselves so we don't wait for a join that won't happen. + */ + pthread_detach( pthread_self() ); + + puts( "Test_Thread 2 - pthread_setspecific - OK" ); + sc = pthread_setspecific( Key, &Data_array[1] ); + rtems_test_assert( !sc ); + + puts( "Test_Thread 2 - pthread_getspecific - OK" ); + value = pthread_getspecific( Key ); + rtems_test_assert( *value == Data_array[1] ); + + return NULL; +} + +void *POSIX_Init( + void *ignored +) +{ + int sc; + struct timespec delay_request; + + puts( "\n\n*** TEST KEY 04 ***" ); + + puts( "Init - pthread_key_create - OK" ); + sc = pthread_key_create( &Key, NULL ); + rtems_test_assert( !sc ); + + puts( "Init - pthread_create - OK" ); + sc = pthread_create( &thread1, NULL, Test_Thread1, NULL ); + rtems_test_assert( !sc ); + + sc = pthread_create( &thread2, NULL, Test_Thread2, NULL ); + rtems_test_assert( !sc ); + + puts( "Init - sleep - let thread run - OK" ); + delay_request.tv_sec = 0; + delay_request.tv_nsec = 8 * 100000000; + sc = nanosleep( &delay_request, NULL ); + rtems_test_assert( !sc ); + + puts( "Init - pthread_key_delete - OK" ); + sc = pthread_key_delete( Key ); + rtems_test_assert( sc == 0 ); + + puts( "*** END OF TEST KEY 04 ***" ); + rtems_test_exit(0); +} + +/* configuration information */ + +#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER +#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER + +#define CONFIGURE_MAXIMUM_POSIX_THREADS 3 +#define CONFIGURE_MAXIMUM_POSIX_KEYS 1 + +#define CONFIGURE_POSIX_INIT_THREAD_TABLE + +#define CONFIGURE_INIT +#include <rtems/confdefs.h> + +/* global variables */ diff --git a/testsuites/psxtests/psxkey04/psxkey04.doc b/testsuites/psxtests/psxkey04/psxkey04.doc new file mode 100644 index 0000000000..6438d4e501 --- /dev/null +++ b/testsuites/psxtests/psxkey04/psxkey04.doc @@ -0,0 +1,22 @@ +# COPYRIGHT (c) 1989-2009. +# On-Line Applications Research Corporation (OAR). +# +# The license and distribution terms for this file may be +# found in the file LICENSE in this distribution or at +# http://www.rtems.com/license/LICENSE. +# + +This file describes the directives and concepts tested by this test set. + +test set name: psxkey04 + +directives: + + pthread_key_create + pthread_setspecific + pthread_getspecific + pthread_key_delete + +concepts: + ++ Ensure that key data's operation(set and get) under multithreads work. diff --git a/testsuites/psxtests/psxkey04/psxkey04.scn b/testsuites/psxtests/psxkey04/psxkey04.scn new file mode 100644 index 0000000000..aa0500fcba --- /dev/null +++ b/testsuites/psxtests/psxkey04/psxkey04.scn @@ -0,0 +1,11 @@ +*** TEST KEY 04 *** +Init - pthread_key_create - OK +Init - pthread_create - OK +Init - sleep - let thread run - OK +Test_Thread 1 - pthread_setspecific - OK +Test_Thread 1 - sleep - let thread 2 run - OK +Test_Thread 2 - pthread_setspecific - OK +Test_Thread 2 - pthread_getspecific - OK +Test_Thread 1 - pthread_getspecific - OK +Init - pthread_key_delete - OK +*** END OF TEST KEY 04 *** diff --git a/testsuites/psxtests/psxkey05/Makefile.am b/testsuites/psxtests/psxkey05/Makefile.am new file mode 100644 index 0000000000..c253900c06 --- /dev/null +++ b/testsuites/psxtests/psxkey05/Makefile.am @@ -0,0 +1,23 @@ + +rtems_tests_PROGRAMS = psxkey05 +psxkey05_SOURCES = init.c + +dist_rtems_tests_DATA = psxkey05.scn +dist_rtems_tests_DATA += psxkey05.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)/include +AM_CPPFLAGS += -I$(top_srcdir)/../support/include + +LINK_OBJS = $(psxkey05_OBJECTS) +LINK_LIBS = $(psxkey05_LDLIBS) + +psxkey05$(EXEEXT): $(psxkey05_OBJECTS) $(psxkey05_DEPENDENCIES) + @rm -f psxkey05$(EXEEXT) + $(make-exe) + +include $(top_srcdir)/../automake/local.am diff --git a/testsuites/psxtests/psxkey05/init.c b/testsuites/psxtests/psxkey05/init.c new file mode 100644 index 0000000000..08d22b0cbd --- /dev/null +++ b/testsuites/psxtests/psxkey05/init.c @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2012 Zhongwei Yao. + * COPYRIGHT (c) 1989-2012. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> +#include "tmacros.h" +#include "pmacros.h" + +/* forward declarations to avoid warnings */ +void *POSIX_Init(void *argument); + +void *POSIX_Init( + void *ignored +) +{ + pthread_key_t key1, key2; + int sc, *value; + int Data_array[2] = {1, 2}; + + puts( "\n\n*** TEST KEY 05 ***" ); + + puts( "Init - pthread key1 create - OK" ); + sc = pthread_key_create( &key1, NULL ); + rtems_test_assert( !sc ); + + puts( "Init - pthread key2 create - OK" ); + sc = pthread_key_create( &key2, NULL ); + rtems_test_assert( !sc ); + + puts( "Init - key1 pthread_setspecific - OK" ); + sc = pthread_setspecific( key1, &Data_array[0] ); + rtems_test_assert( !sc ); + + puts( "Init - key2 pthread_setspecific - OK" ); + sc = pthread_setspecific( key2, &Data_array[1] ); + rtems_test_assert( !sc ); + + puts( "Init - key1 pthread_getspecific - OK" ); + value = pthread_getspecific( key1 ); + rtems_test_assert( *value == Data_array[0] ); + + puts( "Init - key2 pthread_getspecific - OK" ); + value = pthread_getspecific( key2 ); + rtems_test_assert( *value == Data_array[1] ); + + puts( "Init - pthread key1 delete - OK" ); + sc = pthread_key_delete( key1 ); + rtems_test_assert( sc == 0 ); + + puts( "Init - pthread key2 delete - OK" ); + sc = pthread_key_delete( key2 ); + rtems_test_assert( sc == 0 ); + + puts( "*** END OF TEST KEY 05 ***" ); + rtems_test_exit(0); +} + +/* configuration information */ + +#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER +#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER + +#define CONFIGURE_MAXIMUM_POSIX_THREADS 1 +#define CONFIGURE_MAXIMUM_POSIX_KEYS 2 + +#define CONFIGURE_POSIX_INIT_THREAD_TABLE + +#define CONFIGURE_INIT +#include <rtems/confdefs.h> + +/* global variables */ diff --git a/testsuites/psxtests/psxkey05/psxkey05.doc b/testsuites/psxtests/psxkey05/psxkey05.doc new file mode 100644 index 0000000000..f4359d64c7 --- /dev/null +++ b/testsuites/psxtests/psxkey05/psxkey05.doc @@ -0,0 +1,22 @@ +# COPYRIGHT (c) 1989-2009. +# On-Line Applications Research Corporation (OAR). +# +# The license and distribution terms for this file may be +# found in the file LICENSE in this distribution or at +# http://www.rtems.com/license/LICENSE. +# + +This file describes the directives and concepts tested by this test set. + +test set name: psxkey05 + +directives: + + pthread_key_create + pthread_setspecific + pthread_getspecific + pthread_key_delete + +concepts: + ++ Ensure that key data's operation(create, set, get and delete) under multikeys work. diff --git a/testsuites/psxtests/psxkey05/psxkey05.scn b/testsuites/psxtests/psxkey05/psxkey05.scn new file mode 100644 index 0000000000..f352a36785 --- /dev/null +++ b/testsuites/psxtests/psxkey05/psxkey05.scn @@ -0,0 +1,10 @@ +*** TEST KEY 05 *** +Init - pthread key1 create - OK +Init - pthread key2 create - OK +Init - key1 pthread_setspecific - OK +Init - key1 pthread_getspecific - OK +Init - key2 pthread_setspecific - OK +Init - key2 pthread_getspecific - OK +Init - pthread key1 delete - OK +Init - pthread key2 delete - OK +*** END OF TEST KEY 05 ***
\ No newline at end of file diff --git a/testsuites/psxtests/psxkey06/Makefile.am b/testsuites/psxtests/psxkey06/Makefile.am new file mode 100644 index 0000000000..9815baf4eb --- /dev/null +++ b/testsuites/psxtests/psxkey06/Makefile.am @@ -0,0 +1,23 @@ + +rtems_tests_PROGRAMS = psxkey06 +psxkey06_SOURCES = init.c + +dist_rtems_tests_DATA = psxkey06.scn +dist_rtems_tests_DATA += psxkey06.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)/include +AM_CPPFLAGS += -I$(top_srcdir)/../support/include + +LINK_OBJS = $(psxkey06_OBJECTS) +LINK_LIBS = $(psxkey06_LDLIBS) + +psxkey06$(EXEEXT): $(psxkey06_OBJECTS) $(psxkey06_DEPENDENCIES) + @rm -f psxkey06$(EXEEXT) + $(make-exe) + +include $(top_srcdir)/../automake/local.am diff --git a/testsuites/psxtests/psxkey06/init.c b/testsuites/psxtests/psxkey06/init.c new file mode 100644 index 0000000000..98b46a42be --- /dev/null +++ b/testsuites/psxtests/psxkey06/init.c @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2012 Zhongwei Yao. + * COPYRIGHT (c) 1989-2012. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> +#include "tmacros.h" +#include "pmacros.h" + +/* forward declarations to avoid warnings */ +void *POSIX_Init(void *argument); +void *Test_Thread1(void *argument); +void *Test_Thread2(void *argument); + +int Data_array[4] = {1, 2, 3, 4}; + +pthread_key_t key1, key2; + +void *Test_Thread1( + void *argument +) +{ + int sc; + int *value; + struct timespec delay_request; + /* + * Detach ourselves so we don't wait for a join that won't happen. + */ + pthread_detach( pthread_self() ); + + puts( "Test_Thread 1 - key1 pthread_setspecific - OK" ); + sc = pthread_setspecific( key1, &Data_array[0] ); + rtems_test_assert( !sc ); + + puts( "Test_Thread 1 - key2 pthread_setspecific - OK" ); + sc = pthread_setspecific( key2, &Data_array[1] ); + rtems_test_assert( !sc ); + + puts( "Test_Thread 1 - sleep - let thread2 run - OK" ); + delay_request.tv_sec = 0; + delay_request.tv_nsec = 4 * 100000000; + sc = nanosleep( &delay_request, NULL ); + rtems_test_assert( !sc ); + + puts( "Test_Thread 1 - key1 pthread_getspecific - OK" ); + value = pthread_getspecific( key1 ); + rtems_test_assert( *value == Data_array[0] ); + + puts( "Test_Thread 1 - key2 pthread_getspecific - OK" ); + value = pthread_getspecific( key2 ); + rtems_test_assert( *value == Data_array[1] ); + + return NULL; +} + +void *Test_Thread2( + void *argument +) +{ + int sc; + int *value; + /* + * Detach ourselves so we don't wait for a join that won't happen. + */ + pthread_detach( pthread_self() ); + + puts( "Test_Thread 2 - key1 pthread_setspecific - OK" ); + sc = pthread_setspecific( key1, &Data_array[2] ); + rtems_test_assert( !sc ); + + puts( "Test_Thread 2 - key2 pthread_setspecific - OK" ); + sc = pthread_setspecific( key2, &Data_array[3] ); + rtems_test_assert( !sc ); + + puts( "Test_Thread 2 - key1 pthread_getspecific - OK" ); + value = pthread_getspecific( key1 ); + rtems_test_assert( *value == Data_array[2] ); + + puts( "Test_Thread 2 - key2 pthread_getspecific - OK" ); + value = pthread_getspecific( key2 ); + rtems_test_assert( *value == Data_array[3] ); + + return NULL; +} + +void *POSIX_Init( + void *ignored +) +{ + pthread_t thread1, thread2; + int sc; + struct timespec delay_request; + + puts( "\n\n*** TEST KEY 06 ***" ); + + puts( "Init - pthread key1 create - OK" ); + sc = pthread_key_create( &key1, NULL ); + rtems_test_assert( !sc ); + + puts( "Init - pthread key2 create - OK" ); + sc = pthread_key_create( &key2, NULL ); + rtems_test_assert( !sc ); + + puts( "Init - pthread1 create - OK" ); + sc = pthread_create( &thread1, NULL, Test_Thread1, NULL ); + rtems_test_assert( !sc ); + + puts( "Init - pthread2 create - OK" ); + sc = pthread_create( &thread2, NULL, Test_Thread2, NULL ); + rtems_test_assert( !sc ); + + puts( "Init - sleep - let thread run - OK" ); + delay_request.tv_sec = 0; + delay_request.tv_nsec = 8 * 100000000; + sc = nanosleep( &delay_request, NULL ); + rtems_test_assert( !sc ); + + puts( "Init - pthread key1 delete - OK" ); + sc = pthread_key_delete( key1 ); + rtems_test_assert( sc == 0 ); + + puts( "Init - pthread key2 delete - OK" ); + sc = pthread_key_delete( key2 ); + rtems_test_assert( sc == 0 ); + + puts( "*** END OF TEST KEY 06 ***" ); + rtems_test_exit(0); +} + +/* configuration information */ + +#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER +#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER + +#define CONFIGURE_MAXIMUM_POSIX_THREADS 3 +#define CONFIGURE_MAXIMUM_POSIX_KEYS 2 + +#define CONFIGURE_POSIX_INIT_THREAD_TABLE + +#define CONFIGURE_INIT +#include <rtems/confdefs.h> + +/* global variables */ diff --git a/testsuites/psxtests/psxkey06/psxkey06.doc b/testsuites/psxtests/psxkey06/psxkey06.doc new file mode 100644 index 0000000000..6becdb9e66 --- /dev/null +++ b/testsuites/psxtests/psxkey06/psxkey06.doc @@ -0,0 +1,23 @@ +# COPYRIGHT (c) 1989-2009. +# On-Line Applications Research Corporation (OAR). +# +# The license and distribution terms for this file may be +# found in the file LICENSE in this distribution or at +# http://www.rtems.com/license/LICENSE. +# + +This file describes the directives and concepts tested by this test set. + +test set name: psxkey06 + +directives: + + pthread_key_create + pthread_setspecific + pthread_getspecific + pthread_key_delete + +concepts: + ++ Ensure that key data's operation(create, set, get and delete) under + multikeys and multi threads work. diff --git a/testsuites/psxtests/psxkey06/psxkey06.scn b/testsuites/psxtests/psxkey06/psxkey06.scn new file mode 100644 index 0000000000..a105b6fd8f --- /dev/null +++ b/testsuites/psxtests/psxkey06/psxkey06.scn @@ -0,0 +1,18 @@ +*** TEST KEY 06 *** +Init - pthread key1 create - OK +Init - pthread key2 create - OK +Init - pthread1 create - OK +Init - pthread2 create - OK +Init - sleep - let thread run - OK +Test_Thread 1 - key1 pthread_setspecific - OK +Test_Thread 1 - key2 pthread_setspecific - OK +Test_Thread 1 - sleep - let thread2 run - OK +Test_Thread 2 - key1 pthread_setspecific - OK +Test_Thread 2 - key2 pthread_setspecific - OK +Test_Thread 2 - key1 pthread_getspecific - OK +Test_Thread 2 - key2 pthread_getspecific - OK +Test_Thread 1 - key1 pthread_getspecific - OK +Test_Thread 1 - key2 pthread_getspecific - OK +Init - pthread key1 delete - OK +Init - pthread key2 delete - OK +*** END OF TEST KEY 06 *** diff --git a/testsuites/psxtests/psxkey07/Makefile.am b/testsuites/psxtests/psxkey07/Makefile.am new file mode 100644 index 0000000000..a701f309b2 --- /dev/null +++ b/testsuites/psxtests/psxkey07/Makefile.am @@ -0,0 +1,23 @@ + +rtems_tests_PROGRAMS = psxkey07 +psxkey07_SOURCES = init.c + +dist_rtems_tests_DATA = psxkey07.scn +dist_rtems_tests_DATA += psxkey07.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)/include +AM_CPPFLAGS += -I$(top_srcdir)/../support/include + +LINK_OBJS = $(psxkey07_OBJECTS) +LINK_LIBS = $(psxkey07_LDLIBS) + +psxkey07$(EXEEXT): $(psxkey07_OBJECTS) $(psxkey07_DEPENDENCIES) + @rm -f psxkey07$(EXEEXT) + $(make-exe) + +include $(top_srcdir)/../automake/local.am diff --git a/testsuites/psxtests/psxkey07/init.c b/testsuites/psxtests/psxkey07/init.c new file mode 100644 index 0000000000..e911dc77d9 --- /dev/null +++ b/testsuites/psxtests/psxkey07/init.c @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2012 Zhongwei Yao. + * COPYRIGHT (c) 1989-2012. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <sched.h> +#include <errno.h> +#include "tmacros.h" +#include "pmacros.h" + +/* forward declarations to avoid warnings */ +void *POSIX_Init(void *argument); +void *Test_Thread(void *argument); + +pthread_key_t Key; +int created_thread_count, setted_thread_count, got_thread_count; +int all_thread_created; +pthread_mutex_t mutex1, mutex2; +pthread_cond_t create_condition_var, set_condition_var; + +void *Test_Thread( + void *argument +) +{ + int sc; + int *value_p, *value_p2; + + value_p = malloc( sizeof( int ) ); + //printf( "Test_Thread%d - Key pthread_setspecific - OK\n", (int)pthread_self() ); + sc = pthread_setspecific( Key, value_p ); + rtems_test_assert( !sc ); + pthread_mutex_lock( &mutex1 ); + ++setted_thread_count; + pthread_cond_signal( &set_condition_var ); + pthread_mutex_unlock( &mutex1 ); + + /** + * blocked untill all threads have been created. + */ + pthread_mutex_lock( &mutex2 ); + while( !all_thread_created ) + pthread_cond_wait( &create_condition_var, &mutex2 ); + pthread_mutex_unlock( &mutex2 ); + + //printf( "Test_Thread%d - Key pthread_getspecific - OK\n", (int)pthread_self() ); + value_p2 = pthread_getspecific( Key ); + rtems_test_assert( value_p == value_p2 ); + ++got_thread_count; + + return NULL; +} + +void *POSIX_Init( + void *ignored +) +{ + pthread_t *thread_p; + int sc; + struct timespec delay_request; + all_thread_created = 0; + + puts( "\n\n*** TEST KEY 07 ***" ); + + puts( "Init - Mutex 1 create - OK" ); + sc = pthread_mutex_init( &mutex1, NULL ); + rtems_test_assert( !sc ); + puts( "Init - Mutex 2 create - OK" ); + sc = pthread_mutex_init( &mutex2, NULL ); + rtems_test_assert( !sc ); + puts( "Init - Condition variable 1 create - OK" ); + sc = pthread_cond_init( &create_condition_var, NULL ); + rtems_test_assert( !sc ); + puts( "Init - Condition variable 2 create - OK" ); + sc = pthread_cond_init( &set_condition_var, NULL ); + rtems_test_assert( !sc ); + + puts( "Init - pthread Key create - OK" ); + sc = pthread_key_create( &Key, NULL ); + rtems_test_assert( !sc ); + + for( ; ; ) + { + thread_p = malloc( sizeof( pthread_t ) ); + rtems_test_assert( thread_p ); + pthread_mutex_lock( &mutex1 ); + sc = pthread_create( thread_p, NULL, Test_Thread, NULL ); + rtems_test_assert( ( sc == 0 ) || ( sc == EAGAIN ) ); + /** + * check if return is EAGAIN, it means RTEMS Workspace RAM + * have been exhausted. + */ + if ( sc == EAGAIN ) + { + pthread_mutex_unlock( &mutex1 ); + break; + } + ++created_thread_count; + /** + * wait for test thread set key, the while loop here is used to + * avoid suprious wakeup. + */ + while( created_thread_count > setted_thread_count ) + pthread_cond_wait( &set_condition_var, &mutex1 ); + pthread_mutex_unlock( &mutex1 ); + } + printf( "Init - %d pthreads have been created - OK\n", created_thread_count ); + printf( "Init - %d pthreads have been setted key data - OK\n", setted_thread_count ); + rtems_test_assert( created_thread_count == setted_thread_count ); + /* unblock all created pthread to let them set key data.*/ + pthread_mutex_lock( &mutex2 ); + all_thread_created = 1; + pthread_cond_broadcast( &create_condition_var ); + pthread_mutex_unlock( &mutex2 ); + + puts( "Init - sleep - let threads run - OK" ); + delay_request.tv_sec = 0; + delay_request.tv_nsec = 8 * 100000000; + sc = nanosleep( &delay_request, NULL ); + rtems_test_assert( !sc ); + + printf( "Init - %d pthreads have been got key data - OK\n", got_thread_count ); + rtems_test_assert( created_thread_count == got_thread_count ); + puts( "Init - pthread Key delete - OK" ); + sc = pthread_key_delete( Key ); + rtems_test_assert( sc == 0 ); + + puts( "Init - Mutex1 delete - OK" ); + sc = pthread_mutex_destroy( &mutex1 ); + rtems_test_assert( !sc ); + puts( "Init - Mutex2 delete - OK" ); + sc = pthread_mutex_destroy( &mutex2 ); + rtems_test_assert( !sc ); + puts( "Init - Condition variable 1 delete - OK" ); + sc = pthread_cond_destroy( &create_condition_var ); + rtems_test_assert( !sc ); + puts( "Init - Condition variable 2 delete - OK" ); + sc = pthread_cond_destroy( &set_condition_var ); + rtems_test_assert( !sc ); + + puts( "*** END OF TEST KEY 07 ***" ); + rtems_test_exit(0); +} + +/* configuration information */ + +#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER +#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER + + +#define CONFIGURE_MAXIMUM_POSIX_THREADS rtems_resource_unlimited(10) +#define CONFIGURE_MAXIMUM_POSIX_MUTEXES 2 +#define CONFIGURE_MAXIMUM_POSIX_KEYS 1 +#define CONFIGURE_MAXIMUM_POSIX_CONDITION_VARIABLES 2 +#define CONFIGURE_UNIFIED_WORK_AREAS + + + +#define CONFIGURE_POSIX_INIT_THREAD_TABLE + +#define CONFIGURE_INIT +#include <rtems/confdefs.h> + +/* global variables */ diff --git a/testsuites/psxtests/psxkey07/psxkey07.doc b/testsuites/psxtests/psxkey07/psxkey07.doc new file mode 100644 index 0000000000..16d93de78c --- /dev/null +++ b/testsuites/psxtests/psxkey07/psxkey07.doc @@ -0,0 +1,26 @@ +# COPYRIGHT (c) 1989-2009. +# On-Line Applications Research Corporation (OAR). +# +# The license and distribution terms for this file may be +# found in the file LICENSE in this distribution or at +# http://www.rtems.com/license/LICENSE. +# + +This file describes the directives and concepts tested by this test set. + +test set name: psxkey07 + +directives: + + pthread_key_create + pthread_setspecific + pthread_getspecific + pthread_key_delete + +concepts: + ++ Ensure that key data's operation(create, set, get and delete) under unlimited configuration in POSIX API. ++ this test workflow is: + 1. create thread and set thread's key data one by one until exhausting workspace RAM + 2. when step 1 finished, let all thread created thread run the getspecific function to +test if key set and get works correctly. diff --git a/testsuites/psxtests/psxkey07/psxkey07.scn b/testsuites/psxtests/psxkey07/psxkey07.scn new file mode 100644 index 0000000000..851876fce1 --- /dev/null +++ b/testsuites/psxtests/psxkey07/psxkey07.scn @@ -0,0 +1,18 @@ + + +*** TEST KEY 07 *** +Init - Mutex 1 create - OK +Init - Mutex 2 create - OK +Init - Condition variable 1 create - OK +Init - Condition variable 2 create - OK +Init - pthread Key create - OK +Init - 380 pthreads have been created - OK +Init - 380 pthreads have been setted key data - OK +Init - sleep - let threads run - OK +Init - 380 pthreads have been got key data - OK +Init - pthread Key delete - OK +Init - Mutex1 delete - OK +Init - Mutex2 delete - OK +Init - Condition variable 1 delete - OK +Init - Condition variable 2 delete - OK +*** END OF TEST KEY 07 *** diff --git a/testsuites/psxtests/psxkey08/Makefile.am b/testsuites/psxtests/psxkey08/Makefile.am new file mode 100644 index 0000000000..e5bf7873ee --- /dev/null +++ b/testsuites/psxtests/psxkey08/Makefile.am @@ -0,0 +1,23 @@ + +rtems_tests_PROGRAMS = psxkey08 +psxkey08_SOURCES = init.c + +dist_rtems_tests_DATA = psxkey08.scn +dist_rtems_tests_DATA += psxkey08.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)/include +AM_CPPFLAGS += -I$(top_srcdir)/../support/include + +LINK_OBJS = $(psxkey08_OBJECTS) +LINK_LIBS = $(psxkey08_LDLIBS) + +psxkey08$(EXEEXT): $(psxkey08_OBJECTS) $(psxkey08_DEPENDENCIES) + @rm -f psxkey08$(EXEEXT) + $(make-exe) + +include $(top_srcdir)/../automake/local.am diff --git a/testsuites/psxtests/psxkey08/init.c b/testsuites/psxtests/psxkey08/init.c new file mode 100644 index 0000000000..81f4378828 --- /dev/null +++ b/testsuites/psxtests/psxkey08/init.c @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2012 Zhongwei Yao. + * COPYRIGHT (c) 1989-2012. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "tmacros.h" + +#include <stdio.h> +#include <rtems.h> +#include <pthread.h> +#include <unistd.h> +#include <errno.h> + +pthread_key_t Key; +int created_task_count, setted_task_count, got_task_count; +int all_thread_created; +rtems_id sema1, sema2; +rtems_name name1, name2; + +/* forward declarations to avoid warnings */ +rtems_task Init(rtems_task_argument arg); +rtems_task test_task(rtems_task_argument arg); + +rtems_task test_task(rtems_task_argument arg) +{ + int sc; + int *value_p, *value_p2; + + value_p = malloc( sizeof( int ) ); + //printf( "Test_Task%d - Key pthread_setspecific - OK\n", (int)rtems_task_self() ); + sc = pthread_setspecific( Key, value_p ); + rtems_test_assert( !sc ); + ++setted_task_count; + sc = rtems_semaphore_release( sema1 ); + + /** + * blocked untill all tasks have been created. + */ + rtems_semaphore_obtain( sema2 , RTEMS_WAIT, 0 ); + + //printf( "Test_Task%d - Key pthread_getspecific - OK\n", (int)rtems_task_self() ); + value_p2 = pthread_getspecific( Key ); + rtems_test_assert( value_p == value_p2 ); + ++got_task_count; + + pthread_exit( 0 ); +} + +rtems_task Init(rtems_task_argument arg) +{ + rtems_status_code status; + int sc; + rtems_id *task_id_p; + + all_thread_created = 0; + + puts( "\n\n*** TEST KEY 08 ***" ); + + puts( "Init - Semaphore 1 create - OK" ); + name1 = rtems_build_name('S', 'E', 'M', '1'); + sc = rtems_semaphore_create( name1, 0, + RTEMS_SIMPLE_BINARY_SEMAPHORE | + RTEMS_FIFO, + 0, &sema1 ); + rtems_test_assert( sc == RTEMS_SUCCESSFUL ); + + puts( "Init - Semaphore 2 create - OK" ); + name2 = rtems_build_name('S', 'E', 'M', '2'); + sc = rtems_semaphore_create( name2, 0, + RTEMS_SIMPLE_BINARY_SEMAPHORE | + RTEMS_FIFO, + 0, &sema2 ); + rtems_test_assert( sc == RTEMS_SUCCESSFUL ); + + puts( "Init - pthread Key create - OK" ); + sc = pthread_key_create( &Key, NULL ); + rtems_test_assert( !sc ); + + for( ; ; ) + { + task_id_p = malloc( sizeof( rtems_id ) ); + rtems_test_assert( task_id_p ); + sc = rtems_task_create( + rtems_build_name('T','A',created_task_count, ' '), + 1, + RTEMS_MINIMUM_STACK_SIZE, + RTEMS_DEFAULT_MODES, + RTEMS_DEFAULT_ATTRIBUTES, + task_id_p + ); + rtems_test_assert( (sc == RTEMS_UNSATISFIED) || (sc == RTEMS_TOO_MANY) || (sc == RTEMS_SUCCESSFUL) ); + /** + * when return is RTEMS_TOO_MANY or RTEMS_UNSATISFIED, there is not + * enough source to create task. + */ + if ( (sc == RTEMS_TOO_MANY) || (sc == RTEMS_UNSATISFIED) ) + { + break; + } + ++created_task_count; + sc = rtems_task_start( *task_id_p, test_task, 0 ); + rtems_test_assert( sc == RTEMS_SUCCESSFUL ); + sc = rtems_semaphore_obtain( sema1, RTEMS_WAIT, 0 ); + rtems_test_assert( sc == RTEMS_SUCCESSFUL ); + } + + printf( "Init - %d tasks have been created - OK\n", created_task_count ); + printf( "Init - %d tasks have been setted key data - OK\n", setted_task_count ); + rtems_test_assert( created_task_count == setted_task_count ); + + /* unblock all created tasks to let them set key data.*/ + puts( "Init - flush semaphore 2 - OK" ); + sc = rtems_semaphore_flush( sema2 ); + rtems_test_assert( sc == RTEMS_SUCCESSFUL ); + + puts( "Init - sleep to yield processor - OK" ); + status = rtems_task_wake_after( RTEMS_YIELD_PROCESSOR ); + directive_failed( status, "rtems_task_wake_after" ); + + printf( "Init - %d Tasks have been got key data - OK\n", got_task_count ); + rtems_test_assert( created_task_count == got_task_count ); + puts( "Init - pthread Key delete - OK" ); + sc = pthread_key_delete( Key ); + rtems_test_assert( sc == 0 ); + + puts( "Init - semaphore 1 delete - OK" ); + sc = rtems_semaphore_delete( sema1 ); + rtems_test_assert( !sc ); + + puts( "Init - semaphore 2 delete - OK" ); + sc = rtems_semaphore_delete( sema2 ); + rtems_test_assert( !sc ); + + puts( "*** END OF TEST KEY 08***" ); + exit(0); +} + +/* configuration information */ +#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER +#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER + +#define CONFIGURE_MAXIMUM_TASKS rtems_resource_unlimited(5) +#define CONFIGURE_MAXIMUM_SEMAPHORES 2 +#define CONFIGURE_MAXIMUM_POSIX_KEYS 1 + +#define CONFIGURE_INIT_TASK_INITIAL_MODES \ + (RTEMS_PREEMPT | RTEMS_NO_TIMESLICE | RTEMS_ASR | RTEMS_INTERRUPT_LEVEL(0)) + +#define CONFIGURE_INIT_TASK_PRIORITY 4 +#define CONFIGURE_RTEMS_INIT_TASKS_TABLE + +#define CONFIGURE_UNIFIED_WORK_AREAS + +#define CONFIGURE_INIT +#include <rtems/confdefs.h> +/* end of file */ diff --git a/testsuites/psxtests/psxkey08/psxkey08.doc b/testsuites/psxtests/psxkey08/psxkey08.doc new file mode 100644 index 0000000000..5d0b1711c4 --- /dev/null +++ b/testsuites/psxtests/psxkey08/psxkey08.doc @@ -0,0 +1,25 @@ +# COPYRIGHT (c) 1989-2009. +# On-Line Applications Research Corporation (OAR). +# +# The license and distribution terms for this file may be +# found in the file LICENSE in this distribution or at +# http://www.rtems.com/license/LICENSE. +# + +This file describes the directives and concepts tested by this test set. + +test set name: psxkey08 + +directives: + + pthread_key_create + pthread_setspecific + pthread_getspecific + pthread_key_delete + +concepts: + ++ Ensure that key data's operation(create, set, get and delete) under unlimited configuration in RTEMS classic API. Note: posix key is allowed to be called by RTEMS classic API. ++ this test workflow is: + 1. create thread and set thread's key data one by one until exhausting workspace RAM + 2. when step 1 finished, let all thread created thread run the getspecific function to test if key set and get works correctly. diff --git a/testsuites/psxtests/psxkey08/psxkey08.scn b/testsuites/psxtests/psxkey08/psxkey08.scn new file mode 100644 index 0000000000..a4f1be4959 --- /dev/null +++ b/testsuites/psxtests/psxkey08/psxkey08.scn @@ -0,0 +1,15 @@ + + +*** TEST KEY 08 *** +Init - Semaphore 1 create - OK +Init - Semaphore 2 create - OK +Init - pthread Key create - OK +Init - 651 tasks have been created - OK +Init - 651 tasks have been setted key data - OK +Init - flush semaphore 2 - OK +Init - sleep to yield processor - OK +Init - 651 Tasks have been got key data - OK +Init - pthread Key delete - OK +Init - semaphore 1 delete - OK +Init - semaphore 2 delete - OK +*** END OF TEST KEY 08*** diff --git a/testsuites/psxtests/psxkey09/Makefile.am b/testsuites/psxtests/psxkey09/Makefile.am new file mode 100644 index 0000000000..ed3ee0045d --- /dev/null +++ b/testsuites/psxtests/psxkey09/Makefile.am @@ -0,0 +1,23 @@ + +rtems_tests_PROGRAMS = psxkey09 +psxkey09_SOURCES = init.c + +dist_rtems_tests_DATA = psxkey09.scn +dist_rtems_tests_DATA += psxkey09.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)/include +AM_CPPFLAGS += -I$(top_srcdir)/../support/include + +LINK_OBJS = $(psxkey09_OBJECTS) +LINK_LIBS = $(psxkey09_LDLIBS) + +psxkey09$(EXEEXT): $(psxkey09_OBJECTS) $(psxkey09_DEPENDENCIES) + @rm -f psxkey09$(EXEEXT) + $(make-exe) + +include $(top_srcdir)/../automake/local.am diff --git a/testsuites/psxtests/psxkey09/init.c b/testsuites/psxtests/psxkey09/init.c new file mode 100644 index 0000000000..a44f0e36ca --- /dev/null +++ b/testsuites/psxtests/psxkey09/init.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2012 Zhongwei Yao. + * COPYRIGHT (c) 1989-2012. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> +#include "tmacros.h" +#include "pmacros.h" + + +/* forward declarations to avoid warnings */ +void *POSIX_Init(void *argument); +void destructor(void *value); +void *Test_Thread(void *argument); + +int Data_array[1] = {1}; + +pthread_key_t key; +volatile bool destructor_ran; + +void destructor(void *value) +{ + destructor_ran = true; +} + +void *Test_Thread( + void *argument +) +{ + int sc; + + /** + * Detach ourselves to release test thread's resource after thread exit. + */ + pthread_detach( pthread_self() ); + + puts( "Test_Thread - key pthread_setspecific - OK" ); + sc = pthread_setspecific( key, argument ); + rtems_test_assert( !sc ); + + puts( "Test_Thread - pthread_exit to run key destructors - OK" ); + return NULL; +} + +void *POSIX_Init( + void *ignored +) +{ + pthread_t thread; + int sc; + struct timespec delay_request; + + puts( "\n\n*** TEST KEY 09 ***" ); + + puts( "Init - pthread key create with destructor - OK" ); + sc = pthread_key_create( &key, destructor ); + rtems_test_assert( !sc ); + + puts( "Init - pthread create - OK" ); + sc = pthread_create( &thread, NULL, Test_Thread, &sc ); + rtems_test_assert( !sc ); + + puts( "Init - sleep - let thread run - OK" ); + delay_request.tv_sec = 0; + delay_request.tv_nsec = 8 * 100000000; + sc = nanosleep( &delay_request, NULL ); + rtems_test_assert( !sc ); + + puts( "Init - verify destructor run - OK" ); + rtems_test_assert( destructor_ran == true ); + + puts( "Init - pthread key delete - OK" ); + sc = pthread_key_delete( key ); + rtems_test_assert( sc == 0 ); + + puts( "*** END OF TEST KEY 09 ***" ); + rtems_test_exit(0); +} + +/* configuration information */ + +#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER +#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER + +#define CONFIGURE_MAXIMUM_POSIX_THREADS 2 +#define CONFIGURE_MAXIMUM_POSIX_KEYS 1 + +#define CONFIGURE_POSIX_INIT_THREAD_TABLE + +#define CONFIGURE_INIT +#include <rtems/confdefs.h> + +/* global variables */ diff --git a/testsuites/psxtests/psxkey09/psxkey09.doc b/testsuites/psxtests/psxkey09/psxkey09.doc new file mode 100644 index 0000000000..ecb9b742be --- /dev/null +++ b/testsuites/psxtests/psxkey09/psxkey09.doc @@ -0,0 +1,22 @@ +# COPYRIGHT (c) 1989-2009. +# On-Line Applications Research Corporation (OAR). +# +# The license and distribution terms for this file may be +# found in the file LICENSE in this distribution or at +# http://www.rtems.com/license/LICENSE. +# + +This file describes the directives and concepts tested by this test set. + +test set name: psxkey09 + +directives: + + pthread_key_create + pthread_setspecific + pthread_key_delete + _POSIX_Keys_Run_destructors + +concepts: + ++ Ensure that POSIX Key works when thread deleted first and then deleted key self. diff --git a/testsuites/psxtests/psxkey09/psxkey09.scn b/testsuites/psxtests/psxkey09/psxkey09.scn new file mode 100644 index 0000000000..707c7d63b1 --- /dev/null +++ b/testsuites/psxtests/psxkey09/psxkey09.scn @@ -0,0 +1,9 @@ +*** TEST KEY 09 *** +Init - pthread key create with destructor - OK +Init - pthread create - OK +Init - sleep - let thread run - OK +Test_Thread - key pthread_setspecific - OK +Test_Thread - pthread_exit to run key destructors - OK +Init - verify destructor run - OK +Init - pthread key delete - OK +*** END OF TEST KEY 09 *** diff --git a/testsuites/psxtests/psxkey10/Makefile.am b/testsuites/psxtests/psxkey10/Makefile.am new file mode 100644 index 0000000000..8e4f2f409b --- /dev/null +++ b/testsuites/psxtests/psxkey10/Makefile.am @@ -0,0 +1,23 @@ + +rtems_tests_PROGRAMS = psxkey10 +psxkey10_SOURCES = init.c + +dist_rtems_tests_DATA = psxkey10.scn +dist_rtems_tests_DATA += psxkey10.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)/include +AM_CPPFLAGS += -I$(top_srcdir)/../support/include + +LINK_OBJS = $(psxkey10_OBJECTS) +LINK_LIBS = $(psxkey10_LDLIBS) + +psxkey10$(EXEEXT): $(psxkey10_OBJECTS) $(psxkey10_DEPENDENCIES) + @rm -f psxkey10$(EXEEXT) + $(make-exe) + +include $(top_srcdir)/../automake/local.am diff --git a/testsuites/psxtests/psxkey10/init.c b/testsuites/psxtests/psxkey10/init.c new file mode 100644 index 0000000000..eee0c18d8d --- /dev/null +++ b/testsuites/psxtests/psxkey10/init.c @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2012 Zhongwei Yao. + * COPYRIGHT (c) 1989-2012. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> +#include "tmacros.h" +#include "pmacros.h" + +/* forward declarations to avoid warnings */ +void *POSIX_Init(void *argument); +void destructor(void *value); +void *Test_Thread(void *argument); + +int Data_array[1] = {1}; + +pthread_key_t key; +volatile bool destructor_ran; + +void destructor(void *value) +{ + destructor_ran = true; +} + +void *Test_Thread( + void *argument +) +{ + int sc; + + /** + * Detach ourselves to release test thread's resource after thread exit. + */ + pthread_detach( pthread_self() ); + + puts( "Test_Thread - key pthread_setspecific - OK" ); + sc = pthread_setspecific( key, argument ); + rtems_test_assert( !sc ); + + puts( "Test_Thread - pthread key delete - OK" ); + sc = pthread_key_delete( key ); + rtems_test_assert( sc == 0 ); + + puts( "Test_Thread - pthread exit, but don't run key destructors - OK" ); + return NULL; +} + +void *POSIX_Init( + void *ignored +) +{ + pthread_t thread; + int sc; + struct timespec delay_request; + + puts( "\n\n*** TEST KEY 10 ***" ); + + puts( "Init - pthread key create with destructor - OK" ); + sc = pthread_key_create( &key, destructor ); + rtems_test_assert( !sc ); + + puts( "Init - pthread create - OK" ); + sc = pthread_create( &thread, NULL, Test_Thread, &sc ); + rtems_test_assert( !sc ); + + puts( "Init - sleep - let thread run - OK" ); + delay_request.tv_sec = 0; + delay_request.tv_nsec = 8 * 100000000; + sc = nanosleep( &delay_request, NULL ); + rtems_test_assert( !sc ); + + puts( "Init - verify destructor did NOT run - OK" ); + rtems_test_assert( destructor_ran == false ); + + /* puts( "Init - pthread key delete - OK" ); */ + /* sc = pthread_key_delete( key ); */ + /* rtems_test_assert( sc == 0 ); */ + + puts( "*** END OF TEST KEY 10 ***" ); + rtems_test_exit(0); +} + +/* configuration information */ + +#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER +#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER + +#define CONFIGURE_MAXIMUM_POSIX_THREADS 2 +#define CONFIGURE_MAXIMUM_POSIX_KEYS 1 + +#define CONFIGURE_POSIX_INIT_THREAD_TABLE + +#define CONFIGURE_INIT +#include <rtems/confdefs.h> + +/* global variables */ diff --git a/testsuites/psxtests/psxkey10/psxkey10.doc b/testsuites/psxtests/psxkey10/psxkey10.doc new file mode 100644 index 0000000000..75c35c85c2 --- /dev/null +++ b/testsuites/psxtests/psxkey10/psxkey10.doc @@ -0,0 +1,22 @@ +# COPYRIGHT (c) 1989-2009. +# On-Line Applications Research Corporation (OAR). +# +# The license and distribution terms for this file may be +# found in the file LICENSE in this distribution or at +# http://www.rtems.com/license/LICENSE. +# + +This file describes the directives and concepts tested by this test set. + +test set name: psxkey10 + +directives: + + pthread_key_create + pthread_setspecific + pthread_key_delete + _POSIX_Keys_Run_destructors + +concepts: + ++ Ensure that POSIX Key works when key first and then deleted thread self. diff --git a/testsuites/psxtests/psxkey10/psxkey10.scn b/testsuites/psxtests/psxkey10/psxkey10.scn new file mode 100644 index 0000000000..98940e24ad --- /dev/null +++ b/testsuites/psxtests/psxkey10/psxkey10.scn @@ -0,0 +1,10 @@ + +*** TEST KEY 10 *** +Init - pthread key create with destructor - OK +Init - pthread create - OK +Init - sleep - let thread run - OK +Test_Thread - key pthread_setspecific - OK +Test_Thread - pthread key delete - OK +Test_Thread - pthread exit, but don't run key destructors - OK +Init - verify destructor did NOT run - OK +*** END OF TEST KEY 10 *** |