[PATCH 2/3] score: Add Beacon Handler

Sebastian Huber sebastian.huber at embedded-brains.de
Tue Oct 16 17:10:02 UTC 2012


For documentation please have a look at this comment block and also the 
new test.

The @msc part can be compiled by the mscgen tool.

You can use events for this synchronization pattern, but this has severe 
problems in libraries.  You can also use condition variables for this 
pattern.  The benefit of events and beacons is that every task has the 
infrastructure.  You don't need per request objects.  In the example 
below, the request object is on the stack like in bdbuf.

On 16/10/12 16:45, Sebastian Huber wrote:
> +/**
> + * @defgroup ClassicBeacon Beacon
> + *
> + * @ingroup ClassicRTEMS
> + *
> + * A Beacon is a synchronization primitive which helps to solve simple request
> + * handling by asynchronous mechanisms like interrupts or other tasks.  The
> + * Beacon is available for every task similar to the Events.
> + *
> + * @msc
> + *   hscale="1.6";
> + *   M [label="Main Task"], IDLE [label="Idle Task"], IRQ [label="Interrupt Handler"], TIME [label="System Tick Handler"];
> + *   |||;
> + *   --- [label="sequence with request completion"];
> + *   M box M [label="prepare request\nissue request\ncall rtems_beacon_watch()"];
> + *   M=>>IDLE [label="blocking operation"];
> + *   IDLE=>>IRQ [label="request completion event"];
> + *   IRQ box IRQ [label="finish request\ncall rtems_beacon_signal()"];
> + *   IRQ=>>M [label="task is ready again"];
> + *   M box M [label="clean up request\ncall rtems_beacon_clear()"];
> + *   |||;
> + *   --- [label="sequence with early request completion"];
> + *   M box M [label="prepare request\nissue request"];
> + *   M=>>IRQ [label="request completion event"];
> + *   IRQ box IRQ [label="finish request\ncall rtems_beacon_signal()"];
> + *   IRQ=>>M [label="beacon is now signalled"];
> + *   M box M [label="call rtems_beacon_watch()\nclean up request\ncall rtems_beacon_clear()"];
> + *   |||;
> + *   --- [label="sequence with timeout event"];
> + *   M box M [label="prepare request\nissue request\ncall rtems_beacon_watch()"];
> + *   M=>>IDLE [label="blocking operation"];
> + *   IDLE=>>TIME [label="timeout expired"];
> + *   TIME box TIME [label="cancel blocking operation"];
> + *   TIME=>>M [label="task is ready again"];
> + *   M box M [label="cancel request\ncall rtems_beacon_clear()"];
> + * @endmsc
> + *
> + * Suppose you have a task that wants to issue a certain request and then waits
> + * for request completion.  It can create a request structure and store its
> + * task identifier there.  Now it can place the request on a work queue of
> + * another task (or interrupt handler).  Afterwards the task watches for the
> + * beacon to get signalled.  Once the worker task is finished with the request
> + * it can signal the beacon.
> + *
> + * @code
> + * #include <assert.h>
> + * #include <rtems.h>
> + *
> + * typedef struct {
> + *   rtems_id task_id;
> + *   bool work_done;
> + * } request;
> + *
> + * void worker_task(rtems_task_argument arg)
> + * {
> + *   rtems_status_code sc;
> + *   request *req = (request *) arg;
> + *
> + *   req->work_done = true;
> + *
> + *   sc = rtems_beacon_signal(req->task_id);
> + *   assert(sc == RTEMS_SUCCESSFUL);
> + *
> + *   sc = rtems_task_delete(RTEMS_SELF);
> + *   assert(sc == RTEMS_SUCCESSFUL);
> + * }
> + *
> + * void issue_request_and_wait_for_completion(void)
> + * {
> + *   rtems_status_code sc;
> + *   rtems_id id;
> + *   request req;
> + *
> + *   req.task_id = rtems_task_self();
> + *   req.work_done = false;
> + *
> + *   sc = rtems_task_create(
> + *     rtems_build_name('W', 'O', 'R', 'K'),
> + *     1,
> + *     RTEMS_MINIMUM_STACK_SIZE,
> + *     RTEMS_DEFAULT_MODES,
> + *     RTEMS_DEFAULT_ATTRIBUTES,
> + *     &id
> + *   );
> + *   assert(sc == RTEMS_SUCCESSFUL);
> + *
> + *   sc = rtems_task_start(id, worker_task, (rtems_task_argument) &req);
> + *   assert(sc == RTEMS_SUCCESSFUL);
> + *
> + *   sc = rtems_beacon_watch(RTEMS_WAIT, RTEMS_NO_TIMEOUT);
> + *   assert(sc == RTEMS_SUCCESSFUL);
> + *
> + *   assert(req.work_done);
> + *
> + *   sc = rtems_beacon_clear();
> + *   assert(sc == RTEMS_SUCCESSFUL);
> + * }
> + * @endcode
> + *
> + * @{
> + */


-- 
Sebastian Huber, embedded brains GmbH

Address : Obere Lagerstr. 30, D-82178 Puchheim, Germany
Phone   : +49 89 18 90 80 79-6
Fax     : +49 89 18 90 80 79-9
E-Mail  : sebastian.huber at embedded-brains.de
PGP     : Public key available on request.

Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG.




More information about the devel mailing list