[PATCH 1/2] score: Implement scheduler helping protocol
Gedare Bloom
gedare at rtems.org
Tue Jul 8 18:28:00 UTC 2014
On Tue, Jul 8, 2014 at 2:20 PM, Sebastian Huber
<sebastian.huber at embedded-brains.de> wrote:
>>> >
>>> >diff --git a/cpukit/score/include/rtems/score/threadimpl.h
>>> > b/cpukit/score/include/rtems/score/threadimpl.h
>>> >index 4971e9d..cb7d5fe 100644
>>> >--- a/cpukit/score/include/rtems/score/threadimpl.h
>>> >+++ b/cpukit/score/include/rtems/score/threadimpl.h
>>> >@@ -828,6 +828,16 @@ RTEMS_INLINE_ROUTINE bool _Thread_Owns_resources(
>>> > return owns_resources;
>>> > }
>>> >
>>> >+#if defined(RTEMS_SMP)
>>> >+RTEMS_INLINE_ROUTINE Thread_Control *_Thread_Resource_node_to_thread(
>>> >+ Resource_Node *node
>>> >+)
>>> >+{
>>> >+ return (Thread_Control *)
>>> >+ ( (char *) node - offsetof( Thread_Control, Resource_node ) );
>>> >+}
>>
>> We should include some generic container_of function in rtems instead
>> of reproducing it multiple places.
>
>
> In <sys/cdefs.h> we have:
>
> /*
> * Given the pointer x to the member m of the struct s, return
> * a pointer to the containing structure. When using GCC, we first
> * assign pointer x to a local variable, to check that its type is
> * compatible with member m.
> */
> #if __GNUC_PREREQ__(3, 1)
> #define __containerof(x, s, m) ({ \
> const volatile __typeof__(((s *)0)->m) *__x = (x); \
> __DEQUALIFY(s *, (const volatile char *)__x - __offsetof(s, m));\
> })
> #else
> #define __containerof(x, s, m) \
> __DEQUALIFY(s *, (const volatile char *)(x) - __offsetof(s, m))
> #endif
>
> What about adding a similar
>
> _Container_of()
>
> or
>
> rtems_container_of()
>
> to <rtems/score/basedefs.h>?
>
Probably it should be _Container_of() for supercore visible code.
>>> >+
>>> >+ _Resource_Node_set_root( resource_node, &root->Resource_node );
>>> >+
>>> >+ needs_also_help = ( *scheduler->Operations.ask_for_help )(
>>> >+ scheduler,
>>> >+ offers_help,
>>> >+ needs_help
>>> >+ );
>>> >+
>>> >+ if ( needs_also_help != needs_help && needs_also_help != NULL ) {
>>> >+ _Assert( ctx->needs_help == NULL );
>>> >+ ctx->needs_help = needs_also_help;
>>> >+ }
>>> >+
>>> >+ return false;
>>> >+}
>>> >+
>>> >+void _Scheduler_Thread_change_resource_root(
>>> >+ Thread_Control *top,
>>> >+ Thread_Control *root
>>> >+)
>>> >+{
>>> >+ Scheduler_Set_root_context ctx = { root, NULL };
>>> >+ Thread_Control *offers_help = top;
>>> >+ Scheduler_Node *offers_help_node;
>>> >+ Thread_Control *offers_also_help;
>>> >+ ISR_Level level;
>>> >+
>>> >+ _ISR_Disable( level );
>>> >+
>>> >+ offers_help_node = _Scheduler_Thread_get_node( offers_help );
>>> >+ offers_also_help = _Scheduler_Node_get_owner( offers_help_node );
>>> >+
>>> >+ if ( offers_help != offers_also_help ) {
>>> >+ _Scheduler_Set_root_visitor( &offers_also_help->Resource_node, &ctx
>>> > );
>>> >+ _Assert( ctx.needs_help == offers_help );
>>> >+ ctx.needs_help = NULL;
>>> >+ }
>>> >+
>>> >+ _Scheduler_Set_root_visitor( &top->Resource_node, &ctx );
>>> >+ _Resource_Iterate( &top->Resource_node, _Scheduler_Set_root_visitor,
>>> > &ctx );
>>> >+
>>
>> Does this iterate() with disabled interrupts have bad implications for
>> schedulability / worst-case latency?
>>
>
> Yes, the worst-case latency depends now on the resource tree size. I don't
> think its easy to avoid this. You have at least the following options.
>
> 1. Use one lock or a hierarchy of locks to freeze the tree state and thus
> enable a safe iteration.
>
> 2. Partially lock the tree and somehow provide safe iteration. How? Is this
> possible with fine grained locking at all?
>
> 3. Organize the tree so that the interesting elements are the min/max nodes.
> I don't know how this can be done. Each scheduler state change may result
> in updates of all resource trees in the system.
>
> This implementation was done with fine grained locking in mind. So I did
> choose 1. We can use the tree to get a partial order of per-resource locks
> necessary to avoid deadlocks.
>
Ok, this is a tricky problem, and it should definitely be documented.
I don't have a good idea right now about how the resource tree grows.
Perhaps the size of the tree is bounded such that the cost isn't too
bad.
-Gedare
More information about the devel
mailing list