diff --git a/.clang-format b/.clang-format
new file mode 100644
index 0000000..3ed6866
--- /dev/null
+++ b/.clang-format
@@ -0,0 +1,104 @@
+Language: Cpp
+# BasedOnStyle: Google
+AccessModifierOffset: -2
+AlignAfterOpenBracket: Align
+AlignConsecutiveAssignments: true
+AlignConsecutiveDeclarations: false
+AlignEscapedNewlines: Right
+AlignOperands: true
+AlignTrailingComments: true
+AllowAllParametersOfDeclarationOnNextLine: true
+AllowShortBlocksOnASingleLine: false
+AllowShortCaseLabelsOnASingleLine: false
+AllowShortFunctionsOnASingleLine: Inline
+AllowShortIfStatementsOnASingleLine: false
+AllowShortLoopsOnASingleLine: true
+AlwaysBreakAfterDefinitionReturnType: None
+AlwaysBreakAfterReturnType: TopLevelDefinitions
+AlwaysBreakBeforeMultilineStrings: true
+AlwaysBreakTemplateDeclarations: true
+BinPackArguments: false
+BinPackParameters: false
+BreakBeforeBraces : Custom
+BraceWrapping:
+ AfterClass: false
+ AfterControlStatement: false
+ AfterEnum: false
+ AfterFunction: true
+ AfterNamespace: false
+ AfterObjCDeclaration: false
+ AfterStruct: false
+ AfterUnion: false
+ BeforeCatch: true
+ BeforeElse: true
+ IndentBraces: false
+ SplitEmptyFunction: true
+ SplitEmptyRecord: true
+ SplitEmptyNamespace: true
+BreakBeforeBinaryOperators: None
+BreakBeforeInheritanceComma: true
+BreakBeforeTernaryOperators: true
+BreakConstructorInitializers: BeforeColon
+BreakAfterJavaFieldAnnotations: false
+BreakStringLiterals: true
+ColumnLimit: 80
+CommentPragmas: '^ IWYU pragma:'
+CompactNamespaces: false
+ConstructorInitializerAllOnOneLineOrOnePerLine: true
+ConstructorInitializerIndentWidth: 4
+ContinuationIndentWidth: 4
+Cpp11BracedListStyle: true
+DerivePointerAlignment: false
+DisableFormat: false
+ExperimentalAutoDetectBinPacking: false
+FixNamespaceComments: true
+ForEachMacros:
+ - foreach
+ - Q_FOREACH
+ - BOOST_FOREACH
+IncludeCategories:
+ - Regex: '^<.*\.h>'
+ Priority: 1
+ - Regex: '^<.*'
+ Priority: 2
+ - Regex: '.*'
+ Priority: 3
+IncludeIsMainRegex: '([-_](test|unittest))?$'
+IndentCaseLabels: false
+IndentWidth: 2
+IndentWrappedFunctionNames: false
+JavaScriptQuotes: Leave
+JavaScriptWrapImports: true
+KeepEmptyLinesAtTheStartOfBlocks: false
+MacroBlockBegin: ''
+MacroBlockEnd: ''
+MaxEmptyLinesToKeep: 1
+NamespaceIndentation: None
+ObjCBlockIndentWidth: 2
+ObjCSpaceAfterProperty: false
+ObjCSpaceBeforeProtocolList: false
+PenaltyBreakAssignment: 2
+PenaltyBreakBeforeFirstCallParameter: 1
+PenaltyBreakComment: 300
+PenaltyBreakFirstLessLess: 120
+PenaltyBreakString: 1000
+PenaltyExcessCharacter: 1000000
+PenaltyReturnTypeOnItsOwnLine: 200
+PointerAlignment: Left
+ReflowComments: true
+SortIncludes: true
+SortUsingDeclarations: true
+SpaceAfterCStyleCast: true
+SpaceAfterTemplateKeyword: true
+SpaceBeforeAssignmentOperators: true
+SpaceBeforeParens: ControlStatements
+SpaceInEmptyParentheses: false
+SpacesBeforeTrailingComments: 2
+SpacesInAngles: false
+SpacesInContainerLiterals: false
+SpacesInCStyleCastParentheses: false
+SpacesInParentheses: false
+SpacesInSquareBrackets: false
+Standard: Cpp11
+TabWidth: 2
+UseTab: Never
diff --git a/.cproject b/.cproject
new file mode 100644
index 0000000..a2780b7
--- /dev/null
+++ b/.cproject
@@ -0,0 +1,114 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.project b/.project
new file mode 100644
index 0000000..4a9287f
--- /dev/null
+++ b/.project
@@ -0,0 +1,27 @@
+
+
+ concurrency-in-action
+
+
+
+
+
+ org.eclipse.cdt.managedbuilder.core.genmakebuilder
+ clean,full,incremental,
+
+
+
+
+ org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder
+ full,incremental,
+
+
+
+
+
+ org.eclipse.cdt.core.cnature
+ org.eclipse.cdt.core.ccnature
+ org.eclipse.cdt.managedbuilder.core.managedBuildNature
+ org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
+
+
diff --git a/.settings/language.settings.xml b/.settings/language.settings.xml
new file mode 100644
index 0000000..8237590
--- /dev/null
+++ b/.settings/language.settings.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ch1/hello.cpp b/ch1/hello.cpp
index 50378c1..9729041 100644
--- a/ch1/hello.cpp
+++ b/ch1/hello.cpp
@@ -1,18 +1,17 @@
#include
#include
-void hello()
+void
+hello()
{
- std::cout << "Hello Concurrent World\n";
+ std::cout << "Hello Concurrent World\n";
}
-int main()
+int
+main()
{
- //boost::thread t([]()
- std::thread t([]()
- {
- std::cout << "Hello Concurrent World\n";
- });
+ // boost::thread t([]()
+ std::thread t([]() { std::cout << "Hello Concurrent World\n"; });
- t.join();
+ t.join();
}
diff --git a/ch2/accumulate.cpp b/ch2/accumulate.cpp
index 372f1fe..f3d5cb2 100644
--- a/ch2/accumulate.cpp
+++ b/ch2/accumulate.cpp
@@ -1,69 +1,69 @@
#include
#include
#include
-#include
+#include // std::accumulate
#include
-#include // std::accumulate
+#include
template
-struct accumulate_block
-{
- void operator()(Iterator first, Iterator last, T& result)
- {
- result = std::accumulate(first,last,result);
- }
+struct accumulate_block {
+ void operator()(Iterator first, Iterator last, T& result)
+ {
+ result = std::accumulate(first, last, result);
+ }
};
template
-T parallel_accumulate(Iterator first, Iterator last, T init)
+T
+parallel_accumulate(Iterator first, Iterator last, T init)
{
- unsigned long const length = std::distance(first,last);
+ unsigned long const length = std::distance(first, last);
- if (!length) return init;
+ if (!length)
+ return init;
- unsigned long const min_per_thread = 25;
- unsigned long const max_threads =
- (length+min_per_thread-1)/min_per_thread;
+ unsigned long const min_per_thread = 25;
+ unsigned long const max_threads =
+ (length + min_per_thread - 1) / min_per_thread;
- unsigned long const hardware_threads =
- std::thread::hardware_concurrency();
+ unsigned long const hardware_threads = std::thread::hardware_concurrency();
- unsigned long const num_threads =
- std::min(hardware_threads != 0 ? hardware_threads:2, max_threads);
+ unsigned long const num_threads =
+ std::min(hardware_threads != 0 ? hardware_threads : 2, max_threads);
- unsigned long const block_size = length / num_threads;
+ unsigned long const block_size = length / num_threads;
- std::vector results(num_threads);
- std::vector threads(num_threads-1);
+ std::vector results(num_threads);
+ std::vector threads(num_threads - 1);
- Iterator block_start = first;
- for (unsigned long i = 0; i < (num_threads-1); ++i)
- {
- Iterator block_end = block_start;
- std::advance(block_end,block_size);
- threads[i] = std::thread(
- accumulate_block(),
- block_start,block_end,std::ref(results[i]));
- block_start = block_end;
- }
- accumulate_block::iterator,int>()(
- block_start,last,results[num_threads-1]);
+ Iterator block_start = first;
+ for (unsigned long i = 0; i < (num_threads - 1); ++i) {
+ Iterator block_end = block_start;
+ std::advance(block_end, block_size);
+ threads[i] = std::thread(accumulate_block(),
+ block_start,
+ block_end,
+ std::ref(results[i]));
+ block_start = block_end;
+ }
+ accumulate_block::iterator, int>()(
+ block_start, last, results[num_threads - 1]);
- std::for_each(threads.begin(),threads.end(),
- std::mem_fn(&std::thread::join));
+ std::for_each(
+ threads.begin(), threads.end(), std::mem_fn(&std::thread::join));
- return std::accumulate(results.begin(),results.end(),init);
+ return std::accumulate(results.begin(), results.end(), init);
}
-int main()
+int
+main()
{
- std::vector numbers(50);
- for (int i = 0; i < 50; ++i) {
- numbers[i] = i;
- }
- int result = parallel_accumulate::iterator,int>
- (numbers.begin(),numbers.end(),0);
+ std::vector numbers(50);
+ for (int i = 0; i < 50; ++i) {
+ numbers[i] = i;
+ }
+ int result = parallel_accumulate::iterator, int>(
+ numbers.begin(), numbers.end(), 0);
- std::cout << "result: " << result << std::endl;
+ std::cout << "result: " << result << std::endl;
}
-
diff --git a/ch3/hierarchical.cpp b/ch3/hierarchical.cpp
index 4e4f2a2..5bad26e 100644
--- a/ch3/hierarchical.cpp
+++ b/ch3/hierarchical.cpp
@@ -1,57 +1,56 @@
+#include
#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;
+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;
+ 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;
- }
+ 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);
+thread_local unsigned long hierarchical_mutex::this_thread_hierarchy_value(
+ ULONG_MAX);
-int main()
+int
+main()
{
- hierarchical_mutex m1(42);
- hierarchical_mutex m2(2000);
-
+ hierarchical_mutex m1(42);
+ hierarchical_mutex m2(2000);
}
diff --git a/ch3/stack.cpp b/ch3/stack.cpp
index 5afbcf7..23a0150 100644
--- a/ch3/stack.cpp
+++ b/ch3/stack.cpp
@@ -1,68 +1,64 @@
#include
-#include
-#include
#include
+#include
+#include
-struct empty_stack: std::exception
-{
- const char* what() const throw()
- {
- return "empty stack";
- }
-
+struct empty_stack : std::exception {
+ const char* what() const throw() { return "empty stack"; }
};
-template
-class threadsafe_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;
+ std::stack data;
+ mutable std::mutex m;
- 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();
- }
+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()
+int
+main()
{
- threadsafe_stack si;
- si.push(5);
- si.pop();
- if(!si.empty())
- {
- int x;
- si.pop(x);
- }
-
+ threadsafe_stack si;
+ si.push(5);
+ si.pop();
+ if (!si.empty()) {
+ int x;
+ si.pop(x);
+ }
}
diff --git a/ch4/queue.cpp b/ch4/queue.cpp
index d8a7e46..9ca9de9 100644
--- a/ch4/queue.cpp
+++ b/ch4/queue.cpp
@@ -1,104 +1,105 @@
-#include
+#include
#include
-#include
-#include
+#include
#include
#include
-#include
+#include
+#include
template
-class queue
-{
- private:
- mutable std::mutex mut;
- std::queue data_queue;
- std::condition_variable data_cond;
+class queue {
+private:
+ mutable std::mutex mut;
+ std::queue data_queue;
+ std::condition_variable data_cond;
- public:
- queue(){}
+public:
+ queue() {}
- queue(const queue& other)
- {
- std::lock_guard lk(other.mut);
- data_queue = other.data_queue;
+ queue(const queue& other)
+ {
+ std::lock_guard lk(other.mut);
+ data_queue = other.data_queue;
+ }
+
+ void push(T new_value)
+ {
+ std::lock_guard lk(mut);
+ data_queue.push(new_value);
+ data_cond.notify_one();
+ }
+
+ void wait_and_pop(T& value)
+ {
+ std::unique_lock lk(mut);
+ data_cond.wait(lk, [this] { return !data_queue.empty(); });
+ value = data_queue.front();
+ data_queue.pop();
+ }
+
+ std::shared_ptr wait_and_pop()
+ {
+ std::unique_lock lk(mut);
+ data_cond.wait(lk, [this] { return !data_queue.empty(); });
+ std::shared_ptr res(std::make_shared(data_queue.front()));
+ data_queue.pop();
+ return res;
+ }
+
+ bool try_pop(T& value)
+ {
+ std::lock_guard lk(mut);
+ if (data_queue.empty()) {
+ return false;
}
+ value = data_queue.front();
+ data_queue.pop();
+ return true;
+ }
- void push(T new_value)
- {
- std::lock_guard lk(mut);
- data_queue.push(new_value);
- data_cond.notify_one();
+ std::shared_ptr try_pop()
+ {
+ std::lock_guard lk(mut);
+ if (data_queue.empty()) {
+ return std::shared_ptr();
}
+ std::shared_ptr res(std::make_shared(data_queue.front()));
+ data_queue.pop();
+ return res;
+ }
- void wait_and_pop(T& value)
- {
- std::unique_lock lk(mut);
- data_cond.wait(lk, [this]{return !data_queue.empty();});
- value = data_queue.front();
- data_queue.pop();
- }
-
- std::shared_ptr wait_and_pop()
- {
- std::unique_lock lk(mut);
- data_cond.wait(lk, [this]{return !data_queue.empty();});
- std::shared_ptr res(std::make_shared(data_queue.front()));
- data_queue.pop();
- return res;
- }
-
- bool try_pop(T& value)
- {
- std::lock_guard lk(mut);
- if (data_queue.empty()) {
- return false;
- }
- value = data_queue.front();
- data_queue.pop();
- return true;
- }
-
- std::shared_ptr try_pop()
- {
- std::lock_guard lk(mut);
- if (data_queue.empty()) {
- return std::shared_ptr();
- }
- std::shared_ptr res(std::make_shared(data_queue.front()));
- data_queue.pop();
- return res;
- }
-
- bool empty() const
- {
- std::lock_guard lk(mut);
- return data_queue.empty();
- }
+ bool empty() const
+ {
+ std::lock_guard lk(mut);
+ return data_queue.empty();
+ }
};
-void push(queue* q)
+void
+push(queue* q)
{
- for (int i = 0; i < 10; ++i) {
- //std::cout << "pushing " << i << std::endl;
- printf("pushing %d\n", i);
- q->push(i);
- }
+ for (int i = 0; i < 10; ++i) {
+ // std::cout << "pushing " << i << std::endl;
+ printf("pushing %d\n", i);
+ q->push(i);
+ }
}
-void pop(queue* q)
+void
+pop(queue* q)
{
- for (int i = 0; i < 10; ++i) {
- printf("poping %d\n", *q->wait_and_pop());
- }
-}
-
-int main()
-{
- queue q;
- std::thread t1(push,&q);
- std::thread t2(pop,&q);
- t1.join();
- t2.join();
- return 0;
+ for (int i = 0; i < 10; ++i) {
+ printf("poping %d\n", *q->wait_and_pop());
+ }
}
+int
+main()
+{
+ queue q;
+ std::thread t1(push, &q);
+ std::thread t2(pop, &q);
+ t1.join();
+ t2.join();
+ return 0;
+}
diff --git a/ch4/quicksort.cpp b/ch4/quicksort.cpp
index 1eab835..bca6d01 100644
--- a/ch4/quicksort.cpp
+++ b/ch4/quicksort.cpp
@@ -1,74 +1,70 @@
-#include
-#include
-#include
-#include
-#include
#include
+#include
#include
+#include
+#include
+#include
+#include
-std::ostream& operator<<(std::ostream& ostr, const std::list& list)
+std::ostream&
+operator<<(std::ostream& ostr, const std::list& list)
{
- for (auto &i : list) {
- ostr << " " << i;
- }
- return ostr;
+ for (auto& i : list) {
+ ostr << " " << i;
+ }
+ return ostr;
}
-template
-std::list sequential_quick_sort(std::list input)
+template
+std::list
+sequential_quick_sort(std::list input)
{
- if(input.empty())
- {
- return input;
- }
- std::list result;
- result.splice(result.begin(),input,input.begin());
- T const& pivot=*result.begin();
- auto divide_point=std::partition(input.begin(),input.end(),
- [&](T const& t){return t lower_part;
- lower_part.splice(lower_part.end(),input,input.begin(),
- divide_point);
- auto new_lower(
- sequential_quick_sort(std::move(lower_part)));
- auto new_higher(
- sequential_quick_sort(std::move(input)));
- result.splice(result.end(),new_higher);
- result.splice(result.begin(),new_lower);
- return result;
+ if (input.empty()) {
+ return input;
+ }
+ std::list result;
+ result.splice(result.begin(), input, input.begin());
+ T const& pivot = *result.begin();
+ auto divide_point = std::partition(
+ input.begin(), input.end(), [&](T const& t) { return t < pivot; });
+ std::list lower_part;
+ lower_part.splice(lower_part.end(), input, input.begin(), divide_point);
+ auto new_lower(sequential_quick_sort(std::move(lower_part)));
+ auto new_higher(sequential_quick_sort(std::move(input)));
+ result.splice(result.end(), new_higher);
+ result.splice(result.begin(), new_lower);
+ return result;
}
-template
-std::list parallel_quick_sort(std::list input)
+template
+std::list
+parallel_quick_sort(std::list input)
{
- if(input.empty())
- {
- return input;
- }
- std::list result;
- result.splice(result.begin(),input,input.begin());
- T const& pivot=*result.begin();
- auto divide_point=std::partition(input.begin(),input.end(),
- [&](T const& t){return t lower_part;
- lower_part.splice(lower_part.end(),input,input.begin(),
- divide_point);
- std::future > new_lower(
- std::async(¶llel_quick_sort,std::move(lower_part)));
- auto new_higher(
- parallel_quick_sort(std::move(input)));
- result.splice(result.end(),new_higher);
- result.splice(result.begin(),new_lower.get());
- return result;
+ if (input.empty()) {
+ return input;
+ }
+ std::list result;
+ result.splice(result.begin(), input, input.begin());
+ T const& pivot = *result.begin();
+ auto divide_point = std::partition(
+ input.begin(), input.end(), [&](T const& t) { return t < pivot; });
+ std::list lower_part;
+ lower_part.splice(lower_part.end(), input, input.begin(), divide_point);
+ std::future> new_lower(
+ std::async(¶llel_quick_sort, std::move(lower_part)));
+ auto new_higher(parallel_quick_sort(std::move(input)));
+ result.splice(result.end(), new_higher);
+ result.splice(result.begin(), new_lower.get());
+ return result;
}
-int main()
+int
+main()
{
- std::list list1 = {4, 2, 1, 5, 8, 9, 7};
- std::list sorted1 = sequential_quick_sort(list1);
- std::list sorted2 = parallel_quick_sort(list1);
- std::cout << "sorted1: " << sorted1 << std::endl;
- std::cout << "sorted2: " << sorted2 << std::endl;
- return 0;
+ std::list list1 = {4, 2, 1, 5, 8, 9, 7};
+ std::list sorted1 = sequential_quick_sort(list1);
+ std::list sorted2 = parallel_quick_sort(list1);
+ std::cout << "sorted1: " << sorted1 << std::endl;
+ std::cout << "sorted2: " << sorted2 << std::endl;
+ return 0;
}
-
diff --git a/ch6/list.cpp b/ch6/list.cpp
index 8f8a0b4..c641eee 100644
--- a/ch6/list.cpp
+++ b/ch6/list.cpp
@@ -1,126 +1,115 @@
-#include
-#include
-#include
#include
+#include
+#include
+#include
template
-class list
-{
- struct node
- {
- std::mutex m;
- std::shared_ptr data;
- std::unique_ptr next;
+class list {
+ struct node {
+ std::mutex m;
+ std::shared_ptr data;
+ std::unique_ptr next;
- node()
- : next()
- {}
-
- node(T const& value)
- : data(std::make_shared(value))
- {}
- };
+ node() : next() {}
- node head;
+ node(T const& value) : data(std::make_shared(value)) {}
+ };
- public:
- list()
- {}
+ node head;
- ~list()
- {
- remove_if([](T const&){return true;});
+public:
+ list() {}
+
+ ~list()
+ {
+ remove_if([](T const&) { return true; });
+ }
+
+ list(list const& other) = delete;
+ list& operator=(list const& other) = delete;
+
+ void push_front(T const& value)
+ {
+ std::unique_ptr new_node(new node(value));
+ std::lock_guard lk(head.m);
+ new_node->next = std::move(head.next);
+ head.next = std::move(new_node);
+ }
+
+ template
+ void for_each(Function f)
+ {
+ node* current = &head;
+ std::unique_lock lk(head.m);
+ while (node* const next = current->next.get()) {
+ std::unique_lock next_lk(next->m);
+ lk.unlock();
+ f(*next->data);
+ current = next;
+ lk = std::move(next_lk);
}
+ }
- list(list const& other) = delete;
- list& operator=(list const& other) = delete;
-
- void push_front(T const& value)
- {
- std::unique_ptr new_node(new node(value));
- std::lock_guard lk(head.m);
- new_node->next = std::move(head.next);
- head.next = std::move(new_node);
+ template
+ std::shared_ptr find_first_of(Predicate p)
+ {
+ node* current = &head;
+ std::unique_lock lk(head.m);
+ while (node* const next = current->next.get()) {
+ std::unique_lock next_lk(next->m);
+ lk.unlock();
+ if (p(*next->data)) {
+ return next->data;
+ }
+ current = next;
+ lk = std::move(next_lk);
}
+ return std::shared_ptr();
+ }
- template
- void for_each(Function f)
- {
- node* current = &head;
- std::unique_lock lk(head.m);
- while (node* const next = current->next.get())
- {
- std::unique_lock next_lk(next->m);
- lk.unlock();
- f(*next->data);
- current = next;
- lk = std::move(next_lk);
- }
- }
-
- template
- std::shared_ptr find_first_of(Predicate p)
- {
- node *current = &head;
- std::unique_lock lk(head.m);
- while (node* const next = current->next.get())
- {
- std::unique_lock next_lk(next->m);
- lk.unlock();
- if (p(*next->data))
- {
- return next->data;
- }
- current = next;
- lk = std::move(next_lk);
- }
- return std::shared_ptr();
- }
-
- template
- void remove_if(Predicate p)
- {
- node *current = &head;
- std::unique_lock lk(head.m);
- while (node* const next = current->next.get())
- {
- std::unique_lock next_lk(next->m);
- if (p(*next->data))
- {
- std::unique_ptr old_next = std::move(current->next);
- current->next = std::move(next->next);
- next_lk.unlock();
- }
- else
- {
- lk.unlock();
- current = next;
- lk = std::move(next_lk);
- }
- }
+ template
+ void remove_if(Predicate p)
+ {
+ node* current = &head;
+ std::unique_lock lk(head.m);
+ while (node* const next = current->next.get()) {
+ std::unique_lock next_lk(next->m);
+ if (p(*next->data)) {
+ std::unique_ptr old_next = std::move(current->next);
+ current->next = std::move(next->next);
+ next_lk.unlock();
+ }
+ else {
+ lk.unlock();
+ current = next;
+ lk = std::move(next_lk);
+ }
}
+ }
};
-void push(list* l)
+void
+push(list* l)
{
- for (int i = 0; i < 10; ++i) {
- printf("pushing %d\n", i);
- l->push_front(i);
- }
+ for (int i = 0; i < 10; ++i) {
+ printf("pushing %d\n", i);
+ l->push_front(i);
+ }
}
-void visit(int i)
+void
+visit(int i)
{
- printf("visit %d\n", i);
-}
-
-int main()
-{
- list l;
- std::thread t(push,&l);
- sleep(1);
- l.for_each(visit);
- t.join();
- return 0;
+ printf("visit %d\n", i);
}
+int
+main()
+{
+ list l;
+ std::thread t(push, &l);
+ sleep(1);
+ l.for_each(visit);
+ t.join();
+ return 0;
+}
diff --git a/ch6/lookuptable.cpp b/ch6/lookuptable.cpp
index fe0e672..218c646 100644
--- a/ch6/lookuptable.cpp
+++ b/ch6/lookuptable.cpp
@@ -1,133 +1,122 @@
+#include
#include
+#include
+#include
#include
#include
-#include
-#include
-#include
#include
-template >
-class lookup_table
-{
+template >
+class lookup_table {
+private:
+ class bucket_type {
private:
- class bucket_type
+ typedef std::pair bucket_value;
+ typedef std::list bucket_data;
+ typedef typename bucket_data::iterator bucket_iterator;
+
+ bucket_data data;
+ mutable boost::shared_mutex mutex;
+
+ bucket_iterator find_entry_for(Key const& key) const
{
- private:
- typedef std::pair bucket_value;
- typedef std::list bucket_data;
- typedef typename bucket_data::iterator bucket_iterator;
-
- bucket_data data;
- mutable boost::shared_mutex mutex;
-
- bucket_iterator find_entry_for(Key const& key) const
- {
- return std::find_if(data.begin(), data.end(),
- [&](bucket_value const& item)
- {return item.first == key;});
- }
-
- public:
- Value value_for(Key const& key, Value const& default_value) const
- {
- boost::shared_lock lock(mutex);
- bucket_iterator const found_entry = find_entry_for(key);
- return (found_entry == data.end()) ?
- default_value : found_entry->second;
- }
-
- void add_or_update_mapping(Key const& key, Value const& value)
- {
- std::unique_lock lock(mutex);
- bucket_iterator const found_entry = find_entry_for(key);
- if (found_entry == data.end()) {
- data.push_back(bucket_value(key,value));
- }
- else {
- found_entry->second = value;
- }
- }
-
- void remove_mapping(Key const& key)
- {
- std::unique_lock lock(mutex);
- bucket_iterator const found_entry = find_entry_for(key);
- if (found_entry != data.end()) {
- data.erase(found_entry);
- }
- }
- };
-
- std::vector > buckets;
- Hash hasher;
-
- bucket_type& get_bucket(Key const& key) const
- {
- const std::size_t bucket_index = hasher(key) % buckets.size();
- return *buckets[bucket_index];
+ return std::find_if(
+ data.begin(), data.end(), [&](bucket_value const& item) {
+ return item.first == key;
+ });
}
public:
- typedef Key key_type;
- typedef Value mapped_type;
- typedef Hash hash_type;
-
- lookup_table(unsigned num_buckets = 19, const Hash& hasher_ = Hash())
- : buckets(num_buckets)
- , hasher(hasher_)
+ Value value_for(Key const& key, Value const& default_value) const
{
- for (unsigned i = 0; i < num_buckets; ++i)
- {
- buckets[i].reset(new bucket_type);
- }
+ boost::shared_lock lock(mutex);
+ bucket_iterator const found_entry = find_entry_for(key);
+ return (found_entry == data.end()) ? default_value : found_entry->second;
}
- lookup_table(const lookup_table& other) = delete;
- lookup_table& operator=(const lookup_table& other) = delete;
-
- Value value_for(Key const& key,
- Value const& default_value = Value()) const
+ void add_or_update_mapping(Key const& key, Value const& value)
{
- return get_bucket(key).value_for(key, default_value);
+ std::unique_lock lock(mutex);
+ bucket_iterator const found_entry = find_entry_for(key);
+ if (found_entry == data.end()) {
+ data.push_back(bucket_value(key, value));
+ }
+ else {
+ found_entry->second = value;
+ }
}
- void add_or_update_mapping(const Key& key, const Value& value)
+ void remove_mapping(Key const& key)
{
- get_bucket(key).add_or_update_mapping(key, value);
+ std::unique_lock lock(mutex);
+ bucket_iterator const found_entry = find_entry_for(key);
+ if (found_entry != data.end()) {
+ data.erase(found_entry);
+ }
}
+ };
- void remove_mapping(const Key& key)
- {
- get_bucket(key).remove_mapping(key);
- }
+ std::vector> buckets;
+ Hash hasher;
- std::map get_map() const
- {
- std::vector > locks;
- for (unsigned i = 0; i < buckets.size(); ++i)
- {
- locks.push_back(boost::unique_lock(
- buckets[i].mutex));
- }
- std::map res;
- for (unsigned i = 0; i < buckets.size(); ++i)
- {
- for (typename bucket_type::bucket_iterator it = buckets[i].data.begin();
- it != buckets[i].data.end();
- ++it)
- {
- res.insert(*it);
- }
- }
- return res;
+ bucket_type& get_bucket(Key const& key) const
+ {
+ const std::size_t bucket_index = hasher(key) % buckets.size();
+ return *buckets[bucket_index];
+ }
+
+public:
+ typedef Key key_type;
+ typedef Value mapped_type;
+ typedef Hash hash_type;
+
+ lookup_table(unsigned num_buckets = 19, const Hash& hasher_ = Hash())
+ : buckets(num_buckets), hasher(hasher_)
+ {
+ for (unsigned i = 0; i < num_buckets; ++i) {
+ buckets[i].reset(new bucket_type);
}
+ }
+
+ lookup_table(const lookup_table& other) = delete;
+ lookup_table& operator=(const lookup_table& other) = delete;
+
+ Value value_for(Key const& key, Value const& default_value = Value()) const
+ {
+ return get_bucket(key).value_for(key, default_value);
+ }
+
+ void add_or_update_mapping(const Key& key, const Value& value)
+ {
+ get_bucket(key).add_or_update_mapping(key, value);
+ }
+
+ void remove_mapping(const Key& key) { get_bucket(key).remove_mapping(key); }
+
+ std::map get_map() const
+ {
+ std::vector> locks;
+ for (unsigned i = 0; i < buckets.size(); ++i) {
+ locks.push_back(
+ boost::unique_lock(buckets[i].mutex));
+ }
+ std::map res;
+ for (unsigned i = 0; i < buckets.size(); ++i) {
+ for (typename bucket_type::bucket_iterator it = buckets[i].data.begin();
+ it != buckets[i].data.end();
+ ++it) {
+ res.insert(*it);
+ }
+ }
+ return res;
+ }
};
-int main()
+int
+main()
{
- lookup_table t;
- t.add_or_update_mapping(1,"hello");
- std::cout << "value for 1 is " << t.value_for(1) << std::endl;
- return 0;
+ lookup_table t;
+ t.add_or_update_mapping(1, "hello");
+ std::cout << "value for 1 is " << t.value_for(1) << std::endl;
+ return 0;
}
-
diff --git a/ch6/queue.cpp b/ch6/queue.cpp
index d2cd772..fb572ff 100644
--- a/ch6/queue.cpp
+++ b/ch6/queue.cpp
@@ -1,112 +1,113 @@
-#include
+#include
#include
-#include
-#include
+#include
#include
#include
-#include
+#include
+#include
template
-class queue
-{
- private:
- mutable std::mutex mut;
- std::queue > data_queue;
- std::condition_variable data_cond;
+class queue {
+private:
+ mutable std::mutex mut;
+ std::queue> data_queue;
+ std::condition_variable data_cond;
- public:
- queue(){}
+public:
+ queue() {}
- queue(const queue& other)
- {
- std::lock_guard lk(other.mut);
- data_queue = other.data_queue;
+ queue(const queue& other)
+ {
+ std::lock_guard lk(other.mut);
+ data_queue = other.data_queue;
+ }
+
+ void push(T new_value)
+ {
+ std::shared_ptr data(new T(new_value));
+ std::lock_guard lk(mut);
+ data_queue.push(data);
+ data_cond.notify_one();
+ }
+
+ void wait_and_pop(T& value)
+ {
+ std::unique_lock lk(mut);
+ data_cond.wait(lk, [&] { return !data_queue.empty(); });
+ /*
+ while (data_queue.empty()) {
+ data_cond.wait(lk);
}
+ */
+ value = *data_queue.front();
+ data_queue.pop();
+ }
- void push(T new_value)
- {
- std::shared_ptr data(new T(new_value));
- std::lock_guard lk(mut);
- data_queue.push(data);
- data_cond.notify_one();
+ std::shared_ptr wait_and_pop()
+ {
+ std::unique_lock lk(mut);
+ data_cond.wait(lk, [&] { return !data_queue.empty(); });
+ /*
+ while (data_queue.empty()) {
+ data_cond.wait(lk);
}
+ */
+ std::shared_ptr res = data_queue.front();
+ data_queue.pop();
+ return res;
+ }
- void wait_and_pop(T& value)
- {
- std::unique_lock lk(mut);
- data_cond.wait(lk, [&]{return !data_queue.empty();});
- /*
- while (data_queue.empty()) {
- data_cond.wait(lk);
- }
- */
- value = *data_queue.front();
- data_queue.pop();
- }
+ bool try_pop(T& value)
+ {
+ std::lock_guard lk(mut);
+ if (data_queue.empty())
+ return false;
+ value = *data_queue.front();
+ data_queue.pop();
+ }
- std::shared_ptr