Imagix 4D User Guide


Event Calls in Tasks

Along with the Event Transition Between Tasks report, the Event Calls in Tasks report is used to check the use of events for synchronization in multi-tasking systems.

Both reports require that your event mechanism first be identified, as this is not explicit in C/C++ programs. Both the event functions and the events themselves are specified through the Event Definitions dialog. The events are those source code level identifiers (macros, enumeration literals, and constant variables) for the operating system shared resources that are used in event communications. The event functions are those operating system-specific functions used to wait for (pend) an event, to post an event (have the current task provide access to the shared resource), and to clear an event (remove any available postings for the event so that all tasks will again have to wait). The clear event function is assumed to be a variation of the post event function, where a special parameter value dictates that a clear rather than a post take place.

Consider the following simple example where taskX signals taskY that it can now begin its activities:

#define EVENTA 1

extern void PostEvent(int event);
extern void WaitEvent(int event);

void taskX() {
   // gets started on interrupt, set things up
   PostEvent(EVENTA);
}

void taskY() {
   while (1) {
    WaitEvent(EVENTA);
    // do follow on work
   }
}

The Event Calls in Tasks report shows which tasks make calls to the event functions. These are organized by event identifier. This information can be used to confirm that each event is being used to synchronize to correct set of tasks, that the event is not being over or under communicated.

Event Calls in Tasks

Key:
        P:                task posts this event
        W:                task waits for this event
        C:                task clears this event

Settings:
        Wait event function:       WaitEvent
        Post event function:       PostEvent
        Number of events defined:  1
                                   

Task Definitions
Tasks are from User Defined Tasks
Name        Members  Graph  Root
taskX             2    [+]  taskX
taskY             2    [+]  taskY

Event                                             File
          Task
             Line Number of Usage
                  Action
                    User of Event

EVENTA                                            events_simple.c
          taskX
                8 P taskX
          taskY
               13 W taskY

Here's a more complex example, involving several tasks and using multiple events for signalling. The example also shows how the data flow analysis supports value propogation and expression interpretation, along with some special case event posts.

// Events
#define EVENT1 1
#define EVENT2 2
#define EVENT3 4
#define EVENT4 8

void PostEvent(int event, int mode);
void WaitEvent(int event);

#define POSTMODE 1   // regular post
#define OS_FLAG_CLR 2  // clear posted events

void task1() {
    PostEvent(EVENT1, POSTMODE);
    // ignore because of OS_FLAG_CLR
    PostEvent(~(EVENT4|EVENT2), OS_FLAG_CLR);  
}

void task2() {
    WaitEvent(EVENT1);
}

void task3_f1(int p) {
    int event;
    if (p == 13) event = EVENT2;
        else event = EVENT4;
    if (p) {
        PostEvent(event, POSTMODE);   // local var with direct assigns
    } else {
        WaitEvent(EVENT3);
    }
}

void task3() {
    int b = 2;
    if (b)
    while (b--)
        task3_f1(b);
    WaitEvent(EVENT2);
}

// more complicated event expression
int pevents = ~0;
void task4() {
    if (pevents & EVENT4)
        pevents &= ~EVENT1;
    else
        pevents &= ~(EVENT1 | EVENT3);
    PostEvent(pevents, POSTMODE);
    int wevents = EVENT1 | EVENT3 | EVENT4;
    if (pevents)
        wevents &= ~EVENT1;
    WaitEvent(wevents);
}

#define MULTI_EVENT1 (EVENT1 | EVENT3)
#define MULTI_EVENT2 (MULTI_EVENT1 | EVENT2)

void task5() {
    int c = 3;
    int event = EVENT4;
    if (c == 13) event |= MULTI_EVENT1;
    if (c) {
        PostEvent(event, POSTMODE);  // local variable with some expression
    }else {
        WaitEvent(MULTI_EVENT2);
    }
 }

// using arrays for event expressions
static const int execDefaultCallbackEvents[] =
{   // indexed by task id: must correspond to task id's defined in "tasks.h"
    EVENT1,           // SUPERVISOR task - default callback event
    NULL,                           // DISK       task - none
    NULL,                           // XFER       task - none
    NULL,                           // HOST       task - none
    NULL,                           // EXEC       task - none
    EVENT4               // BACKGROUND task - default callback event
};
void task6() {
    int taskid = 0;
    WaitEvent(execDefaultCallbackEvents[taskid]);
};

The report generated for this example tracks all use of events for inter-task communication, resolving the use of events in complex expressions.

Event Calls in Tasks

Key:
        P:                task posts this event
        W:                task waits for this event
        C:                task clears this event

Settings:
        Post event function:       PostEvent
        Wait event function:       WaitEvent
        Number of events defined:  4
                                   

Task Definitions
Tasks are from User Defined Tasks
Name        Members  Graph  Root
Task1             2    [+]  task1
Task2             2    [+]  task2
Task3             4    [+]  task3
Task4             3    [+]  task4
Task5             3    [+]  task5
Task6             2    [+]  task6

Event                                             File
          Task
             Line Number of Usage
                  Action
                    User of Event

EVENT1                                            events_comm.c
          Task1
               17 P task1
          Task2
               23 W task2
          Task5
               67 P task5
               69 W task5
          Task6
               85 W task6

EVENT2                                            events_comm.c
          Task1
               19 P task1
          Task3
               42 W task3
               31 P task3_f1
          Task4
               52 P task4
          Task5
               69 W task5

EVENT3                                            events_comm.c
          Task3
               33 W task3_f1
          Task4
               56 W task4
          Task5
               67 P task5
               69 W task5

EVENT4                                            events_comm.c
          Task1
               19 P task1
          Task3
               31 P task3_f1
          Task4
               52 P task4
               56 W task4
          Task5
               67 P task5
          Task6
               85 W task6