event flag manager API

Joel Sherrill joel.sherrill at OARcorp.com
Fri Oct 12 15:30:51 UTC 2012


On 10/12/2012 09:33 AM, Andrei Dimitrief-Jianu wrote:
> I see it as a more general implementation of an event manager
> as does not relate to a specific task.
An event manager would be just that -- a manager. It is
not standards based. So it is part of the Classic API.

Event "sets" have Ids so they are objects. That gives you
the create, ident, delete pattern.

The question regards structuring the code. Can the
current event code be refactored so you have
"event bit map" score helper. And a Score Event Set
handler. Then both classic API event services share
as much as possible.
>
>
> 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
> _______________________________________________
> rtems-devel mailing list
> rtems-devel at rtems.org
> http://www.rtems.org/mailman/listinfo/rtems-devel


-- 
Joel Sherrill, Ph.D.             Director of Research&  Development
joel.sherrill at OARcorp.com        On-Line Applications Research
Ask me about RTEMS: a free RTOS  Huntsville AL 35806
Support Available               (256) 722-9985




More information about the devel mailing list