Bolier plate for C++ project added

This commit is contained in:
2020-11-24 21:11:46 +01:00
commit 6d6980332a
6 changed files with 458 additions and 0 deletions

110
Assignment_1/adt_set.cpp Normal file
View File

@@ -0,0 +1,110 @@
#include<iostream>
#include<set>
#include<stdexcept>
#include <sstream>
#include <stdlib.h>
using namespace std;
enum methodname {add, rmv, ctn};
typedef struct _operation{
//blah blah blah
methodname method;
int input;
bool output;
} operation;
class ADT_Set {
std::set<int> set;
public:
ADT_Set();
void do_op(operation *op);
void add(int element, bool output);
void rmv(int element, bool output);
void ctn(int element, bool output);
};
ADT_Set::ADT_Set() {
set = { };
}
void ADT_Set::do_op(operation *op) {
switch (op->method) {
case methodname::add:
add(op->input, op->output);
break;
case methodname::rmv:
rmv(op->input, op->output);
break;
case methodname::ctn:
ctn(op->input, op->output);
break;
//default:
// throw invalid_argument("Uknown operation");
}
}
void ADT_Set::add(int element, bool output){
bool elem_in_set = set.find(element) != set.end();
// Element in set -> output must be false
// Element not in set - > output must be true
if(elem_in_set != output) {
set.insert(element);
} else {
std::ostringstream oss;
oss << std::boolalpha << "Invalid operation: add " << element << " " << output;
throw invalid_argument(oss.str());
}
}
void ADT_Set::rmv(int element, bool output){
bool elem_in_set = set.find(element) != set.end();
// Element in set -> output must be true
// Element not in set - > output must be false
if(elem_in_set == output) {
set.erase(element);
} else {
std::ostringstream oss;
oss << std::boolalpha << "Invalid operation: rmv " << element << " " << output;
throw invalid_argument(oss.str());
}
}
void ADT_Set::ctn(int element, bool output){
bool elem_in_set = set.find(element) != set.end();
// Element in set -> output must be true
// Element not in set - > output must be false
if(elem_in_set != output) {
std::ostringstream oss;
oss << std::boolalpha << "Invalid operation: ctn " << element << " " << output;
throw invalid_argument(oss.str());
}
}
operation create_random_operation() {
methodname method;
switch (rand() % 2) {
case 0:
method = methodname::add;
break;
case 1:
method = methodname::rmv;
break;
default:
method = methodname::ctn;
break;
}
int element = rand() % 10;
return {
.method = method, .input = element, .output = NULL
};
}
void fill_with_operations(operation * arr, int arr_size) {
int arrSize = arr_size;
for (int i = 0; i < arrSize; i++) {
arr[i] = create_random_operation();
}
}

View File

@@ -0,0 +1,80 @@
#include <mutex>
//#include"set.cpp"
//#include"adt_set.cpp"
class ConcurrentSet {
Set cset;
std::mutex cmut;
public:
ConcurrentSet();
bool do_op(methodname method, int input);
bool add(int element);
bool rmv(int element);
bool ctn(int element);
};
ConcurrentSet::ConcurrentSet(){
cset = Set();
}
bool ConcurrentSet::do_op(methodname method, int input){
switch (method) {
case methodname::add:
return add(input);
case methodname::rmv:
return rmv(input);
break;
case methodname::ctn:
return ctn(input);
default:
throw std::invalid_argument("Uknown operation");
}
}
bool ConcurrentSet::add(int element) {
bool res;
cmut.lock();
res = cset.add(element);
cmut.unlock();
return res;
}
bool ConcurrentSet::rmv(int element) {
bool res;
cmut.lock();
res = cset.rmv(element);
cmut.unlock();
return res;
}
bool ConcurrentSet::ctn(int element) {
bool res;
cmut.lock();
res = cset.ctn(element);
cmut.unlock();
return res;
}
void conc_worker_func(int num, operation * test_case, int test_case_count, int worker_count){//note that arrays are passed as pointers
int arrSize = test_case_count;
for (int i = 0; i < arrSize; i++) {
q_mutex.lock();
bool output = worker_set.do_op(test_case[i].method, test_case[i].input);
done_queue.push({ .method = test_case[i].method, .input = test_case[i].input, .output = output});
q_mutex.unlock();
}
q_mutex.lock();
done_count += 1;
cout<<"Worker "<<num<<endl;
q_mutex.unlock();
}
int test_concurrent_set() {
ConcurrentSet* s = new ConcurrentSet;
assert(!s->rmv(1));
assert(!s->ctn(1));
assert(s->add(1));
assert(!s->add(1));
assert(s->ctn(1));
assert(s->rmv(1));
assert(!s->ctn(1));
return 1;
}

View File

@@ -0,0 +1,41 @@
/**** This is a helper/skeleton code for the assignment ****/
/**** Author: Sarbojit Das ****/
/**** Compile using command g++ simple_thread.cpp -lpthread ****/
#include<iostream>
#include<thread>
#include"adt_set.cpp"
using namespace std;
ADT_Set adt_set = ADT_Set();
void worker_func(int num, operation test_case[]){
cout<<"Worker "<<num<<endl;
}
void monitor_func(operation test_case[]){
//blah blah blah
cout<<"Monitor"<<endl;
}
int main(){
int N_Threads = 3;
thread *worker= new thread[N_Threads];
operation test_case[100];
//fill test_case with your sequence of operations
thread monitor = thread(monitor_func,test_case);
for (int i=0;i<N_Threads;i++){
worker[i]=thread(worker_func,i,test_case);
}
for (int i=0;i<N_Threads;i++){
worker[i].join();
}
monitor.join();
return 0;
}

94
Assignment_1/main.cpp Normal file
View File

@@ -0,0 +1,94 @@
#include"adt_set.cpp"
#include"set.cpp"
#include"concurrent_set.cpp"
#define TEST_CASE_COUNT 1000
enum program {adt_set, test_one_set, one_thread_set, n_thread_set, concurrent_set};
int run_adt_set(){
ADT_Set adt_set = ADT_Set();
operation test_case[6] = {
{ methodname::add, 1, true },
{ methodname::add, 1, false },
{ methodname::ctn, 1, true },
{ methodname::rmv, 1, true },
{ methodname::ctn, 1, false },
{ methodname::rmv, 1, false }
};
for (operation op : test_case) {
adt_set.do_op(&op);
}
return 0;
}
int run_N_thread_set(int N) {
int worker_count = N;
thread *worker= new thread[worker_count];
operation test_case[TEST_CASE_COUNT];
fill_with_operations(test_case, TEST_CASE_COUNT);
thread monitor = thread(monitor_func,test_case, worker_count);
for (int i=0;i<worker_count;i++){
worker[i]=thread(worker_func, i, test_case, TEST_CASE_COUNT, worker_count);
}
for (int i=0;i<worker_count;i++){
worker[i].join();
}
monitor.join();
return 0;
}
int run_one_thread_set() {
return run_N_thread_set(1);
}
int run_N_thread_concurrent_set(int N) {
int worker_count = N;
thread *worker= new thread[worker_count];
operation test_case[TEST_CASE_COUNT];
fill_with_operations(test_case, TEST_CASE_COUNT);
thread monitor = thread(monitor_func, test_case, worker_count);
for (int i=0;i<worker_count;i++){
worker[i]=thread(conc_worker_func, i, test_case, TEST_CASE_COUNT, worker_count);
}
for (int i=0;i<worker_count;i++){
worker[i].join();
}
monitor.join();
return 0;
}
int main(){
program p = program::concurrent_set; // change this
switch (p) {
case program::adt_set:
return run_adt_set();
break;
case program::one_thread_set:
return run_one_thread_set();
break;
case program::n_thread_set:
return run_N_thread_set(4);
break;
case program::test_one_set:
return test_set();
break;
case program::concurrent_set:
return run_N_thread_concurrent_set(2);
break;
}
}

129
Assignment_1/set.cpp Normal file
View File

@@ -0,0 +1,129 @@
#include<iostream>
#include<thread>
#include <algorithm>
#include <queue>
#include <mutex>
#include <assert.h>
//#include"adt_set.cpp"
class Node {
public:
int data;
Node* next;
};
class Set {
Node* first;
public:
Set();
bool do_op(methodname method, int input);
bool add(int element);
bool rmv(int element);
bool ctn(int element);
};
Set::Set(){
first = new Node(); // dummy node;
}
bool Set::do_op(methodname method, int input){
switch (method) {
case methodname::add:
return add(input);
case methodname::rmv:
return rmv(input);
break;
case methodname::ctn:
return ctn(input);
default:
throw std::invalid_argument("Uknown operation");
}
}
bool Set::add(int element) {
bool element_in_list = ctn(element);
if (!element_in_list) {
Node* tmp = new Node();
tmp->data = element;
tmp->next = first->next;
first->next = tmp;
return true;
} else {
return false;
}
}
bool Set::rmv(int element) {
Node* current = first;
Node* prev = first;
while(current != NULL) {
prev = current;
current = current->next;
if (current != NULL && current->data == element) {
prev->next = current->next;
return true;
}
}
return false;
}
bool Set::ctn(int element) {
Node* current = first;
while(current != NULL) {
current = current->next;
if (current != NULL && current->data == element) {
return true;
}
}
return false;
}
std::mutex q_mutex;
std::queue<operation> done_queue = queue<operation>();
int done_count = 0;
Set worker_set = Set();
void worker_func(int num, operation * test_case, int test_case_count, int worker_count){//note that arrays are passed as pointers
int arrSize = test_case_count;
for (int i = 0; i < arrSize; i++) {
bool output = worker_set.do_op(test_case[i].method, test_case[i].input);
q_mutex.lock();
done_queue.push({ .method = test_case[i].method, .input = test_case[i].input, .output = output});
q_mutex.unlock();
}
q_mutex.lock();
done_count += 1;
cout<<"Worker "<<num<<endl;
q_mutex.unlock();
}
void monitor_func(operation test_case[], int worker_count){
ADT_Set adt_set = ADT_Set();
//blah blah blah
bool done = false;
while (!done) {
q_mutex.lock();
if(done_count == worker_count && done_queue.empty()) {
done = true;
} else if(!done_queue.empty()) {
operation op = done_queue.front();
done_queue.pop();
adt_set.do_op(&op);
}
q_mutex.unlock();
}
cout<<"Monitor"<<endl;
}
int test_set() {
Set s = Set();
assert(!s.rmv(1));
assert(!s.ctn(1));
assert(s.add(1));
assert(!s.add(1));
assert(s.ctn(1));
assert(s.rmv(1));
assert(!s.ctn(1));
return 1;
}