event flag manager API
Gedare Bloom
gedare at rtems.org
Fri Oct 12 14:03:47 UTC 2012
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