<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>