event flag manager API

Andrei Dimitrief-Jianu andrei.dimitrief.jianu at gmail.com
Fri Oct 12 14:33:43 UTC 2012


I see it as a more general implementation of an event manager
as does not relate to a specific task.



On Fri, Oct 12, 2012 at 10:03 AM, Gedare Bloom <gedare at rtems.org> wrote:
> How/Does this relate to the existing RTEMS Event Manager?
> -Gedare
>
> On Tue, Oct 2, 2012 at 10:31 AM, Andrei Dimitrief-Jianu
> <andrei.dimitrief.jianu at gmail.com> wrote:
>> Hello,
>>
>> Below is a description for an event flag manager API. It would be used
>> to synchronize
>> tasks, but in a manner that is independent of a particular task.
>>
>> I am interested in feedback. I am not sure if the API covers all
>> possible scenarios
>> or if it needs clarifications.
>>
>> Regards,
>> Andrei.
>>
>>
>> *** EVENT FLAG MANAGER
>>
>> The event flag manager uses multiple bits in a bit pattern to
>> synchronize tasks.
>> Each bit in the bit pattern represents an event that can be set, cleared, and
>> waited for. An event flag can use a maximum of 32 events to synchronize tasks.
>>
>>
>> ** EFLAG_CREATE
>>
>> * CALLING SEQUENCE:
>>
>> rtems_status_code rtems_eflag_create(
>>   rtems_name name,
>>   uint32_t flag_pattern,
>>   rtems_attribute attribute_set,
>>   rtems_id *id
>> );
>>
>> * DIRECTIVE STATUS CODES:
>>
>> RTEMS_SUCCESSFUL - event flag created successfully
>>
>> RTEMS_INVALID_ADDRESS - id is NULL
>> RTEMS_INVALID_ATTRIBUTE - the attribute set contains invalid flag
>> RTEMS_INVALID_FLAG - the flag is invalid
>> RTEMS_INVALID_NAME - invalid event flag name
>> RTEMS_NOT_DEFINED - invalid attribute set
>> RTEMS_TOO_MANY - too many event flags or too many global objects created
>>
>> * DESCRIPTION:
>>
>> The directive creates an event flag with the specified flag pattern.
>>
>> * NOTES:
>>
>> The attribute set can be a combination of the following:
>>
>> RTEMS_LOCAL - local task (default)
>> RTEMS_GLOBAL - global task
>> RTEMS_FIFO - tasks wait by FIFO (default)
>> RTEMS_PRIORITY - tasks wait by priority
>>
>> RTEMS_DEFAULT_ATTRIBUTES - all default attributes are desired
>>
>> If RTEMS_FIFO is used in the attribute set, the tasks will wait for the
>> events to occur in the order they were blocked.
>>
>>
>> ** EFLAG_IDENT
>>
>> * CALLING SEQUENCE:
>>
>> rtems_status_code rtems_eflag_ident(
>>   rtems_name name,
>>   uint32_t node,
>>   rtems_id *id
>> );
>>
>> * DIRECTIVE STATUS CODES:
>>
>> RTEMS_SUCCESSFUL - event flag identified successfully
>>
>> RTEMS_INVALID_NAME - event flag name not found
>> RTEMS_INVALID_NODE - invalid node id
>>
>> * DESCRIPTION:
>>
>> The directive returns the event flag id associated with the event flag name.
>>
>> * NOTES:
>>
>> If node is RTEMS_SEARCH_ALL_NODES, all nodes are searched with the
>> local node being
>> searched first. All other nodes are searched with the lowest numbered
>> node searched first.
>>
>>
>> ** EFLAG_DELETE
>>
>> * CALLING SEQUENCE:
>>
>> rtems_status_code rtems_eflag_delete(
>>   rtems_id id
>> );
>>
>> * DIRECTIVE STATUS CODES:
>>
>> RTEMS_SUCCESSFUL - event flag deleted successfully
>>
>> RTEMS_INVALID_ID - invalid event flag id
>> RTEMS_NOT_OWNER_OF_RESOURCE - calling task does not own the event flag
>> RTEMS_RESOURCE_IN_USE - event flag in use
>>
>> * DESCRIPTION:
>>
>> The directive deletes the event flag specified by id. All tasks blocked waiting
>> for the event(s) will be readied and returned a status code
>> (RTEMS_OBJECT_WAS_DELETED)
>> which indicates that the event flag was deleted.
>>
>> * NOTES:
>>
>> The event flag should be flushed before calling rtems_eflag_delete
>> directive. Otherwise,
>> rtems_eflag_delete returns with a status code of RTEMS_RESOURCE_IN_USE.
>>
>>
>> ** EFLAG_WAIT_ONE
>>
>> * CALLING SEQUENCE:
>>
>> rtems_status_code rtems_eflag_wait_one(
>>   rtems_id id,
>>   uint32_t flag,
>>   rtems_options option_set,
>>   rtems_interval timeout
>> );
>>
>> * DIRECTIVE STATUS CODES:
>>
>> RTEMS_SUCCESSFUL - directive returned after event was set
>>
>> RTEMS_INVALID_FLAG - the flag is invalid
>> RTEMS_INVALID_ID - invalid event flag id
>> RTEMS_OBJECT_WAS_DELETED - event flag deleted while waiting
>> RTEMS_TIMEOUT - timed out waiting for the event
>> RTEMS_UNSATISFIED - event made unavailable by a flush directive
>>
>> * DESCRIPTION:
>>
>> The directive blocks waiting for the event specified by flag.
>>
>> * NOTES:
>>
>> The option set can have the values:
>>
>> RTEMS_WAIT - the task will wait for the lock (default)
>> RTEMS_NO_WAIT - task does not wait
>>
>> If RTEMS_NO_TIMEOUT is passed as timeout, the directive blocks waiting for
>> the event, even if option set does not contain RTEMS_WAIT.
>>
>> The flag passed as argument must contain one and only one bit set, otherwise
>> an error status code RTEMS_INVALID_FLAG is returned.
>>
>>
>> ** EFLAG_WAIT_ANY
>>
>> * CALLING SEQUENCE:
>>
>> rtems_status_code rtems_eflag_wait_any(
>>   rtems_id id,
>>   uint32_t flag_pattern,
>>   rtems_options option_set,
>>   rtems_interval timeout
>> );
>>
>> * DIRECTIVE STATUS CODES:
>>
>> RTEMS_SUCCESSFUL - directive returned after any of the events is set
>>
>> RTEMS_INVALID_FLAG - the flag is invalid
>> RTEMS_INVALID_ID - invalid event flag id
>> RTEMS_OBJECT_WAS_DELETED - event flag deleted while waiting
>> RTEMS_TIMEOUT - timed out waiting for the event
>> RTEMS_UNSATISFIED - any of the events specified by the flag pattern
>> made unavailable by a flush directive
>>
>> * DESCRIPTION:
>>
>> The directive blocks waiting for any of the events specified by the
>> flag pattern to be set.
>>
>> * NOTES:
>>
>> The option set can have the values:
>>
>> RTEMS_WAIT - the task will wait for the lock (default)
>> RTEMS_NO_WAIT - task does not wait
>>
>> If RTEMS_NO_TIMEOUT is passed as timeout, the directive blocks waiting for
>> any if the events, even if option set does not contain RTEMS_WAIT.
>>
>> The flag passed as argument must contain at least one bit set, otherwise
>> an error status code RTEMS_INVALID_FLAG is returned.
>>
>>
>> ** EFLAG_WAIT_ALL
>>
>> * CALLING SEQUENCE:
>>
>> rtems_status_code rtems_eflag_wait_all(
>>   rtems_id id,
>>   uint32_t flag_pattern,
>>   rtems_options option_set,
>>   rtems_interval timeout
>> );
>>
>> * DIRECTIVE STATUS CODES:
>>
>> RTEMS_SUCCESSFUL - directive returned after all events were set
>>
>> RTEMS_INVALID_FLAG - the flag is invalid
>> RTEMS_INVALID_ID - invalid event flag id
>> RTEMS_OBJECT_WAS_DELETED - event flag deleted while waiting
>> RTEMS_TIMEOUT - timed out waiting for the event
>> RTEMS_UNSATISFIED - all of the events specified by the flag pattern
>> made unavailable by a flush directive
>>
>> * DESCRIPTION:
>>
>> The directive blocks waiting for all of the events specified by the
>> flag pattern to be set.
>>
>> * NOTES:
>>
>> The option set can have the values:
>>
>> RTEMS_WAIT - the task will wait for the lock (default)
>> RTEMS_NO_WAIT - task does not wait
>>
>> If RTEMS_NO_TIMEOUT is passed as timeout, the directive blocks waiting for
>> all the events, even if option set does not contain RTEMS_WAIT.
>>
>> The flag passed as argument must contain at least one bit set, otherwise
>> an error status code RTEMS_INVALID_FLAG is returned.
>>
>>
>> ** EFLAG_SET
>>
>> * CALLING SEQUENCE:
>>
>> rtems_status_code rtems_eflag_set(
>>   rtems_id id,
>>   uint32_t flag_pattern
>> );
>>
>> * DIRECTIVE STATUS CODES:
>>
>> RTEMS_SUCCESSFUL - event flags set successfully
>>
>> RTEMS_INVALID_FLAG - the flag pattern is invalid
>> RTEMS_INVALID_ID - invalid event flag id
>>
>> * DESCRIPTION:
>>
>> The directive sets the events specified by the flag pattern in the
>> event flag specified by id.
>>
>> * NOTES:
>>
>> The flag pattern passed as argument must contain at least one bit set,
>> otherwise an error status code RTEMS_INVALID_FLAG is returned.
>>
>>
>> ** EFLAG_SET_AND_CLEAR
>>
>> * CALLING SEQUENCE:
>>
>> rtems_status_code rtems_eflag_set_and_clear(
>>   rtems_id id,
>>   uint32_t flag_pattern
>> );
>>
>> * DIRECTIVE STATUS CODES:
>>
>> RTEMS_SUCCESSFUL - event flags set and cleared successfully
>>
>> RTEMS_INVALID_FLAG - the flag pattern is invalid
>> RTEMS_INVALID_ID - invalid event flag id
>>
>> * DESCRIPTION:
>>
>> The directive sets the events specified by the flag pattern in the event flag
>> specified by id and after all tasks waiting for the events are unblocked,
>> it clears the events flag set. Operations are executed atomically.
>>
>> * NOTES:
>>
>> The flag pattern passed as argument must contain at least one bit set,
>> otherwise an error status code RTEMS_INVALID_FLAG is returned.
>>
>>
>> ** EFLAG_CLEAR
>>
>> * CALLING SEQUENCE:
>>
>> rtems_status_code rtems_eflag_clear(
>>   rtems_id id,
>>   uint32_t flag_pattern
>> );
>>
>> * DIRECTIVE STATUS CODES:
>>
>> RTEMS_SUCCESSFUL - event flags cleared successfully
>>
>> RTEMS_INVALID_FLAG - the flag pattern is invalid
>> RTEMS_INVALID_ID - invalid event flag id
>>
>> * DESCRIPTION:
>>
>> The directive clears the events specified by the flag pattern.
>>
>> * NOTES:
>>
>> The flag pattern passed as argument must contain at least one bit set,
>> otherwise an error status code RTEMS_INVALID_FLAG is returned.
>>
>>
>> ** EFLAG_FLUSH
>>
>> * CALLING SEQUENCE:
>>
>> rtems_status_code rtems_eflag_flush(
>>   rtems_id id,
>>   uint32_t flag_pattern
>> );
>>
>> * DIRECTIVE STATUS CODES:
>>
>> RTEMS_SUCCESSFUL - event flags flushed successfully
>>
>> RTEMS_INVALID_FLAG - the flag pattern is invalid
>> RTEMS_INVALID_ID - invalid event flag id
>>
>> * DESCRIPTION:
>>
>> The directive flushes the events specified by the flag pattern.
>>
>> * NOTES:
>>
>> The flag pattern passed as argument must contain at least one bit set,
>> otherwise an error status code RTEMS_INVALID_FLAG is returned.
>>
>> The tasks which are unblocked as the result of this directive will
>> return from the rtems_eflag_wait_one, rtems_eflag_wait_any or
>> rtems_eflag_wait_all directive with a status code of RTEMS_UNSATISFIED.
>>
>> As a result, the event flags described by the flag pattern will be cleared.
>>
>>
>> ** EFLAG_STATUS
>>
>> * CALLING SEQUENCE:
>>
>> rtems_status_code rtems_eflag_status(
>>   rtems_id id,
>>   uint32_t *flag_pattern
>> );
>>
>> * DIRECTIVE STATUS CODES:
>>
>> RTEMS_SUCCESSFUL - event status returned successfully
>>
>> RTEMS_INVALID_ADDRESS - the flag pattern pointer is NULL
>> RTEMS_INVALID_ID - invalid event flag id
>>
>> * DESCRIPTION:
>>
>> The directive returns the status of the event flag specified by id.
>>
>> * NOTES:
>>
>> [...]
>>
>>
>> ** USE CASE:
>>
>> ////////////////////////////////////////////////////////////////////
>> #define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
>> #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
>> #define CONFIGURE_MICROSECONDS_PER_TICK 1000
>> #define CONFIGURE_TICKS_PER_TIMESLICE 50
>> #define CONFIGURE_MAXIMUM_TASKS 4
>> #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
>> #define CONFIGURE_INIT
>>
>> #include <bsp.h>
>> #include <stdlib.h>
>> #include <stdio.h>
>> #include <rtems/confdefs.h>
>>
>> #define EVENT_FLAG_1 0x01
>> #define EVENT_FLAG_2 0x02
>> #define EVENT_FLAG_3 0x04
>>
>> rtems_task worker_task( rtems_task_argument argument );
>>
>> rtems_id eflag_id;
>>
>> rtems_task
>> Init( rtems_task_argument ignored )
>> {
>>   rtems_id  task_id;
>>   rtems_status_code status_code;
>>   rtems_name task_name;
>>
>>   rtems_name eflag_name;
>>   eflag_name = rtems_build_name( 'E', 'F', 'L', 'G' );
>>   status_code = rtems_eflag_create(
>>     eflag_name,
>>     EVENT_FLAG_1 | EVENT_FLAG_2 | EVENT_FLAG_3,
>>     RTEMS_LOCAL | RTEMS_FIFO,
>>     &eflag_id
>>     );
>>   if( RTEMS_SUCCESSFUL != status_code )
>>   {
>>     printf( "\nrtems_eflag_create failed with status of %d.\n", status_code );
>>     exit( 1 );
>>   }
>>
>>   /////////////////////////////////////////////////////////////////////////////
>>   task_name = rtems_build_name( 'T', 'S', 'K', '1' );
>>
>>   status_code = rtems_task_create(
>>     task_name, 1, RTEMS_MINIMUM_STACK_SIZE,
>>     RTEMS_NO_PREEMPT, RTEMS_FLOATING_POINT, &task_id );
>>   if( RTEMS_SUCCESSFUL != status_code )
>>   {
>>     printf( "\nrtems_task_create failed with status of %d.\n", status_code );
>>     exit( 1 );
>>   }
>>
>>   status_code = rtems_task_start( task_id, worker_task, EVENT_FLAG_1 );
>>   if( RTEMS_SUCCESSFUL != status_code )
>>   {
>>     printf( "\nrtems_task_start failed with status of %d.\n", status_code );
>>     exit( 1 );
>>   }
>>   /////////////////////////////////////////////////////////////////////////////
>>   task_name = rtems_build_name( 'T', 'S', 'K', '2' );
>>
>>   status_code = rtems_task_create(
>>     task_name, 1, RTEMS_MINIMUM_STACK_SIZE,
>>     RTEMS_NO_PREEMPT, RTEMS_FLOATING_POINT, &task_id );
>>   if( RTEMS_SUCCESSFUL != status_code )
>>   {
>>     printf( "\nrtems_task_create failed with status of %d.\n", status_code );
>>     exit( 1 );
>>   }
>>
>>   status_code = rtems_task_start( task_id, worker_task, EVENT_FLAG_2 );
>>   if( RTEMS_SUCCESSFUL != status_code )
>>   {
>>     printf( "\nrtems_task_start failed with status of %d.\n", status_code );
>>     exit( 1 );
>>   }
>>   /////////////////////////////////////////////////////////////////////////////
>>   task_name = rtems_build_name( 'T', 'S', 'K', '3' );
>>
>>   status_code = rtems_task_create(
>>     task_name, 1, RTEMS_MINIMUM_STACK_SIZE,
>>     RTEMS_NO_PREEMPT, RTEMS_FLOATING_POINT, &task_id );
>>   if( RTEMS_SUCCESSFUL != status_code )
>>   {
>>     printf( "\nrtems_task_create failed with status of %d.\n", status_code );
>>     exit( 1 );
>>   }
>>
>>   status_code = rtems_task_start( task_id, worker_task, EVENT_FLAG_3 );
>>   if( RTEMS_SUCCESSFUL != status_code )
>>   {
>>     printf( "\nrtems_task_start failed with status of %d.\n", status_code );
>>     exit( 1 );
>>   }
>>   /////////////////////////////////////////////////////////////////////////////
>>
>>   printf( "\nmain task waiting for the workers to finish...\n" );
>>   status_code = rtems_eflag_wait_all(
>>     eflag_id,
>>     EVENT_FLAG_1 | EVENT_FLAG_2 | EVENT_FLAG_3,
>>     RTEMS_WAIT,
>>     RTEMS_NO_TIMEOUT
>>   );
>>   if( RTEMS_SUCCESSFUL != status_code )
>>   {
>>     printf( "\nrtems_eflag_wait_all failed with status of %d.\n", status_code );
>>     exit( 1 );
>>   }
>>
>>   status_code = rtems_eflag_delete( eflag_id );
>>   if( RTEMS_SUCCESSFUL != status_code )
>>   {
>>     printf( "\nrtems_eflag_delete failed with status of %d.\n", status_code );
>>     exit( 1 );
>>   }
>>
>>   printf( "\nmain task is exiting...\n" );
>>
>>   exit( 0 );
>> }
>>
>> rtems_task
>> worker_task( rtems_task_argument argument )
>> {
>>   int index = 0;
>>   while( index++ < 10 * argument )
>>   {
>>     printf( "\ntask [%d] > doing something in the user task [%d].\n",
>> (uint32_t)argument, index );
>>     rtems_task_wake_after( RTEMS_MILLISECONDS_TO_TICKS( 1000 ) );
>>   }
>>
>>   rtems_eflag_set( eflag_id, (uint32_t)argument );
>>
>>   printf( "\ntask [%d] is exiting...\n", (uint32_t)argument );
>>   rtems_task_delete( rtems_task_self() );
>>
>> }
>> ////////////////////////////////////////////////////////////////////
>> _______________________________________________
>> rtems-devel mailing list
>> rtems-devel at rtems.org
>> http://www.rtems.org/mailman/listinfo/rtems-devel



More information about the devel mailing list