Bläddra i källkod

Initial revision of MultiTasker from Pete.


git-svn-id: https://svn.microneil.com/svn/CodeDweller/branches/adeniz_1@102 d34b734f-a00e-4b39-a726-e4eeb87269ab
adeniz_1
adeniz 9 år sedan
förälder
incheckning
2cc85b9b53
3 ändrade filer med 249 tillägg och 0 borttagningar
  1. 27
    0
      multitasking.cpp
  2. 46
    0
      multitasking.hpp
  3. 176
    0
      multitaskingExample.cpp

+ 27
- 0
multitasking.cpp Visa fil

@@ -0,0 +1,27 @@
// multitasking.cpp
// Copyright 2015 MicroNeil Research Corporation

#include "multitasking.hpp"

void MultiTasker::processBatch(size_t n, MultiTaskQueue& q, bool StopOnWait) {
size_t batchSize = n;
while(batchSize--) {
MultiTask& t = q.get();
switch(t.task()) {
case Running: { working.put(t); break; }
case Waiting: { waiting.put(t); if(StopOnWait) return; break; }
case Finished: { finished.put(t); break; }
}
}
}

MultiTaskState MultiTasker::task() {
size_t workingBatchSize = working.size();
size_t waitingBatchSize = waiting.size();
processBatch(workingBatchSize, working);
processBatch(waitingBatchSize, waiting, true);

if(false == working.empty()) { return Running; }
else if (false == waiting.empty()) { return Waiting; }
else { return Finished; }
}

+ 46
- 0
multitasking.hpp Visa fil

@@ -0,0 +1,46 @@
#ifndef M_MultiTasking
#define M_MultiTasking

#include <cstddef>
#include <queue>

enum MultiTaskState {Running, Waiting, Finished};

class MultiTask {
public:
virtual MultiTaskState task() = 0;
};

class MultiTaskQueue : public std::queue<MultiTask*> {
public:

void put(MultiTask& T) { push(&T); }
MultiTask& get() { MultiTask& T = *(front()); pop(); return T; }

};

class MultiTasker : public MultiTask {
private:
void processBatch(size_t n, MultiTaskQueue& q, bool StopOnWait = false);

public:
MultiTaskQueue working;
MultiTaskQueue waiting;
MultiTaskQueue finished;
MultiTaskState task();

bool isReady() { return (false == working.empty()); }
bool isWaiting() { return (false == waiting.empty() && true == working.empty()); }
bool isFinished() { return (true == working.empty() && true == waiting.empty()); }
bool hasWork() { return (false == isFinished()); }

size_t completed() { return finished.size(); }
size_t pending() { return (working.size() + waiting.size()); }
size_t total() { return (working.size() + waiting.size() + finished.size()); }

void put(MultiTask& t) { working.put(t); }
MultiTask& get() { return finished.get(); }
bool canGet() { return (false == finished.empty()); }
};

#endif // M_MultiTasking

+ 176
- 0
multitaskingExample.cpp Visa fil

@@ -0,0 +1,176 @@
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
#include <cstdlib>
#include "../CodeDweller/timing.hpp"
#include "multitasking.hpp"

using namespace std;

class TaskHistory : public vector<string> {
public:
void post(string stuff) {
push_back(stuff);
}
};

string makeProgressMessage(int m) {
stringstream messageBuilder;
messageBuilder << "Making Progress (" << m << ")";
return messageBuilder.str();
}

class TestTask : public MultiTask {
private:
string myName;
TaskHistory& myHistory;
Timeout myReadyTimeout;

MultiTaskState task() {
if(false == myReadyTimeout.isExpired()) return Waiting;
int myChangedMind = rand() % 100;
MultiTaskState myNewState = Running;
switch(myChangedMind) {
case 0: {
myHistory.post("I'm Finished!");
myNewState = Finished;
break;
}

case 1:
case 3:
case 5:
case 51:
case 53:
case 55:
case 71:
case 73:
case 75:
case 9: {
myHistory.post("I need a nap...");
myReadyTimeout.restart();
myNewState = Waiting;
break;
}

default: {
myHistory.post(makeProgressMessage(myChangedMind));
myNewState = Running;
break;
}
}
return myNewState;
}

static const int napDuration = 10;

public:

TestTask(string theName, TaskHistory& theHistory) :
myName(theName),
myHistory(theHistory),
myReadyTimeout(napDuration) {
}

string name() { return myName; }

};

void outputHistory(TaskHistory& H) {
for(vector<string>::iterator s = H.begin(); s != H.end(); ++s) {
cout << *s << endl;
}
}

int main() {
unsigned long seed = 1234;
srand(seed);
cout << "MultiTasker Demo! seed(" << seed << ")" << endl;

TaskHistory H0, H1, H2, H3, H4, H5, H6, H7, H8, H9;
TestTask T0("Random Job 0", H0);
TestTask T1("Random Job 1", H1);
TestTask T2("Random Job 2", H2);
TestTask T3("Random Job 3", H3);
TestTask T4("Random Job 4", H4);
TestTask T5("Random Job 5", H5);
TestTask T6("Random Job 6", H6);
TestTask T7("Random Job 7", H7);
TestTask T8("Random Job 8", H8);
TestTask T9("Random Job 9", H9);

MultiTasker M0;
M0.put(T0); cout << "Pending Count: " << M0.pending() << endl;
M0.put(T1); cout << "Pending Count: " << M0.pending() << endl;
M0.put(T2); cout << "Pending Count: " << M0.pending() << endl;
M0.put(T3); cout << "Pending Count: " << M0.pending() << endl;
M0.put(T4); cout << "Pending Count: " << M0.pending() << endl;
M0.put(T5); cout << "Pending Count: " << M0.pending() << endl;
M0.put(T6); cout << "Pending Count: " << M0.pending() << endl;
M0.put(T7); cout << "Pending Count: " << M0.pending() << endl;
M0.put(T8); cout << "Pending Count: " << M0.pending() << endl;
M0.put(T9); cout << "Pending Count: " << M0.pending() << endl;

PollTimer NothingToDo(10,50);

while(M0.hasWork()) {
M0.task();
cout
<< "In Work: " << M0.pending()
<< ", Working: " << M0.working.size()
<< ", Waiting: " << M0.waiting.size()
<< ", Finished: " << M0.finished.size();

if(M0.isReady()) {
cout << endl;
NothingToDo.reset();
}
else if(M0.isWaiting()) {
cout << " pause..." << endl;
NothingToDo.pause();
}
}

cout << endl << endl << "M0 Complete Order..." << endl;
bool firstT = true;
while(M0.canGet()) {
TestTask& T = (TestTask&) M0.get();
if(firstT) { firstT = false; }
else { cout << ", "; }
cout << T.name();
}

cout << endl << endl << "T0(" << T0.name() << ") History..." << endl;
outputHistory(H0);

cout << endl << endl << "T1(" << T1.name() << ") History..." << endl;
outputHistory(H1);

cout << endl << endl << "T2(" << T2.name() << ") History..." << endl;
outputHistory(H2);

cout << endl << endl << "T3(" << T3.name() << ") History..." << endl;
outputHistory(H3);

cout << endl << endl << "T4(" << T4.name() << ") History..." << endl;
outputHistory(H4);

cout << endl << endl << "T5(" << T5.name() << ") History..." << endl;
outputHistory(H5);

cout << endl << endl << "T6(" << T6.name() << ") History..." << endl;
outputHistory(H6);

cout << endl << endl << "T7(" << T7.name() << ") History..." << endl;
outputHistory(H7);

cout << endl << endl << "T8(" << T8.name() << ") History..." << endl;
outputHistory(H8);

cout << endl << endl << "T9(" << T9.name() << ") History..." << endl;
outputHistory(H9);

return 0;
}


Laddar…
Avbryt
Spara