Revision a3d116e3

View differences:

configure.user
18 18
#    yes -> no NOT use barrier messages
19 19
#    no  -> use barrier messages
20 20
#
21
NOBARRIER=yes
21
NOBARRIER=no
22 22

  
23 23
#
24 24
# In combination with NOBARRIER: Define the cache line size used for aligning
include/cscheduler.h
23 23

  
24 24
#include "cobject.h"
25 25
#include "platdep/timeutil.h"  // for timeval
26
#include "ctaskheap.h"
26 27

  
27 28
NAMESPACE_BEGIN
28 29

  
......
134 135
    virtual cMessage *getNextEvent();
135 136
};
136 137

  
138
/**
139
 * Event Scheduler employing EEF (Earliest Endtime First) Scheduling
140
 *
141
 * @ingroup Internals
142
 */
143
class SIM_API cEEFScheduler : public cScheduler
144
{
145
  private:
146
    cTaskHeap independentEventsHeap;
147
  public:
148
    /**
149
     * Constructor.
150
     */
151
    cEEFScheduler();
152

  
153
    virtual ~cEEFScheduler();
154

  
155
    /**
156
     * Called at the beginning of a simulation run.
157
     */
158
    virtual void startRun() {};
159

  
160
    /**
161
     * Called at the end of a simulation run.
162
     */
163
    virtual void endRun() {};
164

  
165
    /**
166
     * Returns the event with the smallest Ending Time in the Set of offloadable events.
167
     */
168
    virtual cMessage *getNextEvent();
169
    /*
170
     * Returns the event with the smallest Ending Time in the Set of offloadable events
171
     * and removes it from the heap. Or, if the heap is empty, returns the first event of the MsgQueue
172
     */
173
    virtual cMessage* removeNextEvent();
174
};
175

  
137 176

  
138 177
/**
139 178
 * Real-time scheduler class. When installed as scheduler using the scheduler-class
include/cspinningthreadpool.h
132 132
	virtual int waitAtBarrier(int barrierMin,cMessageHeap* msgQueue);
133 133

  
134 134
	/**
135
	 * Returns true if msg is scheduled before the minimal Barrier (barrierMin).
136
	 * Returns false otherwise.
137
	 */
138
	virtual bool isBeforeBarrier(int barrierMin, cMessage* msg);
139

  
140
	/**
135 141
	 * Returns true iff there is currently no event being processed (and therefore
136 142
	 * no pseudo barrier message active.
137 143
	 */
src/sim/cscheduler.cc
27 27
#include "cconfiguration.h"
28 28
#include "cconfigoption.h"
29 29
#include "platmisc.h" // usleep
30
#include "cbarriermessage.h"
30 31

  
31 32
USING_NAMESPACE
32 33

  
......
98 99
}
99 100

  
100 101
//-----
102
Register_Class(cEEFScheduler)
103
;
101 104

  
105
cEEFScheduler::cEEFScheduler()
106
{
107
}
108
cEEFScheduler::~cEEFScheduler()
109
{
110
}
111

  
112
cMessage *cEEFScheduler::getNextEvent()
113
{
114
#ifdef NOBARRIER
115
    //
116
    // If we retrieve a valid msg from the queue, we return it:
117
    //
118
    cMessage *msg = sim->msgQueue.peekFirst();
119
    if (msg)
120
    return msg;
121

  
122
    //
123
    // if there is no event left and we don't use the threadpool, end the sim
124
    //
125
    if (!sim->threadPool)
126
    throw cTerminationException(eENDEDOK);
127

  
128
    //
129
    // If we did not get a valid msg from the queue, but there are still
130
    // barrier messages left, we wait:
131
    //
132
    while (sim->msgQueue.empty() && !sim->threadPool->barrierEmpty())
133
    {
134
        __asm__ ("pause");
135
    }
136
    msg = sim->msgQueue.peekFirst();
137

  
138
    //
139
    // If there is a msg now, we return it:
140
    //
141
    if (msg)
142
    return msg;
143

  
144
    //
145
    // If there is still no message in the queue, there are
146
    // also no barriers left (else we would have waited), and we quit:
147
    //
148

  
149
    else
150
    throw cTerminationException(eENDEDOK);
151

  
152
#else
153
    cMessage *msg;
154
    cBarrierMessage* barrier;
155
    while (!sim->msgQueue.empty())
156
    {
157
        msg = sim->msgQueue.peekFirst();
158
        barrier = dynamic_cast<cBarrierMessage*> (msg);
159
        if (barrier != NULL)
160
        {
161
            return independentEventsHeap.empty() ? msg
162
                    : independentEventsHeap.peekFirst();
163
        }
164
        independentEventsHeap.insert(sim->msgQueue.removeFirst());
165
    }
166
    if (independentEventsHeap.empty()) {
167
        throw cTerminationException(eENDEDOK);
168
    }
169
    return independentEventsHeap.peekFirst();
170
#endif
171
}
172

  
173
cMessage* cEEFScheduler::removeNextEvent() {
174
    printf ("Test");
175
    return independentEventsHeap.empty() ? sim->msgQueue.removeFirst() : independentEventsHeap.getFirst();
176
}
177

  
178
//-----
102 179
Register_Class(cRealTimeScheduler);
103 180

  
104 181
void cRealTimeScheduler::startRun()
src/sim/csimulation.cc
107 107
    take(&msgQueue);
108 108

  
109 109
    // install a default scheduler
110
    setScheduler(new cSequentialScheduler());
110
    setScheduler(new cEEFScheduler());
111 111
}
112 112

  
113 113
cSimulation::~cSimulation()
......
685 685
            barrierMin = threadPool->waitAtBarrier(barrierMin, &msgQueue);
686 686
        }
687 687
#endif
688

  
688
#ifdef NOBARRIER
689 689
        // Event is free for scheduling => Remove it from the queue.
690 690
        msg = msgQueue.removeFirst();
691

  
691
#else
692
        msg = ((cEEFScheduler*)schedulerp)->removeNextEvent();
693
#endif
692 694
#ifdef NOBARRIER
693 695
        // Update mod pointer:
694 696
        mod = (cSimpleModule*) simulation.vect[msg->getArrivalModuleId()];
src/sim/cspinningthreadpool.cc
206 206

  
207 207
    } while (true);
208 208
}
209

  
210 209
#undef BARRIERVALID
211 210

  
211
bool cSpinningThreadPool::isBeforeBarrier(int barrierMin, cMessage* msg) {
212
    return (barrierMin >= 0 && threadStates[barrierMin*SPACING] < *msg);
213
}
212 214

  
213 215
Register_PerRunConfigOption(CFGID_SPINNING_THREADPOOL_THREAD_POOL_SIZE, "thread-pool-size", CFG_INT, "5", "Number of worker threads");
214 216
Register_PerRunConfigOption(CFGID_SPINNING_THREADPOOL_USE_MAIN_THREAD, "use-main-thread", CFG_BOOL, "false", "Use the Main Thread as a workerthread also");

Also available in: Unified diff