commit 6d6980332ac6d3d84bead7d14240848b0fba4865 Author: Hannes Kuchelmeister Date: Tue Nov 24 21:11:46 2020 +0100 Bolier plate for C++ project added diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5da8ffc --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +*/* +!*/*.cpp +!*/*.h +!.gitignore \ No newline at end of file diff --git a/Assignment_1/adt_set.cpp b/Assignment_1/adt_set.cpp new file mode 100644 index 0000000..557f13e --- /dev/null +++ b/Assignment_1/adt_set.cpp @@ -0,0 +1,110 @@ +#include +#include +#include +#include +#include + +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 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(); + } +} \ No newline at end of file diff --git a/Assignment_1/concurrent_set.cpp b/Assignment_1/concurrent_set.cpp new file mode 100644 index 0000000..4445caf --- /dev/null +++ b/Assignment_1/concurrent_set.cpp @@ -0,0 +1,80 @@ +#include +//#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 "<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; +} \ No newline at end of file diff --git a/Assignment_1/helper_code.cpp b/Assignment_1/helper_code.cpp new file mode 100644 index 0000000..8ff303c --- /dev/null +++ b/Assignment_1/helper_code.cpp @@ -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 +#include + +#include"adt_set.cpp" + +using namespace std; + +ADT_Set adt_set = ADT_Set(); + +void worker_func(int num, operation test_case[]){ + cout<<"Worker "< +#include +#include +#include +#include +#include +//#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 done_queue = queue(); +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 "<