Skip to content

Commit

Permalink
Merge pull request #2 from oppiz/master
Browse files Browse the repository at this point in the history
added process priority
  • Loading branch information
klavins authored Mar 11, 2019
2 parents 0429e4a + ba06690 commit 3e225de
Show file tree
Hide file tree
Showing 4 changed files with 256 additions and 3 deletions.
4 changes: 4 additions & 0 deletions include/manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ namespace elma {
Manager& schedule(Process& process, high_resolution_clock::duration period);
Manager& all(std::function<void(Process&)> f);

Manager& set_priority(Process& process, int priority);
Manager& sort_processes();

Manager& init();
Manager& start();
Manager& update();
Expand All @@ -58,6 +61,7 @@ namespace elma {
Client& client() { return _client; }

private:
const int Priority_min = -5, Priority_max = 15;
vector<Process *> _processes;
map<string, Channel *> _channels;
map<string, vector<std::function<void(Event&)>>> event_handlers;
Expand Down
6 changes: 3 additions & 3 deletions include/process.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,13 @@ namespace elma {
typedef enum { UNINITIALIZED, STOPPED, RUNNING } status_type;

//! Default constructor. Names process "no name"
Process() : _name("unnamed process"), _status(UNINITIALIZED), _manager_ptr(NULL) {}
Process(int n = 0) : _name("unnamed process"), _status(UNINITIALIZED), _manager_ptr(NULL), _priority(n) {}

//! Constructor that takes a name for the process
/*!
\param name The name of the process
*/
Process(std::string name) : _name(name), _status(UNINITIALIZED), _manager_ptr(NULL) {}
Process(std::string name, int n = 0) : _name(name), _status(UNINITIALIZED), _manager_ptr(NULL), _priority(n) {}
virtual ~Process() = default;

// Interface for derived classes
Expand Down Expand Up @@ -122,7 +122,7 @@ namespace elma {
_previous_update, // duration from start to update before last
_last_update; // duration from start to last update
time_point<high_resolution_clock> _start_time; // time of most recent start
int _num_updates; // number of times update() has been called
int _num_updates, _priority; // number of times update() has been called
Manager * _manager_ptr; // a pointer to the manager

};
Expand Down
33 changes: 33 additions & 0 deletions src/manager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ namespace elma {
_processes.push_back(&process);
process._manager_ptr = this;

if (Priority_min > process._priority || process._priority > Priority_max ){
throw Exception("Priority must be between -5(low priority) and 15(high priority)");
}

return *this;

}
Expand Down Expand Up @@ -90,6 +94,7 @@ namespace elma {
//! Initialize all processes. Usually called before run()
//! \return A reference to the manager, for chaining
Manager& Manager::init() {
sort_processes();
return all([](Process& p) { p._init();});
}

Expand All @@ -116,6 +121,34 @@ namespace elma {
});
}

//! sort _Processes based on _priority to ensure higher priority process are updated first.
//! \return A reference to the manager, for chaining
Manager& Manager::sort_processes() {

std::sort(_processes.begin(), _processes.end(),[](const Process * lhs, const Process * rhs){
return lhs->_priority > rhs->_priority;
});

return *this;
}

//! Set Process Priority and sort _Processes to ensure higher priority are updated first.
//! Priority may be set -5 (low priority) to 15 (high priority)
//! This should allow priority adjustment while running.
//! \param process The process you want to adjust priority level.
//! \param priority, a integer between -5 and 15
//! \return A reference to the manager, for chaining
Manager& Manager::set_priority(Process& process, int priority) {

if (Priority_min <= priority && priority <= Priority_max ){
process._priority = priority;
sort_processes();
}else{
throw Exception("Priority must be between -5(low priority) and 15(high priority)");
}
return *this;
}

//! Run the manager for the specified amount of time.
//! \param The desired amount of time to run
//! \return A reference to the manager, for chaining
Expand Down
216 changes: 216 additions & 0 deletions test/priority.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
#include <iostream>
#include <vector>
#include <string>
#include "gtest/gtest.h"
#include "elma.h"

namespace {

using namespace elma;
using std::vector;

#define SLEEP(__ms__) std::this_thread::sleep_for(std::chrono::milliseconds(__ms__))
#define MS(__ms__) high_resolution_clock::duration(milliseconds(__ms__))

const int Priority_min = -5, Priority_max = 15;

TEST(Priority, basic) {

static vector<string> test1;
static vector<string> ans1 = {"lilly", "boby", "james", "lilly", "boby", "james", "lilly", "boby", "james" };

class Tester: public elma::Process {
public:
Tester(string name, int n = 0) : Process(name, n) {}
void init() {}
void start() {}
void update() {
test1.push_back("james");
}
void stop() {}

};

class Tester2: public elma::Process {
public:
Tester2(string name, int n = 0) : Process(name, n) {}
void init() {}
void start() {}
void update() {
test1.push_back("lilly");
}
void stop() {}

};

class Tester3: public elma::Process {
public:
Tester3(string name, int n = 0) : Process(name, n) {}
void init() {}
void start() {}
void update() {
test1.push_back("boby");
}
void stop() {}

};



elma::Manager m;
Tester james("james",0);
Tester2 lily("lily", 2);
Tester3 boby("boby", 1);

m.schedule(james, MS(30))
.schedule(lily, MS(30))
.schedule(boby, MS(30));

m.init().run(MS(100));
EXPECT_EQ(test1, ans1);

}

TEST(Priority, SetPriorityMethod) {

static vector<string> test1;
static vector<string> ans1 = {"lilly", "boby", "james", "lilly", "boby", "james", "lilly", "boby", "james" };

class Tester: public elma::Process {
public:
Tester(string name, int n = 0) : Process(name, n) {}
void init() {}
void start() {}
void update() {
test1.push_back("james");
}
void stop() {}

};

class Tester2: public elma::Process {
public:
Tester2(string name, int n = 0) : Process(name, n) {}
void init() {}
void start() {}
void update() {
test1.push_back("lilly");
}
void stop() {}

};

class Tester3: public elma::Process {
public:
Tester3(string name, int n = 0) : Process(name, n) {}
void init() {}
void start() {}
void update() {
test1.push_back("boby");
}
void stop() {}

};



elma::Manager m;
Tester james("james");
Tester2 lily("lily");
Tester3 boby("boby");

m.schedule(james, MS(30))
.schedule(lily, MS(30))
.schedule(boby, MS(30));

m.set_priority(james, 0);
m.set_priority(lily, 2);
m.set_priority(boby, 1);

m.init().run(MS(100));
EXPECT_EQ(test1, ans1);

}


TEST(Priority, LookSort) {

class Tester: public elma::Process {
public:
Tester(string name, int n = 0) : Process(name, n) {}
void init() {}
void start() {}
void update() {}
void stop() {}

};

class Tester2: public elma::Process {
public:
Tester2(string name, int n = 0) : Process(name, n) {}
void init() {}
void start() {}
void update() {}
void stop() {}

};

class Tester3: public elma::Process {
public:
Tester3(string name, int n = 0) : Process(name, n) {}
void init() {}
void start() {}
void update() {}
void stop() {}

};

elma::Manager m;
Tester james("james",0);
Tester2 lily("lily", 2);
Tester3 boby("boby", 1);

m.schedule(james, MS(30))
.schedule(lily, MS(30))
.schedule(boby, MS(60));

vector<string> test2;
vector<string> test3;
vector<string> ans2 = {"james", "lily", "boby"};
vector<string> ans3 = {"lily", "boby", "james"};

//This is pushing correct. By visual inspection
//m.all([test2](Process& p) mutable { test2.push_back(p.name()); });
//EXPECT_EQ(test2, ans2);
m.all([test2](Process& p) mutable { std::cout << p.name() << "\n"; });

m.init().run(MS(100));
//This is pushing correct. By visual inspection
//m.all([test3](Process& p) mutable { test3.push_back(p.name()); });
//EXPECT_EQ(test3, ans3);
m.all([test2](Process& p) mutable { std::cout << p.name() << "\n"; });

}


TEST(Priority, OutOfBounds) {

class Tester: public elma::Process {
public:
Tester(string name, int n = 0) : Process(name, n) {}
void init() {}
void start() {}
void update() {}
void stop() {}

};


elma::Manager m;
Tester james("james",19);
EXPECT_ANY_THROW( m.schedule(james, MS(30)));
Tester bob("bob");
EXPECT_ANY_THROW(m.set_priority(bob, 23));
}

}

0 comments on commit 3e225de

Please sign in to comment.