Project

General

Profile

Revision f40e1183

IDf40e118385356debad57b2a0d87b9c59f14952ac

Added by Georg Kunz about 9 years ago

[core] cleanup of execution state handling within casynchmodule

View differences:

include/casyncmodule.h
46 46
class SIM_API cAsyncModule : public cSimpleModule
47 47
{
48 48
  private:
49
    // the module is idling, i.e., no event is current executed
50
    static const AO_t idleExecution = 0;
51 49

  
52
    // the module is currently executing a synchronous event
53
    static const AO_t syncExecution = 1;
54

  
55
    // the module is currently executing an asynchronous event
56
    static const AO_t asyncExecution = 2;
50
    // the two different execution states: either handleMessage is called
51
    // synchronously by the scheduler or asynchronously (to the scheduler)
52
    // by a worker thread
53
    enum ExecutionStates
54
    {
55
        synchronous,
56
        asynchronous
57
    };
57 58

  
58
    // keeps the current state of the module
59
    AO_t execState;
59
    // current state of execution
60
    ExecutionStates executionState;
60 61

  
61 62
    // new messages may only be scheduled with timestamps >= this value
62 63
    simtime_t t_end;
......
73 74
    // flag indicating that a thread is processing an event within this module
74 75
    AO_t busy;
75 76

  
77
    // how many messages did a given event send?
78
    unsigned int sentMessageCount;
79

  
80
    /**
81
     * update meta data needed for event execution
82
     */
83
    void prepareHandleMessage(cMessage* msg);
76 84

  
77 85
  protected:
78 86
    // the central number generator of this module
src/sim/casyncmodule.cc
34 34
cAsyncModule::cAsyncModule(const char *name, cModule *parent, unsigned stacksize) :
35 35
		t_end(0.0)
36 36
{
37
    AO_store(&execState, 0);
38

  
39 37
    //
40 38
	// how many local random number generators do we need? This should become a
41 39
	// special parameter of every asyncmodule. Not yet implemented.
......
75 73
    //
76 74
    // check current state
77 75
    //
78
    AO_t currentState = AO_load_acquire(&execState);
79
    if (currentState == asyncExecution)
76
    if (executionState == asynchronous)
80 77
    {
81 78
        if (msg==NULL)
82 79
          throw cRuntimeError("scheduleAt(): message pointer is NULL");
......
105 102
void cAsyncModule::callHandleAsyncMessage(cMessage* msg)
106 103
{
107 104
    //
108
    // check if an event is being processed currently
105
    // set execution state
109 106
    //
110
    AO_t oldState, newState;
111
    AO_store_write(&newState, asyncExecution);
112
    AO_store_write(&oldState, idleExecution);
113

  
114
    int res = AO_compare_and_swap_full(&execState, oldState, newState);
115
    if (res == 0)
116
    {
117
        throw cRuntimeError(this, "Race condition detected: Cannot process "
118
                                      "asynchronous event - already processing "
119
                                      "event in module %s", this->getName());
120
    }
107
    executionState = asynchronous;
121 108

  
122 109
    //
123
    // set some internal state
124
    //
125
    t_end = msg->getArrivalTime() + msg->getEventDuration();
126 110
    // set the simtime for this event
127 111
    //
128 112
    cThreadPool::setSimTime(msg->getArrivalTime());
......
130 114
    cThreadPool::setContext(this);
131 115
    cThreadPool::setDefaultOwner(this);
132 116

  
133
    // take ownership of the message only after the test above
134
    this->take(msg);
117
    //
118
    // update meta data
119
    //
120
    prepareHandleMessage(msg);
135 121

  
136 122
    //
137 123
    // call the actual method
138 124
    //
139 125
    handleMessage(msg);
140

  
141
    AO_store_release(&execState, idleExecution);
142

  
143 126
}
144 127

  
145 128

  
146 129
void cAsyncModule::callHandleMessage(cMessage* msg)
147 130
{
148 131
    //
149
    // check if an event is being processed currently
132
    // set execution state
150 133
    //
151
    AO_t oldState, newState;
152
    AO_store_write(&newState, syncExecution);
153
    AO_store_write(&oldState, idleExecution);
134
    executionState = synchronous;
154 135

  
155
    int res = AO_compare_and_swap_full(&execState, oldState, newState);
156
    if (res == 0)
157
    {
158
        throw cRuntimeError(this, "Race condition detected: Cannot process "
159
                                      "synchronous event - already processing "
160
                                      "event in module %s", this->getName());
161
    }
136
    //
137
    // update meta data
138
    //
139
    prepareHandleMessage(msg);
162 140

  
141
    //
142
    // call the actual method
143
    //
144
    handleMessage(msg);
145
}
146

  
147

  
148
void cAsyncModule::prepareHandleMessage(cMessage* msg)
149
{
150
    //
151
    // set some internal state
152
    //
163 153
    t_end = msg->getArrivalTime() + msg->getEventDuration();
164 154

  
155

  
165 156
    //
166 157
    // take ownership of the message only after the test above
167 158
    //
168 159
    this->take(msg);
169 160

  
170 161
    //
171
    // call the actual method
162
    // reset message counter
172 163
    //
173
    handleMessage(msg);
174

  
175
    AO_store_release(&execState, idleExecution);
164
    sentMessageCount = 0;
176 165
}
177 166

  
178

  
179 167
int cAsyncModule::send(cMessage *msg, int gateid)
180 168
{
181 169
    return sendDelayed(msg, 0.0, gateid);
......
222 210
    //
223 211
    // check current state
224 212
    //
225
    AO_t currentState = AO_load_acquire(&execState);
226
    if (currentState == asyncExecution)
213
    if (executionState == asynchronous)
227 214
    {
228 215
        //
229 216
        // error checking, omit ownership checks if it breaks
......
321 308
    //
322 309
    // check current state
323 310
    //
324
    AO_t currentState = AO_load_acquire(&execState);
325
    if (currentState == asyncExecution)
311
    if (executionState == asynchronous)
326 312
    {
327 313
        //
328 314
        // error checking
......
373 359

  
374 360
        msg->setSentFrom(this, -1, time);
375 361

  
376

  
377

  
378 362
        bool keepit = togate->deliver(msg, time + delay);
379 363
        if (!keepit)
380 364
                delete msg;

Also available in: Unified diff