Index: cpukit/posix/include/rtems/posix/config.h
===================================================================
--- cpukit/posix/include/rtems/posix/config.h	(revision 5a556e4ea882ac16e1b75f08eb098076c21b8a10)
+++ cpukit/posix/include/rtems/posix/config.h	(revision b5c906429f6e67452eec1b0089ac7a204ff998ee)
@@ -52,4 +52,5 @@
   uint32_t                            maximum_condition_variables;
   uint32_t                            maximum_keys;
+  uint32_t                            maximum_key_value_pairs;
   uint32_t                            maximum_timers;
   uint32_t                            maximum_queued_signals;
Index: cpukit/posix/include/rtems/posix/key.h
===================================================================
--- cpukit/posix/include/rtems/posix/key.h	(revision 5a556e4ea882ac16e1b75f08eb098076c21b8a10)
+++ cpukit/posix/include/rtems/posix/key.h	(revision b5c906429f6e67452eec1b0089ac7a204ff998ee)
@@ -1,5 +1,5 @@
 /**
  * @file
- * 
+ *
  * @brief POSIX Key Private Support
  *
@@ -9,10 +9,11 @@
 
 /*
- *  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.
  */
 
@@ -20,4 +21,7 @@
 #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>
 
@@ -26,5 +30,5 @@
  *
  * @ingroup POSIXAPI
- * 
+ *
  */
 /**@{**/
@@ -35,30 +39,76 @@
 
 /**
- * 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
+);
 
 /**
@@ -68,5 +118,5 @@
  * 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.
  *
Index: cpukit/posix/include/rtems/posix/threadsup.h
===================================================================
--- cpukit/posix/include/rtems/posix/threadsup.h	(revision 5a556e4ea882ac16e1b75f08eb098076c21b8a10)
+++ cpukit/posix/include/rtems/posix/threadsup.h	(revision b5c906429f6e67452eec1b0089ac7a204ff998ee)
@@ -84,4 +84,13 @@
   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;
 
Index: cpukit/posix/src/key.c
===================================================================
--- cpukit/posix/src/key.c	(revision 5a556e4ea882ac16e1b75f08eb098076c21b8a10)
+++ cpukit/posix/src/key.c	(revision b5c906429f6e67452eec1b0089ac7a204ff998ee)
@@ -7,10 +7,11 @@
 
 /*
- *  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.
  */
 
@@ -30,17 +31,113 @@
 #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
+/* 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.
  *
- *  DESCRIPTION:
+ * 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.
  *
- *  This routine performs the initialization necessary for this manager.
- *
- *  Input parameters:   NONE
- *
- *  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)
 {
@@ -61,3 +158,11 @@
 #endif
   );
+
+  _RBTree_Initialize_empty(
+      &_POSIX_Keys_Key_value_lookup_tree,
+      _POSIX_Keys_Key_value_lookup_tree_compare_function,
+      true
+  );
+
+  _POSIX_Keys_Keypool_init();
 }
Index: cpukit/posix/src/keycreate.c
===================================================================
--- cpukit/posix/src/keycreate.c	(revision 5a556e4ea882ac16e1b75f08eb098076c21b8a10)
+++ cpukit/posix/src/keycreate.c	(revision b5c906429f6e67452eec1b0089ac7a204ff998ee)
@@ -1,16 +1,16 @@
 /**
- *  @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.
  */
 
@@ -38,8 +38,4 @@
 {
   POSIX_Keys_Control  *the_key;
-  void                *table;
-  uint32_t             the_api;
-  uint32_t             bytes_to_allocate;
-
 
   _Thread_Disable_dispatch();
@@ -53,48 +49,4 @@
 
   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;
Index: cpukit/posix/src/keydelete.c
===================================================================
--- cpukit/posix/src/keydelete.c	(revision 5a556e4ea882ac16e1b75f08eb098076c21b8a10)
+++ cpukit/posix/src/keydelete.c	(revision b5c906429f6e67452eec1b0089ac7a204ff998ee)
@@ -7,10 +7,10 @@
 
 /*
- *  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.
  */
 
@@ -43,6 +43,4 @@
 
     case OBJECTS_LOCAL:
-      _Objects_Close( &_POSIX_Keys_Information, &the_key->Object );
-
       _POSIX_Keys_Free_memory( the_key );
 
@@ -52,5 +50,5 @@
        */
       _POSIX_Keys_Free( the_key );
-      _Objects_Put( &the_key->Object );
+      _Objects_Put(&the_key->Object);
       return 0;
 
Index: cpukit/posix/src/keyfreememory.c
===================================================================
--- cpukit/posix/src/keyfreememory.c	(revision 5a556e4ea882ac16e1b75f08eb098076c21b8a10)
+++ cpukit/posix/src/keyfreememory.c	(revision b5c906429f6e67452eec1b0089ac7a204ff998ee)
@@ -2,15 +2,16 @@
  * @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.
  */
 
@@ -22,4 +23,5 @@
 #include <rtems/score/thread.h>
 #include <rtems/score/wkspace.h>
+#include <rtems/score/rbtree.h>
 #include <rtems/posix/key.h>
 
@@ -28,7 +30,37 @@
 )
 {
-  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 );
+  }
 }
Index: cpukit/posix/src/keygetspecific.c
===================================================================
--- cpukit/posix/src/keygetspecific.c	(revision 5a556e4ea882ac16e1b75f08eb098076c21b8a10)
+++ cpukit/posix/src/keygetspecific.c	(revision b5c906429f6e67452eec1b0089ac7a204ff998ee)
@@ -7,10 +7,11 @@
 
 /*
- *  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.
  */
 
@@ -27,4 +28,5 @@
 #include <rtems/score/thread.h>
 #include <rtems/score/wkspace.h>
+#include <rtems/score/rbtree.h>
 #include <rtems/posix/key.h>
 
@@ -37,18 +39,29 @@
 )
 {
-  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;
 
Index: cpukit/posix/src/keyrundestructors.c
===================================================================
--- cpukit/posix/src/keyrundestructors.c	(revision 5a556e4ea882ac16e1b75f08eb098076c21b8a10)
+++ cpukit/posix/src/keyrundestructors.c	(revision b5c906429f6e67452eec1b0089ac7a204ff998ee)
@@ -7,12 +7,13 @@
 
 /*
- *  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.
  */
 
@@ -23,5 +24,8 @@
 #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>
 
 /*
@@ -33,40 +37,59 @@
  *         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();
 }
Index: cpukit/posix/src/keysetspecific.c
===================================================================
--- cpukit/posix/src/keysetspecific.c	(revision 5a556e4ea882ac16e1b75f08eb098076c21b8a10)
+++ cpukit/posix/src/keysetspecific.c	(revision b5c906429f6e67452eec1b0089ac7a204ff998ee)
@@ -7,10 +7,11 @@
 
 /*
- *  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.
  */
 
@@ -23,9 +24,12 @@
 #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>
 
 /*
@@ -38,17 +42,36 @@
 )
 {
-  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;
 
Index: cpukit/posix/src/pthread.c
===================================================================
--- cpukit/posix/src/pthread.c	(revision 5a556e4ea882ac16e1b75f08eb098076c21b8a10)
+++ cpukit/posix/src/pthread.c	(revision b5c906429f6e67452eec1b0089ac7a204ff998ee)
@@ -237,4 +237,7 @@
   );
 
+  /** initialize thread's key vaule node chain */
+  _Chain_Initialize_empty( &api->Key_Chain );
+
   return true;
 }
Index: cpukit/sapi/include/confdefs.h
===================================================================
--- cpukit/sapi/include/confdefs.h	(revision 5a556e4ea882ac16e1b75f08eb098076c21b8a10)
+++ cpukit/sapi/include/confdefs.h	(revision b5c906429f6e67452eec1b0089ac7a204ff998ee)
@@ -1729,9 +1729,15 @@
   #ifndef CONFIGURE_MAXIMUM_POSIX_KEYS
     #define CONFIGURE_MAXIMUM_POSIX_KEYS           0
-    #define CONFIGURE_MEMORY_FOR_POSIX_KEYS(_keys) 0
-  #else
-    #define CONFIGURE_MEMORY_FOR_POSIX_KEYS(_keys) \
+    #define CONFIGURE_MAXIMUM_POSIX_KEY_VALUE_PAIRS      0
+    #define CONFIGURE_MEMORY_FOR_POSIX_KEYS(_keys, _key_value_pairs) 0
+  #else
+    #ifndef CONFIGURE_MAXIMUM_POSIX_KEY_VALUE_PAIRS
+      #define CONFIGURE_MAXIMUM_POSIX_KEY_VALUE_PAIRS \
+        CONFIGURE_MAXIMUM_POSIX_KEYS \
+        * (CONFIGURE_MAXIMUM_POSIX_THREADS + CONFIGURE_MAXIMUM_TASKS)
+    #endif
+  #define CONFIGURE_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
 
@@ -1855,5 +1861,6 @@
           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 ) + \
@@ -2304,4 +2311,5 @@
         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,
@@ -2546,5 +2554,6 @@
       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 ),
@@ -2617,4 +2626,5 @@
        (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) || \
@@ -2698,4 +2708,18 @@
 #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 */
Index: testsuites/psxtests/Makefile.am
===================================================================
--- testsuites/psxtests/Makefile.am	(revision 5a556e4ea882ac16e1b75f08eb098076c21b8a10)
+++ testsuites/psxtests/Makefile.am	(revision b5c906429f6e67452eec1b0089ac7a204ff998ee)
@@ -8,5 +8,6 @@
     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 \
Index: testsuites/psxtests/configure.ac
===================================================================
--- testsuites/psxtests/configure.ac	(revision 5a556e4ea882ac16e1b75f08eb098076c21b8a10)
+++ testsuites/psxtests/configure.ac	(revision b5c906429f6e67452eec1b0089ac7a204ff998ee)
@@ -123,4 +123,11 @@
 psxkey02/Makefile
 psxkey03/Makefile
+psxkey04/Makefile
+psxkey05/Makefile
+psxkey06/Makefile
+psxkey07/Makefile
+psxkey08/Makefile
+psxkey09/Makefile
+psxkey10/Makefile
 psxmount/Makefile
 psxmsgq01/Makefile
Index: testsuites/psxtests/psxkey01/init.c
===================================================================
--- testsuites/psxtests/psxkey01/init.c	(revision 5a556e4ea882ac16e1b75f08eb098076c21b8a10)
+++ testsuites/psxtests/psxkey01/init.c	(revision b5c906429f6e67452eec1b0089ac7a204ff998ee)
@@ -44,8 +44,8 @@
   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 ***" );
Index: testsuites/psxtests/psxkey01/psxkey01.scn
===================================================================
--- testsuites/psxtests/psxkey01/psxkey01.scn	(revision 5a556e4ea882ac16e1b75f08eb098076c21b8a10)
+++ testsuites/psxtests/psxkey01/psxkey01.scn	(revision b5c906429f6e67452eec1b0089ac7a204ff998ee)
@@ -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 ***
Index: testsuites/psxtests/psxkey04/Makefile.am
===================================================================
--- testsuites/psxtests/psxkey04/Makefile.am	(revision b5c906429f6e67452eec1b0089ac7a204ff998ee)
+++ testsuites/psxtests/psxkey04/Makefile.am	(revision b5c906429f6e67452eec1b0089ac7a204ff998ee)
@@ -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
Index: testsuites/psxtests/psxkey04/init.c
===================================================================
--- testsuites/psxtests/psxkey04/init.c	(revision b5c906429f6e67452eec1b0089ac7a204ff998ee)
+++ testsuites/psxtests/psxkey04/init.c	(revision b5c906429f6e67452eec1b0089ac7a204ff998ee)
@@ -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 */
Index: testsuites/psxtests/psxkey04/psxkey04.scn
===================================================================
--- testsuites/psxtests/psxkey04/psxkey04.scn	(revision b5c906429f6e67452eec1b0089ac7a204ff998ee)
+++ testsuites/psxtests/psxkey04/psxkey04.scn	(revision b5c906429f6e67452eec1b0089ac7a204ff998ee)
@@ -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 ***
Index: testsuites/psxtests/psxkey05/Makefile.am
===================================================================
--- testsuites/psxtests/psxkey05/Makefile.am	(revision b5c906429f6e67452eec1b0089ac7a204ff998ee)
+++ testsuites/psxtests/psxkey05/Makefile.am	(revision b5c906429f6e67452eec1b0089ac7a204ff998ee)
@@ -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
Index: testsuites/psxtests/psxkey05/init.c
===================================================================
--- testsuites/psxtests/psxkey05/init.c	(revision b5c906429f6e67452eec1b0089ac7a204ff998ee)
+++ testsuites/psxtests/psxkey05/init.c	(revision b5c906429f6e67452eec1b0089ac7a204ff998ee)
@@ -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 */
Index: testsuites/psxtests/psxkey05/psxkey05.scn
===================================================================
--- testsuites/psxtests/psxkey05/psxkey05.scn	(revision b5c906429f6e67452eec1b0089ac7a204ff998ee)
+++ testsuites/psxtests/psxkey05/psxkey05.scn	(revision b5c906429f6e67452eec1b0089ac7a204ff998ee)
@@ -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 ***
Index: testsuites/psxtests/psxkey06/Makefile.am
===================================================================
--- testsuites/psxtests/psxkey06/Makefile.am	(revision b5c906429f6e67452eec1b0089ac7a204ff998ee)
+++ testsuites/psxtests/psxkey06/Makefile.am	(revision b5c906429f6e67452eec1b0089ac7a204ff998ee)
@@ -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
Index: testsuites/psxtests/psxkey06/init.c
===================================================================
--- testsuites/psxtests/psxkey06/init.c	(revision b5c906429f6e67452eec1b0089ac7a204ff998ee)
+++ testsuites/psxtests/psxkey06/init.c	(revision b5c906429f6e67452eec1b0089ac7a204ff998ee)
@@ -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 */
Index: testsuites/psxtests/psxkey06/psxkey06.scn
===================================================================
--- testsuites/psxtests/psxkey06/psxkey06.scn	(revision b5c906429f6e67452eec1b0089ac7a204ff998ee)
+++ testsuites/psxtests/psxkey06/psxkey06.scn	(revision b5c906429f6e67452eec1b0089ac7a204ff998ee)
@@ -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 ***
Index: testsuites/psxtests/psxkey07/Makefile.am
===================================================================
--- testsuites/psxtests/psxkey07/Makefile.am	(revision b5c906429f6e67452eec1b0089ac7a204ff998ee)
+++ testsuites/psxtests/psxkey07/Makefile.am	(revision b5c906429f6e67452eec1b0089ac7a204ff998ee)
@@ -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
Index: testsuites/psxtests/psxkey07/init.c
===================================================================
--- testsuites/psxtests/psxkey07/init.c	(revision b5c906429f6e67452eec1b0089ac7a204ff998ee)
+++ testsuites/psxtests/psxkey07/init.c	(revision b5c906429f6e67452eec1b0089ac7a204ff998ee)
@@ -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 */
Index: testsuites/psxtests/psxkey07/psxkey07.scn
===================================================================
--- testsuites/psxtests/psxkey07/psxkey07.scn	(revision b5c906429f6e67452eec1b0089ac7a204ff998ee)
+++ testsuites/psxtests/psxkey07/psxkey07.scn	(revision b5c906429f6e67452eec1b0089ac7a204ff998ee)
@@ -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 ***
Index: testsuites/psxtests/psxkey08/Makefile.am
===================================================================
--- testsuites/psxtests/psxkey08/Makefile.am	(revision b5c906429f6e67452eec1b0089ac7a204ff998ee)
+++ testsuites/psxtests/psxkey08/Makefile.am	(revision b5c906429f6e67452eec1b0089ac7a204ff998ee)
@@ -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
Index: testsuites/psxtests/psxkey08/init.c
===================================================================
--- testsuites/psxtests/psxkey08/init.c	(revision b5c906429f6e67452eec1b0089ac7a204ff998ee)
+++ testsuites/psxtests/psxkey08/init.c	(revision b5c906429f6e67452eec1b0089ac7a204ff998ee)
@@ -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 */
Index: testsuites/psxtests/psxkey08/psxkey08.scn
===================================================================
--- testsuites/psxtests/psxkey08/psxkey08.scn	(revision b5c906429f6e67452eec1b0089ac7a204ff998ee)
+++ testsuites/psxtests/psxkey08/psxkey08.scn	(revision b5c906429f6e67452eec1b0089ac7a204ff998ee)
@@ -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***
Index: testsuites/psxtests/psxkey09/Makefile.am
===================================================================
--- testsuites/psxtests/psxkey09/Makefile.am	(revision b5c906429f6e67452eec1b0089ac7a204ff998ee)
+++ testsuites/psxtests/psxkey09/Makefile.am	(revision b5c906429f6e67452eec1b0089ac7a204ff998ee)
@@ -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
Index: testsuites/psxtests/psxkey09/init.c
===================================================================
--- testsuites/psxtests/psxkey09/init.c	(revision b5c906429f6e67452eec1b0089ac7a204ff998ee)
+++ testsuites/psxtests/psxkey09/init.c	(revision b5c906429f6e67452eec1b0089ac7a204ff998ee)
@@ -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 */
Index: testsuites/psxtests/psxkey09/psxkey09.scn
===================================================================
--- testsuites/psxtests/psxkey09/psxkey09.scn	(revision b5c906429f6e67452eec1b0089ac7a204ff998ee)
+++ testsuites/psxtests/psxkey09/psxkey09.scn	(revision b5c906429f6e67452eec1b0089ac7a204ff998ee)
@@ -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 ***
Index: testsuites/psxtests/psxkey10/Makefile.am
===================================================================
--- testsuites/psxtests/psxkey10/Makefile.am	(revision b5c906429f6e67452eec1b0089ac7a204ff998ee)
+++ testsuites/psxtests/psxkey10/Makefile.am	(revision b5c906429f6e67452eec1b0089ac7a204ff998ee)
@@ -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
Index: testsuites/psxtests/psxkey10/init.c
===================================================================
--- testsuites/psxtests/psxkey10/init.c	(revision b5c906429f6e67452eec1b0089ac7a204ff998ee)
+++ testsuites/psxtests/psxkey10/init.c	(revision b5c906429f6e67452eec1b0089ac7a204ff998ee)
@@ -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 */
Index: testsuites/psxtests/psxkey10/psxkey10.scn
===================================================================
--- testsuites/psxtests/psxkey10/psxkey10.scn	(revision b5c906429f6e67452eec1b0089ac7a204ff998ee)
+++ testsuites/psxtests/psxkey10/psxkey10.scn	(revision b5c906429f6e67452eec1b0089ac7a204ff998ee)
@@ -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 ***
