diff --git a/ch1/Makefile b/ch1/Makefile index 66b434d..94d66da 100644 --- a/ch1/Makefile +++ b/ch1/Makefile @@ -1,4 +1,4 @@ -CPP = g++-4.8 +CPP = g++ CPPFLAGS = -g -std=c++0x OFLAG = -o .SUFFIXES : .o .cpp .c diff --git a/ch3/Makefile b/ch3/Makefile new file mode 100644 index 0000000..63b66f3 --- /dev/null +++ b/ch3/Makefile @@ -0,0 +1,22 @@ +CPP = g++ +CPPFLAGS = -g -std=c++0x +OFLAG = -o +.SUFFIXES : .o .cpp .c +.cpp.o : + $(CPP) $(CPPFLAGS) -c $< +.c.o : + $(CPP) $(CPPFLAGS) -c $< + +PROGS = stack hierarchical + +all: $(PROGS) + +stack: stack.o + $(CPP) $(OFLAG) stack stack.o -lpthread + +hierarchical: hierarchical.o + $(CPP) $(OFLAG) hierarchical hierarchical.o -lpthread + +clean: + rm -f ${PROGS} *.o + diff --git a/ch3/hierarchical.cpp b/ch3/hierarchical.cpp new file mode 100644 index 0000000..4e4f2a2 --- /dev/null +++ b/ch3/hierarchical.cpp @@ -0,0 +1,57 @@ +#include +#include +#include + +class hierarchical_mutex +{ + std::mutex internal_mutex; + unsigned long const hierarchy_value; + unsigned long previous_hierarchy_value; + static thread_local unsigned long this_thread_hierarchy_value; + + void check_for_hierarchy_violation() + { + if(this_thread_hierarchy_value <= hierarchy_value) + { + throw std::logic_error("mutex hierarchy violated"); + } + } + void update_hierarchy_value() + { + previous_hierarchy_value=this_thread_hierarchy_value; + this_thread_hierarchy_value=hierarchy_value; + } +public: + explicit hierarchical_mutex(unsigned long value): + hierarchy_value(value), + previous_hierarchy_value(0) + {} + void lock() + { + check_for_hierarchy_violation(); + internal_mutex.lock(); + update_hierarchy_value(); + } + void unlock() + { + this_thread_hierarchy_value=previous_hierarchy_value; + internal_mutex.unlock(); + } + bool try_lock() + { + check_for_hierarchy_violation(); + if(!internal_mutex.try_lock()) + return false; + update_hierarchy_value(); + return true; + } +}; +thread_local unsigned long + hierarchical_mutex::this_thread_hierarchy_value(ULONG_MAX); + +int main() +{ + hierarchical_mutex m1(42); + hierarchical_mutex m2(2000); + +} diff --git a/ch3/stack.cpp b/ch3/stack.cpp new file mode 100644 index 0000000..5afbcf7 --- /dev/null +++ b/ch3/stack.cpp @@ -0,0 +1,68 @@ +#include +#include +#include +#include + +struct empty_stack: std::exception +{ + const char* what() const throw() + { + return "empty stack"; + } + +}; + +template +class threadsafe_stack +{ +private: + std::stack data; + mutable std::mutex m; +public: + threadsafe_stack(){} + threadsafe_stack(const threadsafe_stack& other) + { + std::lock_guard lock(other.m); + data=other.data; + } + threadsafe_stack& operator=(const threadsafe_stack&) = delete; + + void push(T new_value) + { + std::lock_guard lock(m); + data.push(new_value); + } + std::shared_ptr pop() + { + std::lock_guard lock(m); + if(data.empty()) throw empty_stack(); + std::shared_ptr const res(std::make_shared(data.top())); + data.pop(); + return res; + } + void pop(T& value) + { + std::lock_guard lock(m); + if(data.empty()) throw empty_stack(); + value=data.top(); + data.pop(); + } + bool empty() const + { + std::lock_guard lock(m); + return data.empty(); + } +}; + +int main() +{ + threadsafe_stack si; + si.push(5); + si.pop(); + if(!si.empty()) + { + int x; + si.pop(x); + } + +}