<div dir="ltr"><div>Hi, Gedare, I think Joel has mentioned this about unlimited problem. I remember Joel has suggested a way to deal with this when use the pre-allocation approach. But I haven't got that idea... However, I only find my problem description mail, haven't found Joel's solution... Joel, do you remember there is such a mail?</div>
<div><div>"</div><div>>Joel wrote:</div><div>>>9/12/2012 5:08 AM, Ashi wrote:<br>>>Hi, Joel. <br>      >>My work stops at the problem of how to support unlimited mode when      we <span>pre</span>-allocate all memory at key manager >>initialization, and I      still haven't got time to learn the object extend code sample as      Chris mentioned in last mail. And I >>also haven't figured out how      to write right Configuration in confdef.h, my last post in      dev-list is about this.<br>
      >>I really have a busy time these days, and really sorry for my slow      progress. Anyway I'll try my best!<br></div>    >I think it should be merged as it is. When in unlimited mode, we can    document the<br>
    >recommendation that you use a unified work space.  We can leave this    as a<br>    >future enhancement. <br><br>    >But what you did is a BIG improvement. This next step is an    integration clean up<br>    >that can occur separately.<br>
<br>    >let's move to review and merge what you have, update the project    page, check coverage<br>    >on what's there, etc.<div><div tabindex="0" id=":17h"><img src="https://mail.google.com/mail/u/0/images/cleardot.gif">"<br>
<br></div></div></div><div class="gmail_quote">On Fri, Mar 15, 2013 at 6:53 AM, Gedare Bloom <span dir="ltr"><<a href="mailto:gedare@rtems.org" target="_blank">gedare@rtems.org</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb(204,204,204);border-left-width:1px;border-left-style:solid">On Tue, Mar 12, 2013 at 8:34 PM, Gedare Bloom <<a href="mailto:gedare@rtems.org" target="_blank">gedare@rtems.org</a>> wrote:<br>


> From: Zhongwei Yao <<a href="mailto:ashi08104@gmail.com" target="_blank">ashi08104@gmail.com</a>><br>
<div>><br>
> diff --git a/cpukit/posix/include/rtems/posix/key.h b/cpukit/posix/include/rtems/posix/key.h<br>
> index 0bb1dbe..16aea78 100644<br>
> --- a/cpukit/posix/include/rtems/posix/key.h<br>
> +++ b/cpukit/posix/include/rtems/posix/key.h<br>
</div><div>> @@ -34,27 +37,53 @@ extern "C" {<br>
>  #endif<br>
><br>
>  /**<br>
> - * This is the data Structure used to manage a POSIX key.<br>
> - *<br>
> - * NOTE: The Values is a table indexed by the index portion of the<br>
> - *       ID of the currently executing thread.<br>
> + * @brief The rbtree node used to manage a POSIX key and value.<br>
> + */<br>
> +typedef struct {<br>
> +  /** This field is the chain node structure. */<br>
> +  Chain_Node ch_node;<br>
> +  /**<br>
> +   * This field is the chain node, which is<br>
> +   * used in pre-allocated key node chain.<br>
> +   */<br>
> +  Chain_Node pre_ch_node;<br>
</div>Is a POSIX_Keys_Rbtree_node ever on two chains (one with ch_node and<br>
one with pre_ch_node) at the same time?<br>
<br>
If not, then they can share the same Chain_Control. This would also<br>
eliminate the need below to use offsetof.<br>
<div><br>
> diff --git a/cpukit/posix/src/keysetspecific.c b/cpukit/posix/src/keysetspecific.c<br>
> index b25e44c..de96964 100644<br>
> --- a/cpukit/posix/src/keysetspecific.c<br>
> +++ b/cpukit/posix/src/keysetspecific.c<br>
</div><div>> @@ -37,18 +41,41 @@ int pthread_setspecific(<br>
>    const void    *value<br>
>  )<br>
>  {<br>
> -  register POSIX_Keys_Control *the_key;<br>
> -  uint32_t                     api;<br>
> -  uint32_t                     index;<br>
>    Objects_Locations            location;<br>
> +  POSIX_Keys_Rbtree_node      *rb_node;<br>
> +  Chain_Node                  *ch_node;<br>
> +  POSIX_API_Control           *api;<br>
><br>
> -  the_key = _POSIX_Keys_Get( key, &location );<br>
> +  _POSIX_Keys_Get( key, &location );<br>
>    switch ( location ) {<br>
><br>
>      case OBJECTS_LOCAL:<br>
> -      api   = _Objects_Get_API( _Thread_Executing->Object.id );<br>
> -      index = _Objects_Get_index( _Thread_Executing->Object.id );<br>
> -      the_key->Values[ api ][ index ] = (void *) value;<br>
> +      ch_node = _Chain_Get_unprotected( &_POSIX_Keys_Preallocation_chain );<br>
</div>What if the Preallocation chain is empty?<br>
<div><br>
> +      /* there is no _Chain_Container_of in RTEMS Chain API */<br>
> +      rb_node = ( POSIX_Keys_Rbtree_node * ) \<br>
> +        ( ( uintptr_t )( ch_node ) \<br>
> +          - offsetof( POSIX_Keys_Rbtree_node, pre_ch_node ) );<br>
</div>Might not need this if you share the chain node for the two chains. If<br>
you do need to, maybe we should implement _Chain_Container_of().<br>
<div><br>
<br>
><br>
> diff --git a/cpukit/sapi/include/confdefs.h b/cpukit/sapi/include/confdefs.h<br>
> index cc55e92..2aaf30e 100644<br>
> --- a/cpukit/sapi/include/confdefs.h<br>
> +++ b/cpukit/sapi/include/confdefs.h<br>
> @@ -1709,11 +1709,18 @@ rtems_fs_init_functions_t    rtems_fs_init_helper =<br>
><br>
>    #ifndef CONFIGURE_MAXIMUM_POSIX_KEYS<br>
>      #define CONFIGURE_MAXIMUM_POSIX_KEYS           0<br>
> -    #define CONFIGURE_MEMORY_FOR_POSIX_KEYS(_keys) 0<br>
> +    #define CONFIGURE_MAXIMUM_POSIX_KEY_PAIRS      0<br>
> +    #define CONFIGURE_MEMORY_FOR_POSIX_KEYS(_keys, _key_pairs) 0<br>
>    #else<br>
> -    #define CONFIGURE_MEMORY_FOR_POSIX_KEYS(_keys) \<br>
> +    #ifndef CONFIGURE_MAXIMUM_POSIX_KEY_PAIRS<br>
> +      #define CONFIGURE_MAXIMUM_POSIX_KEY_PAIRS \<br>
> +        CONFIGURE_MAXIMUM_POSIX_KEYS \<br>
> +        * (CONFIGURE_MAXIMUM_POSIX_THREADS + CONFIGURE_MAXIMUM_TASKS)<br>
> +    #endif<br>
> +  #define CONFIGURE_MEMORY_FOR_POSIX_KEYS(_keys, _key_pairs)       \<br>
>        (_Configure_Object_RAM(_keys, sizeof(POSIX_Keys_Control) ) \<br>
> -        + (_keys) * 3 * _Configure_From_workspace(sizeof(void *) * 2))<br>
> +      + _key_pairs                        \<br>
> +      * _Configure_From_workspace(sizeof(POSIX_Keys_Rbtree_node)))<br>
>    #endif<br>
</div>Both CONFIGURE_MAXIMUM_POSIX_KEY_PAIRS and<br>
CONFIGURE_MAXIMUM_POSIX_KEYS should ignore the unlimited bit. Well,<br>
the first should probably inherit it from either unlimited keys or<br>
unlimited threads. The second should mask it off from _key_pairs by<br>
_Configure_Max_Objects(_key_pairs).<br>
<br>
We need to discuss the case of unlimited posix key pairs a little<br>
further, because the pre-allocation strategy does not handle it<br>
properly I think. The problem here is that a "key_pair" is not an<br>
Object, and so it is not managed by the Object Manager, so it does not<br>
make use of the pre-allocation support that Objects get. One approach<br>
could be to wrap the pre-allocation of "key_pair" with the allocation<br>
of keys themselves. This could easily handle limited and unlimited<br>
keys with limited threads: allocate the number of keys * number of<br>
threads every time Object allocation for keys occurs. The tricky case<br>
is when threads is unlimited, in which case the Object allocation also<br>
needs to allocate additional key_pairs when it allocates additional<br>
threads.<br>
<span><font color="#888888"><br>
-Gedare<br>
</font></span></blockquote></div><div class="gmail_extra">Cheers,</div><div class="gmail_extra">Zhongwei<br></div></div>