Skip to content

Commit

Permalink
added process priority
Browse files Browse the repository at this point in the history
  • Loading branch information
oppiz committed Mar 7, 2019
1 parent f137664 commit a195ba6
Show file tree
Hide file tree
Showing 4 changed files with 235 additions and 3 deletions.
3 changes: 3 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& SetPriority(string name, int priority);
Manager& SortProcess();

Manager& init();
Manager& start();
Manager& update();
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
43 changes: 43 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 (-5 > process._priority || process._priority > 15 ){
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() {
SortProcess();
return all([](Process& p) { p._init();});
}

Expand All @@ -116,6 +121,44 @@ 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::SortProcess() {

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 name The name of 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::SetPriority(string name, int priority) {

if (-5 <= priority && priority <= 15 ){
//Find process to adjust
auto it = std::find_if(_processes.begin(), _processes.end(), [name](const Process * n) {
return n->_name == name;
});

if (it != _processes.end()) {
(*it)->_priority = priority;
SortProcess();
}else{
throw Exception("Tried to access an unregistered or non-existant process.");
}
}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
186 changes: 186 additions & 0 deletions test/priority.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
#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__))

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");
//std::cout << "james" << "\n";
}
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");
//std::cout << "lilly" << "\n";
}
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");
//std::cout << "boby" << "\n";
}
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.SetPriority("james", 3);
m.init().run(MS(100));
EXPECT_EQ(test1, ans1);

}

TEST(Priority, NoProcess) {


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",0);


m.schedule(james, MS(30));
EXPECT_ANY_THROW(m.SetPriority("jams", 3));
}

TEST(Priority, LookSort) {

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");
//std::cout << "james" << "\n";
}
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");
//std::cout << "lilly" << "\n";
}
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");
//std::cout << "boby" << "\n";
}
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.SetPriority("bob", 23));
}

}

0 comments on commit a195ba6

Please sign in to comment.