From 13f11221c33a889cd230ace20f83f2ae97c8b08b Mon Sep 17 00:00:00 2001 From: Oliver Kowalke Date: Sat, 29 Oct 2011 12:24:05 +0200 Subject: [PATCH] remove task and tasklet --- boost/task.hpp | 44 - boost/task/as_sub_task.hpp | 51 - boost/task/async.hpp | 128 -- boost/task/bounded_fifo.hpp | 205 --- boost/task/bounded_prio_queue.hpp | 238 ---- boost/task/bounded_smart_queue.hpp | 249 ---- boost/task/callable.hpp | 165 --- boost/task/context.hpp | 94 -- boost/task/detail/bind_processor.hpp | 37 - boost/task/detail/bind_processor_aix.hpp | 52 - boost/task/detail/bind_processor_freebsd.hpp | 63 - boost/task/detail/bind_processor_hpux.hpp | 65 - boost/task/detail/bind_processor_linux.hpp | 66 - boost/task/detail/bind_processor_solaris.hpp | 53 - boost/task/detail/bind_processor_windows.hpp | 55 - boost/task/detail/config.hpp | 80 -- boost/task/detail/future_traits.hpp | 82 -- boost/task/detail/meta.hpp | 27 - boost/task/detail/pool_base.hpp | 369 ----- boost/task/detail/smart.hpp | 67 - boost/task/detail/worker.hpp | 279 ---- boost/task/detail/worker_group.hpp | 101 -- boost/task/detail/wsq.hpp | 65 - boost/task/exceptions.hpp | 105 -- boost/task/fast_semaphore.hpp | 48 - boost/task/handle.hpp | 285 ---- boost/task/meta.hpp | 40 - boost/task/new_thread.hpp | 94 -- boost/task/own_thread.hpp | 66 - boost/task/poolsize.hpp | 43 - boost/task/semaphore.hpp | 64 - boost/task/spin/auto_reset_event.hpp | 49 - boost/task/spin/barrier.hpp | 39 - boost/task/spin/bounded_channel.hpp | 398 ------ boost/task/spin/condition.hpp | 293 ---- boost/task/spin/count_down_event.hpp | 50 - boost/task/spin/future.hpp | 1125 --------------- boost/task/spin/manual_reset_event.hpp | 56 - boost/task/spin/mutex.hpp | 56 - boost/task/spin/unbounded_channel.hpp | 273 ---- boost/task/stacksize.hpp | 43 - boost/task/static_pool.hpp | 208 --- boost/task/task.hpp | 497 ------- boost/task/unbounded_fifo.hpp | 135 -- boost/task/unbounded_prio_queue.hpp | 152 -- boost/task/unbounded_smart_queue.hpp | 163 --- boost/task/utility.hpp | 44 - boost/task/watermark.hpp | 54 - boost/tasklet.hpp | 27 - boost/tasklet/auto_reset_event.hpp | 59 - boost/tasklet/barrier.hpp | 56 - boost/tasklet/bounded_channel.hpp | 265 ---- boost/tasklet/condition.hpp | 198 --- boost/tasklet/count_down_event.hpp | 60 - boost/tasklet/detail/config.hpp | 41 - boost/tasklet/detail/future_traits.hpp | 90 -- boost/tasklet/detail/interrupt_flags.hpp | 35 - boost/tasklet/detail/state_flags.hpp | 40 - boost/tasklet/detail/tasklet_base.hpp | 97 -- boost/tasklet/detail/tasklet_object.hpp | 99 -- boost/tasklet/exceptions.hpp | 127 -- boost/tasklet/future.hpp | 1080 -------------- boost/tasklet/interruption.hpp | 86 -- boost/tasklet/manual_reset_event.hpp | 66 - boost/tasklet/mutex.hpp | 101 -- boost/tasklet/object/id.hpp | 68 - boost/tasklet/round_robin.hpp | 138 -- boost/tasklet/scheduler.hpp | 96 -- boost/tasklet/spin_condition.hpp | 152 -- boost/tasklet/spin_mutex.hpp | 66 - boost/tasklet/strategy.hpp | 187 --- boost/tasklet/tasklet.hpp | 226 --- boost/tasklet/unbounded_channel.hpp | 197 --- boost/tasklet/utility.hpp | 71 - libs/task/build/Jamfile.v2 | 89 -- libs/task/doc/Jamfile.v2 | 36 - libs/task/doc/acknowledgements.qbk | 13 - libs/task/doc/as_sub_task.qbk | 40 - libs/task/doc/async_completion_token.qbk | 315 ----- libs/task/doc/async_execution.qbk | 90 -- libs/task/doc/execution_policies.qbk | 21 - libs/task/doc/fork_join.qbk | 78 - libs/task/doc/handle.qbk | 333 ----- libs/task/doc/meta_functions.qbk | 60 - libs/task/doc/new_thread.qbk | 86 -- libs/task/doc/overview.qbk | 140 -- libs/task/doc/own_thread.qbk | 62 - libs/task/doc/processor_binding.qbk | 30 - libs/task/doc/queue.qbk | 118 -- libs/task/doc/scheduler.qbk | 125 -- libs/task/doc/shutdown.qbk | 106 -- libs/task/doc/spin_barrier.qbk | 47 - libs/task/doc/spin_condition_variables.qbk | 199 --- libs/task/doc/spin_event_variables.qbk | 289 ---- libs/task/doc/spin_fifos.qbk | 206 --- libs/task/doc/spin_future_ref.qbk | 928 ------------ libs/task/doc/spin_futures.qbk | 181 --- libs/task/doc/spin_mutexes.qbk | 43 - libs/task/doc/spin_synchronization.qbk | 18 - libs/task/doc/static_pool.qbk | 301 ---- libs/task/doc/task.qbk | 126 -- libs/task/doc/task_ref.qbk | 407 ------ libs/task/doc/this_task.qbk | 63 - libs/task/doc/threadpool.qbk | 63 - libs/task/doc/todo.qbk | 22 - libs/task/doc/work_stealing.qbk | 50 - libs/task/examples/Jamfile.v2 | 37 - libs/task/examples/bind_to_processors.cpp | 116 -- libs/task/examples/interrupt.cpp | 70 - libs/task/examples/priority.cpp | 64 - libs/task/examples/shutdown_now.cpp | 68 - libs/task/examples/smart.cpp | 88 -- libs/task/examples/sub_tasks.cpp | 88 -- libs/task/examples/submit.cpp | 75 - libs/task/examples/sync/fork_join_event.cpp | 87 -- libs/task/examples/sync/message_passing.cpp | 113 -- libs/task/examples/sync/ping_pong.cpp | 125 -- libs/task/src/callable.cpp | 36 - libs/task/src/context.cpp | 84 -- libs/task/src/detail/worker.cpp | 51 - libs/task/src/detail/worker_group.cpp | 88 -- libs/task/src/detail/wsq.cpp | 120 -- libs/task/src/fast_semaphore.cpp | 74 - libs/task/src/poolsize.cpp | 22 - libs/task/src/semaphore_posix.cpp | 100 -- libs/task/src/semaphore_windows.cpp | 57 - libs/task/src/spin/auto_reset_event.cpp | 71 - libs/task/src/spin/barrier.cpp | 43 - libs/task/src/spin/condition.cpp | 52 - libs/task/src/spin/count_down_event.cpp | 82 -- libs/task/src/spin/manual_reset_event.cpp | 104 -- libs/task/src/spin/mutex.cpp | 77 - libs/task/src/stacksize.cpp | 21 - libs/task/src/watermark.cpp | 34 - libs/task/test/Jamfile.v2 | 46 - libs/task/test/condition_test_common.hpp | 99 -- libs/task/test/test_as_sub_task.cpp | 70 - libs/task/test/test_bounded_pool.cpp | 509 ------- libs/task/test/test_functions.hpp | 99 -- libs/task/test/test_new_thread.cpp | 284 ---- libs/task/test/test_own_thread.cpp | 312 ---- libs/task/test/test_spin_auto_reset_event.cpp | 210 --- libs/task/test/test_spin_bounded_channel.cpp | 171 --- libs/task/test/test_spin_condition.cpp | 191 --- .../test/test_spin_condition_notify_all.cpp | 225 --- .../test/test_spin_condition_notify_one.cpp | 159 --- ...st_spin_condition_timed_wait_times_out.cpp | 175 --- libs/task/test/test_spin_count_down_event.cpp | 122 -- .../test/test_spin_manual_reset_event.cpp | 234 --- libs/task/test/test_spin_mutex.cpp | 85 -- .../task/test/test_spin_unbounded_channel.cpp | 171 --- libs/task/test/test_task.cpp | 99 -- libs/task/test/test_tasklet.cpp | 425 ------ libs/task/test/test_unbounded_pool.cpp | 440 ------ libs/task/test/util.ipp | 159 --- libs/tasklet/build/Jamfile.v2 | 39 - libs/tasklet/doc/Jamfile.v2 | 33 - libs/tasklet/doc/barrier.qbk | 52 - libs/tasklet/doc/channel.qbk | 193 --- libs/tasklet/doc/condition_variables.qbk | 267 ---- libs/tasklet/doc/event_variables.qbk | 283 ---- .../tasklet/doc/html/standalone_HTML.manifest | 55 - libs/tasklet/doc/mutexes.qbk | 67 - libs/tasklet/doc/overview.qbk | 54 - libs/tasklet/doc/synchronization.qbk | 15 - libs/tasklet/doc/tasklet.qbk | 102 -- libs/tasklet/doc/tasklet_ref.qbk | 1255 ----------------- libs/tasklet/doc/todo.qbk | 13 - libs/tasklet/examples/Jamfile.v2 | 27 - libs/tasklet/examples/barrier_mt.cpp | 158 --- libs/tasklet/examples/cancel.cpp | 69 - libs/tasklet/examples/future.cpp | 44 - libs/tasklet/examples/future_mt.cpp | 176 --- libs/tasklet/examples/interrupt.cpp | 124 -- libs/tasklet/examples/join.cpp | 70 - libs/tasklet/examples/migrate_mt.cpp | 124 -- libs/tasklet/examples/ping_pong.cpp | 107 -- libs/tasklet/examples/ping_pong_mt.cpp | 160 --- libs/tasklet/examples/simple.cpp | 50 - libs/tasklet/performance/Jamfile.v2 | 18 - libs/tasklet/performance/bind_processor.hpp | 28 - .../performance/bind_processor_aix.hpp | 37 - .../performance/bind_processor_freebsd.hpp | 41 - .../performance/bind_processor_hpux.hpp | 43 - .../performance/bind_processor_linux.hpp | 43 - .../performance/bind_processor_solaris.hpp | 38 - .../performance/bind_processor_windows.hpp | 36 - libs/tasklet/performance/performance.cpp | 125 -- libs/tasklet/performance/performance.hpp | 26 - .../performance/performance_gcc_i386.hpp | 62 - .../performance/performance_gcc_x86-64.hpp | 62 - .../performance/performance_msvc_i386.hpp | 60 - libs/tasklet/src/auto_reset_event.cpp | 47 - libs/tasklet/src/barrier.cpp | 44 - libs/tasklet/src/condition.cpp | 92 -- libs/tasklet/src/count_down_event.cpp | 61 - libs/tasklet/src/detail/tasklet_base.cpp | 75 - libs/tasklet/src/manual_reset_event.cpp | 83 -- libs/tasklet/src/mutex.cpp | 83 -- libs/tasklet/src/round_robin.cpp | 478 ------- libs/tasklet/src/spin_condition.cpp | 53 - libs/tasklet/src/spin_mutex.cpp | 48 - libs/tasklet/src/strategy.cpp | 194 --- libs/tasklet/src/tasklet.cpp | 133 -- libs/tasklet/test/Jamfile.v2 | 44 - libs/tasklet/test/condition_test_common.hpp | 63 - libs/tasklet/test/test_auto_reset_event.cpp | 132 -- libs/tasklet/test/test_barrier.cpp | 149 -- libs/tasklet/test/test_cancel.cpp | 183 --- libs/tasklet/test/test_condition.cpp | 261 ---- libs/tasklet/test/test_count_down_event.cpp | 96 -- libs/tasklet/test/test_generic_locks.cpp | 384 ----- libs/tasklet/test/test_interrupt.cpp | 248 ---- libs/tasklet/test/test_join.cpp | 362 ----- libs/tasklet/test/test_lock.cpp | 209 --- libs/tasklet/test/test_manual_reset_event.cpp | 170 --- libs/tasklet/test/test_mutex.cpp | 132 -- libs/tasklet/test/test_priority.cpp | 39 - libs/tasklet/test/test_scheduler.cpp | 262 ---- libs/tasklet/test/test_spin_condition.cpp | 248 ---- libs/tasklet/test/test_spin_mutex.cpp | 131 -- libs/tasklet/test/test_tasklet.cpp | 121 -- libs/tasklet/test/test_unique_lock.cpp | 200 --- libs/tasklet/test/test_utility.cpp | 158 --- 224 files changed, 30899 deletions(-) delete mode 100644 boost/task.hpp delete mode 100755 boost/task/as_sub_task.hpp delete mode 100644 boost/task/async.hpp delete mode 100644 boost/task/bounded_fifo.hpp delete mode 100644 boost/task/bounded_prio_queue.hpp delete mode 100644 boost/task/bounded_smart_queue.hpp delete mode 100755 boost/task/callable.hpp delete mode 100644 boost/task/context.hpp delete mode 100644 boost/task/detail/bind_processor.hpp delete mode 100644 boost/task/detail/bind_processor_aix.hpp delete mode 100755 boost/task/detail/bind_processor_freebsd.hpp delete mode 100644 boost/task/detail/bind_processor_hpux.hpp delete mode 100644 boost/task/detail/bind_processor_linux.hpp delete mode 100644 boost/task/detail/bind_processor_solaris.hpp delete mode 100644 boost/task/detail/bind_processor_windows.hpp delete mode 100644 boost/task/detail/config.hpp delete mode 100644 boost/task/detail/future_traits.hpp delete mode 100644 boost/task/detail/meta.hpp delete mode 100755 boost/task/detail/pool_base.hpp delete mode 100755 boost/task/detail/smart.hpp delete mode 100644 boost/task/detail/worker.hpp delete mode 100644 boost/task/detail/worker_group.hpp delete mode 100644 boost/task/detail/wsq.hpp delete mode 100644 boost/task/exceptions.hpp delete mode 100755 boost/task/fast_semaphore.hpp delete mode 100644 boost/task/handle.hpp delete mode 100644 boost/task/meta.hpp delete mode 100755 boost/task/new_thread.hpp delete mode 100755 boost/task/own_thread.hpp delete mode 100644 boost/task/poolsize.hpp delete mode 100755 boost/task/semaphore.hpp delete mode 100644 boost/task/spin/auto_reset_event.hpp delete mode 100644 boost/task/spin/barrier.hpp delete mode 100644 boost/task/spin/bounded_channel.hpp delete mode 100644 boost/task/spin/condition.hpp delete mode 100644 boost/task/spin/count_down_event.hpp delete mode 100644 boost/task/spin/future.hpp delete mode 100644 boost/task/spin/manual_reset_event.hpp delete mode 100644 boost/task/spin/mutex.hpp delete mode 100644 boost/task/spin/unbounded_channel.hpp delete mode 100755 boost/task/stacksize.hpp delete mode 100644 boost/task/static_pool.hpp delete mode 100644 boost/task/task.hpp delete mode 100644 boost/task/unbounded_fifo.hpp delete mode 100644 boost/task/unbounded_prio_queue.hpp delete mode 100644 boost/task/unbounded_smart_queue.hpp delete mode 100644 boost/task/utility.hpp delete mode 100644 boost/task/watermark.hpp delete mode 100644 boost/tasklet.hpp delete mode 100644 boost/tasklet/auto_reset_event.hpp delete mode 100644 boost/tasklet/barrier.hpp delete mode 100644 boost/tasklet/bounded_channel.hpp delete mode 100644 boost/tasklet/condition.hpp delete mode 100644 boost/tasklet/count_down_event.hpp delete mode 100644 boost/tasklet/detail/config.hpp delete mode 100644 boost/tasklet/detail/future_traits.hpp delete mode 100644 boost/tasklet/detail/interrupt_flags.hpp delete mode 100644 boost/tasklet/detail/state_flags.hpp delete mode 100644 boost/tasklet/detail/tasklet_base.hpp delete mode 100644 boost/tasklet/detail/tasklet_object.hpp delete mode 100644 boost/tasklet/exceptions.hpp delete mode 100644 boost/tasklet/future.hpp delete mode 100644 boost/tasklet/interruption.hpp delete mode 100644 boost/tasklet/manual_reset_event.hpp delete mode 100644 boost/tasklet/mutex.hpp delete mode 100644 boost/tasklet/object/id.hpp delete mode 100644 boost/tasklet/round_robin.hpp delete mode 100644 boost/tasklet/scheduler.hpp delete mode 100644 boost/tasklet/spin_condition.hpp delete mode 100644 boost/tasklet/spin_mutex.hpp delete mode 100644 boost/tasklet/strategy.hpp delete mode 100644 boost/tasklet/tasklet.hpp delete mode 100644 boost/tasklet/unbounded_channel.hpp delete mode 100644 boost/tasklet/utility.hpp delete mode 100644 libs/task/build/Jamfile.v2 delete mode 100644 libs/task/doc/Jamfile.v2 delete mode 100644 libs/task/doc/acknowledgements.qbk delete mode 100644 libs/task/doc/as_sub_task.qbk delete mode 100644 libs/task/doc/async_completion_token.qbk delete mode 100644 libs/task/doc/async_execution.qbk delete mode 100644 libs/task/doc/execution_policies.qbk delete mode 100644 libs/task/doc/fork_join.qbk delete mode 100644 libs/task/doc/handle.qbk delete mode 100644 libs/task/doc/meta_functions.qbk delete mode 100644 libs/task/doc/new_thread.qbk delete mode 100644 libs/task/doc/overview.qbk delete mode 100644 libs/task/doc/own_thread.qbk delete mode 100644 libs/task/doc/processor_binding.qbk delete mode 100644 libs/task/doc/queue.qbk delete mode 100644 libs/task/doc/scheduler.qbk delete mode 100644 libs/task/doc/shutdown.qbk delete mode 100644 libs/task/doc/spin_barrier.qbk delete mode 100644 libs/task/doc/spin_condition_variables.qbk delete mode 100644 libs/task/doc/spin_event_variables.qbk delete mode 100644 libs/task/doc/spin_fifos.qbk delete mode 100644 libs/task/doc/spin_future_ref.qbk delete mode 100644 libs/task/doc/spin_futures.qbk delete mode 100644 libs/task/doc/spin_mutexes.qbk delete mode 100644 libs/task/doc/spin_synchronization.qbk delete mode 100644 libs/task/doc/static_pool.qbk delete mode 100644 libs/task/doc/task.qbk delete mode 100644 libs/task/doc/task_ref.qbk delete mode 100644 libs/task/doc/this_task.qbk delete mode 100644 libs/task/doc/threadpool.qbk delete mode 100644 libs/task/doc/todo.qbk delete mode 100644 libs/task/doc/work_stealing.qbk delete mode 100644 libs/task/examples/Jamfile.v2 delete mode 100644 libs/task/examples/bind_to_processors.cpp delete mode 100644 libs/task/examples/interrupt.cpp delete mode 100644 libs/task/examples/priority.cpp delete mode 100644 libs/task/examples/shutdown_now.cpp delete mode 100644 libs/task/examples/smart.cpp delete mode 100755 libs/task/examples/sub_tasks.cpp delete mode 100644 libs/task/examples/submit.cpp delete mode 100755 libs/task/examples/sync/fork_join_event.cpp delete mode 100755 libs/task/examples/sync/message_passing.cpp delete mode 100755 libs/task/examples/sync/ping_pong.cpp delete mode 100755 libs/task/src/callable.cpp delete mode 100755 libs/task/src/context.cpp delete mode 100644 libs/task/src/detail/worker.cpp delete mode 100644 libs/task/src/detail/worker_group.cpp delete mode 100644 libs/task/src/detail/wsq.cpp delete mode 100755 libs/task/src/fast_semaphore.cpp delete mode 100755 libs/task/src/poolsize.cpp delete mode 100755 libs/task/src/semaphore_posix.cpp delete mode 100755 libs/task/src/semaphore_windows.cpp delete mode 100644 libs/task/src/spin/auto_reset_event.cpp delete mode 100644 libs/task/src/spin/barrier.cpp delete mode 100644 libs/task/src/spin/condition.cpp delete mode 100644 libs/task/src/spin/count_down_event.cpp delete mode 100644 libs/task/src/spin/manual_reset_event.cpp delete mode 100644 libs/task/src/spin/mutex.cpp delete mode 100755 libs/task/src/stacksize.cpp delete mode 100755 libs/task/src/watermark.cpp delete mode 100644 libs/task/test/Jamfile.v2 delete mode 100644 libs/task/test/condition_test_common.hpp delete mode 100755 libs/task/test/test_as_sub_task.cpp delete mode 100644 libs/task/test/test_bounded_pool.cpp delete mode 100644 libs/task/test/test_functions.hpp delete mode 100644 libs/task/test/test_new_thread.cpp delete mode 100644 libs/task/test/test_own_thread.cpp delete mode 100755 libs/task/test/test_spin_auto_reset_event.cpp delete mode 100644 libs/task/test/test_spin_bounded_channel.cpp delete mode 100644 libs/task/test/test_spin_condition.cpp delete mode 100644 libs/task/test/test_spin_condition_notify_all.cpp delete mode 100644 libs/task/test/test_spin_condition_notify_one.cpp delete mode 100644 libs/task/test/test_spin_condition_timed_wait_times_out.cpp delete mode 100755 libs/task/test/test_spin_count_down_event.cpp delete mode 100755 libs/task/test/test_spin_manual_reset_event.cpp delete mode 100644 libs/task/test/test_spin_mutex.cpp delete mode 100644 libs/task/test/test_spin_unbounded_channel.cpp delete mode 100755 libs/task/test/test_task.cpp delete mode 100644 libs/task/test/test_tasklet.cpp delete mode 100644 libs/task/test/test_unbounded_pool.cpp delete mode 100644 libs/task/test/util.ipp delete mode 100644 libs/tasklet/build/Jamfile.v2 delete mode 100644 libs/tasklet/doc/Jamfile.v2 delete mode 100644 libs/tasklet/doc/barrier.qbk delete mode 100644 libs/tasklet/doc/channel.qbk delete mode 100644 libs/tasklet/doc/condition_variables.qbk delete mode 100644 libs/tasklet/doc/event_variables.qbk delete mode 100644 libs/tasklet/doc/html/standalone_HTML.manifest delete mode 100644 libs/tasklet/doc/mutexes.qbk delete mode 100644 libs/tasklet/doc/overview.qbk delete mode 100644 libs/tasklet/doc/synchronization.qbk delete mode 100644 libs/tasklet/doc/tasklet.qbk delete mode 100644 libs/tasklet/doc/tasklet_ref.qbk delete mode 100644 libs/tasklet/doc/todo.qbk delete mode 100644 libs/tasklet/examples/Jamfile.v2 delete mode 100644 libs/tasklet/examples/barrier_mt.cpp delete mode 100644 libs/tasklet/examples/cancel.cpp delete mode 100644 libs/tasklet/examples/future.cpp delete mode 100644 libs/tasklet/examples/future_mt.cpp delete mode 100644 libs/tasklet/examples/interrupt.cpp delete mode 100644 libs/tasklet/examples/join.cpp delete mode 100644 libs/tasklet/examples/migrate_mt.cpp delete mode 100644 libs/tasklet/examples/ping_pong.cpp delete mode 100644 libs/tasklet/examples/ping_pong_mt.cpp delete mode 100644 libs/tasklet/examples/simple.cpp delete mode 100644 libs/tasklet/performance/Jamfile.v2 delete mode 100644 libs/tasklet/performance/bind_processor.hpp delete mode 100644 libs/tasklet/performance/bind_processor_aix.hpp delete mode 100644 libs/tasklet/performance/bind_processor_freebsd.hpp delete mode 100644 libs/tasklet/performance/bind_processor_hpux.hpp delete mode 100644 libs/tasklet/performance/bind_processor_linux.hpp delete mode 100644 libs/tasklet/performance/bind_processor_solaris.hpp delete mode 100644 libs/tasklet/performance/bind_processor_windows.hpp delete mode 100644 libs/tasklet/performance/performance.cpp delete mode 100644 libs/tasklet/performance/performance.hpp delete mode 100644 libs/tasklet/performance/performance_gcc_i386.hpp delete mode 100644 libs/tasklet/performance/performance_gcc_x86-64.hpp delete mode 100644 libs/tasklet/performance/performance_msvc_i386.hpp delete mode 100644 libs/tasklet/src/auto_reset_event.cpp delete mode 100644 libs/tasklet/src/barrier.cpp delete mode 100644 libs/tasklet/src/condition.cpp delete mode 100644 libs/tasklet/src/count_down_event.cpp delete mode 100644 libs/tasklet/src/detail/tasklet_base.cpp delete mode 100644 libs/tasklet/src/manual_reset_event.cpp delete mode 100644 libs/tasklet/src/mutex.cpp delete mode 100644 libs/tasklet/src/round_robin.cpp delete mode 100644 libs/tasklet/src/spin_condition.cpp delete mode 100644 libs/tasklet/src/spin_mutex.cpp delete mode 100644 libs/tasklet/src/strategy.cpp delete mode 100644 libs/tasklet/src/tasklet.cpp delete mode 100644 libs/tasklet/test/Jamfile.v2 delete mode 100644 libs/tasklet/test/condition_test_common.hpp delete mode 100644 libs/tasklet/test/test_auto_reset_event.cpp delete mode 100644 libs/tasklet/test/test_barrier.cpp delete mode 100644 libs/tasklet/test/test_cancel.cpp delete mode 100644 libs/tasklet/test/test_condition.cpp delete mode 100644 libs/tasklet/test/test_count_down_event.cpp delete mode 100644 libs/tasklet/test/test_generic_locks.cpp delete mode 100644 libs/tasklet/test/test_interrupt.cpp delete mode 100644 libs/tasklet/test/test_join.cpp delete mode 100644 libs/tasklet/test/test_lock.cpp delete mode 100644 libs/tasklet/test/test_manual_reset_event.cpp delete mode 100644 libs/tasklet/test/test_mutex.cpp delete mode 100644 libs/tasklet/test/test_priority.cpp delete mode 100644 libs/tasklet/test/test_scheduler.cpp delete mode 100644 libs/tasklet/test/test_spin_condition.cpp delete mode 100644 libs/tasklet/test/test_spin_mutex.cpp delete mode 100644 libs/tasklet/test/test_tasklet.cpp delete mode 100644 libs/tasklet/test/test_unique_lock.cpp delete mode 100644 libs/tasklet/test/test_utility.cpp diff --git a/boost/task.hpp b/boost/task.hpp deleted file mode 100644 index 4e95fb76..00000000 --- a/boost/task.hpp +++ /dev/null @@ -1,44 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_TASKS_H -#define BOOST_TASKS_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#endif // BOOST_TASKS_H - diff --git a/boost/task/as_sub_task.hpp b/boost/task/as_sub_task.hpp deleted file mode 100755 index 8cccd592..00000000 --- a/boost/task/as_sub_task.hpp +++ /dev/null @@ -1,51 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_TASKS_AS_SUB_TASK_H -#define BOOST_TASKS_AS_SUB_TASK_H - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace tasks { - -struct as_sub_task -{ - template< typename R > - handle< R > operator()( BOOST_RV_REF( task< R >) t) - { - detail::worker * w( detail::worker::tss_get() ); - if ( w) - { - spin::promise< R > prom; - spin::shared_future< R > f( prom.get_future() ); - context ctx; - handle< R > h( f, ctx); - w->put( callable( t, boost::move( prom), ctx) ); - return h; - } - else - return new_thread()( t); - } -}; - -}} - -#include - -#endif // BOOST_TASKS_AS_SUB_TASK_H diff --git a/boost/task/async.hpp b/boost/task/async.hpp deleted file mode 100644 index 1a4e1782..00000000 --- a/boost/task/async.hpp +++ /dev/null @@ -1,128 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_TASKS_ASYNC_H -#define BOOST_TASKS_ASYNC_H - -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace tasks { - -template< typename R > -handle< R > async( task< R > t) -{ return async( boost::move( t) ); } - -template< typename R > -handle< R > async( BOOST_RV_REF( task< R >) t) -{ return as_sub_task()( t); } - -template< typename R > -handle< R > async( task< R > t, as_sub_task ast) -{ return async( boost::move( t), ast); } - -template< typename R > -handle< R > async( BOOST_RV_REF( task< R >) t, as_sub_task ast) -{ return ast( t); } - -template< typename R > -handle< R > async( task< R > t, own_thread ot) -{ return async( boost::move( t) ); } - -template< typename R > -handle< R > async( BOOST_RV_REF( task< R >) t, own_thread ot) -{ return ot( t); } - -template< typename R > -handle< R > async( task< R > t, new_thread nt) -{ return async( boost::move( t), nt); } - -template< typename R > -handle< R > async( BOOST_RV_REF( task< R >) t, new_thread nt) -{ return nt( t); } - -template< typename R, typename Queue, typename UMS > -handle< R > async( task< R > t, static_pool< Queue, UMS > & pool) -{ return async( boost::move(t), pool); } - -template< typename R, typename Queue, typename UMS > -handle< R > async( BOOST_RV_REF( task< R >) t, static_pool< Queue, UMS > & pool) -{ return pool.submit( t); } - -template< typename R, typename Attr, typename Queue, typename UMS > -handle< R > async( task< R > t, Attr attr, static_pool< Queue, UMS > & pool) -{ return async( boost::move(t), attr, pool); } - -template< typename R, typename Attr, typename Queue, typename UMS > -handle< R > async( BOOST_RV_REF( task< R >) t, Attr attr, static_pool< Queue, UMS > & pool) -{ return pool.submit( t, attr); } - -template< typename R, typename Strategy > -handle< R > async( - task< R > t, - tasklets::scheduler< Strategy > & sched, - std::size_t stacksize = tasklet::default_stacksize) -{ return async( boost::move( t), sched, stacksize); } - -template< typename R, typename Strategy > -handle< R > async( - BOOST_RV_REF( task< R >) t, - tasklets::scheduler< Strategy > & sched, - std::size_t stacksize = tasklet::default_stacksize) -{ - if ( this_task::runs_in_pool() ) - { - spin::promise< R > prom; - spin::shared_future< R > f( prom.get_future() ); - context ctx; - handle< R > h( f, ctx); - tasklet fib( callable( t, boost::move( prom), ctx), stacksize); - sched.submit_tasklet( boost::move( fib) ); - return h; - } - else - { - promise< R > prom; - shared_future< R > f( prom.get_future() ); - context ctx; - handle< R > h( f, ctx); - tasklet fib( - callable( - t, -// TODO: workaround because thread_move_t will be abigous for move -#ifdef BOOST_HAS_RVALUE_REFS - boost::move( prom), -#else - boost::detail::thread_move_t< promise< R > >( prom), -#endif - ctx), stacksize); - sched.submit_tasklet( boost::move( fib) ); - return h; - } -} - -}} - -#include - -#endif // BOOST_TASKS_ASYNC_H diff --git a/boost/task/bounded_fifo.hpp b/boost/task/bounded_fifo.hpp deleted file mode 100644 index d09e31ed..00000000 --- a/boost/task/bounded_fifo.hpp +++ /dev/null @@ -1,205 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_TASKS_BOUNDED_FIFO_H -#define BOOST_TASKS_BOUNDED_FIFO_H - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace tasks { - -class bounded_fifo -{ -public: - typedef detail::has_no_attribute attribute_tag_type; - typedef callable value_type; - -private: - struct node - { - typedef shared_ptr< node > sptr_t; - - value_type va; - sptr_t next; - }; - - enum state - { - ACTIVE = 0, - DEACTIVE - }; - - atomic< state > state_; - atomic< std::size_t > count_; - node::sptr_t head_; - mutable mutex head_mtx_; - node::sptr_t tail_; - mutable mutex tail_mtx_; - condition not_full_cond_; - std::size_t hwm_; - std::size_t lwm_; - fast_semaphore & fsem_; - - bool active_() const - { return ACTIVE == state_.load(); } - - void deactivate_() - { state_.store( DEACTIVE); } - - std::size_t size_() const - { return count_.load(); } - - bool empty_() const - { return head_ == get_tail_(); } - - bool full_() const - { return size_() >= hwm_; } - - node::sptr_t get_tail_() const - { - lock_guard< mutex > lk( tail_mtx_); - node::sptr_t tmp = tail_; - return tmp; - } - - node::sptr_t pop_head_() - { - node::sptr_t old_head = head_; - head_ = old_head->next; - count_.fetch_sub( 1); - return old_head; - } - -public: - bounded_fifo( - fast_semaphore & fsem, - high_watermark const& hwm, - low_watermark const& lwm) : - state_( ACTIVE), - count_( 0), - head_( new node), - head_mtx_(), - tail_( head_), - tail_mtx_(), - not_full_cond_(), - hwm_( hwm), - lwm_( lwm), - fsem_( fsem) - {} - - std::size_t upper_bound() const - { return hwm_; } - - std::size_t lower_bound() const - { return lwm_; } - - bool active() const - { return active_(); } - - void deactivate() - { - unique_lock< mutex > lk( head_mtx_); - deactivate_(); - not_full_cond_.notify_all(); - } - - bool empty() const - { - unique_lock< mutex > lk( head_mtx_); - return empty_(); - } - - void put( value_type const& va) - { - node::sptr_t new_node( new node); - { - unique_lock< mutex > lk( tail_mtx_); - - if ( full_() ) - { - while ( active_() && full_() ) - not_full_cond_.wait( lk); - } - if ( ! active_() ) - throw task_rejected("queue is not active"); - - tail_->va = va; - tail_->next = new_node; - tail_ = new_node; - count_.fetch_add( 1); - } - fsem_.post(); - } - - template< typename TimeDuration > - void put( - value_type const& va, - TimeDuration const& rel_time) - { - node::sptr_t new_node( new node); - { - unique_lock< mutex > lk( tail_mtx_); - - if ( full_() ) - { - while ( active_() && full_() ) - if ( ! not_full_cond_.wait( lk, rel_time) ) - throw task_rejected("timed out"); - } - if ( ! active_() ) - throw task_rejected("queue is not active"); - - tail_->va = va; - tail_->next = new_node; - tail_ = new_node; - count_.fetch_add( 1); - } - fsem_.post(); - } - - bool try_take( value_type & va) - { - unique_lock< mutex > lk( head_mtx_); - if ( empty_() ) - return false; - va.swap( head_->va); - pop_head_(); - bool valid = ! va.empty(); - if ( valid && size_() <= lwm_) - { - if ( lwm_ == hwm_) - not_full_cond_.notify_one(); - else - // more than one producer could be waiting - // in order to submit an task - not_full_cond_.notify_all(); - } - return valid; - } -}; - -}} - -#include - -#endif // BOOST_TASKS_BOUNDED_FIFO_H diff --git a/boost/task/bounded_prio_queue.hpp b/boost/task/bounded_prio_queue.hpp deleted file mode 100644 index 47978edd..00000000 --- a/boost/task/bounded_prio_queue.hpp +++ /dev/null @@ -1,238 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_TASKS_BOUNDED_PRIO_QUEUE_H -#define BOOST_TASKS_BOUNDED_PRIO_QUEUE_H - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace tasks { - -template< - typename Attr, - typename Comp = std::less< Attr > -> -class bounded_prio_queue -{ -public: - typedef detail::has_attribute attribute_tag_type; - typedef Attr attribute_type; - - struct value_type - { - callable ca; - attribute_type attr; - - value_type( - callable const& ca_, - attribute_type const& attr_) : - ca( ca_), attr( attr_) - { BOOST_ASSERT( ! ca.empty() ); } - - void swap( value_type & other) - { - ca.swap( other.ca); - std::swap( attr, other.attr); - } - }; - -private: - struct compare : public std::binary_function< value_type, value_type, bool > - { - bool operator()( value_type const& va1, value_type const& va2) - { return Comp()( va1.attr, va2.attr); } - }; - - typedef std::priority_queue< - value_type, - std::deque< value_type >, - compare - > queue_type; - - enum state - { - ACTIVE = 0, - DEACTIVE - }; - - atomic< state > state_; - queue_type queue_; - mutable shared_mutex mtx_; - condition not_full_cond_; - std::size_t hwm_; - std::size_t lwm_; - fast_semaphore & fsem_; - - bool active_() const - { return ACTIVE == state_.load(); } - - void deactivate_() - { state_.store( DEACTIVE); } - - bool empty_() const - { return queue_.empty(); } - - bool full_() const - { return size_() >= hwm_; } - - std::size_t size_() const - { return queue_.size(); } - - void put_( - value_type const& va, - unique_lock< shared_mutex > & lk) - { - if ( full_() ) - { - not_full_cond_.wait( - lk, - bind( - & bounded_prio_queue::producers_activate_, - this) ); - } - if ( ! active_() ) - throw task_rejected("queue is not active"); - queue_.push( va); - fsem_.post(); - } - - template< typename TimeDuration > - void put_( - value_type const& va, - TimeDuration const& rel_time, - unique_lock< shared_mutex > & lk) - { - if ( full_() ) - { - if ( ! not_full_cond_.timed_wait( - lk, - rel_time, - bind( - & bounded_prio_queue::producers_activate_, - this) ) ) - throw task_rejected("timed out"); - } - if ( ! active_() ) - throw task_rejected("queue is not active"); - queue_.push( va); - fsem_.post(); - } - - bool try_take_( callable & ca) - { - if ( empty_() ) - return false; - callable tmp( queue_.top().ca); - queue_.pop(); - ca.swap( tmp); - bool valid = ! ca.empty(); - if ( valid && size_() <= lwm_) - { - if ( lwm_ == hwm_) - not_full_cond_.notify_one(); - else - // more than one producer could be waiting - // in order to submit an task - not_full_cond_.notify_all(); - } - return valid; - } - - bool producers_activate_() const - { return ! active_() || ! full_(); } - -public: - bounded_prio_queue( - fast_semaphore & fsem, - high_watermark const& hwm, - low_watermark const& lwm) : - state_( ACTIVE), - queue_(), - mtx_(), - not_full_cond_(), - hwm_( hwm), - lwm_( lwm), - fsem_( fsem) - { - if ( lwm_ > hwm_ ) - throw invalid_watermark(); - } - - bool active() const - { return active_(); } - - void deactivate() - { - unique_lock< shared_mutex > lk( mtx_); - deactivate_(); - not_full_cond_.notify_all(); - } - - bool empty() const - { - shared_lock< shared_mutex > lk( mtx_); - return empty_(); - } - - std::size_t upper_bound() const - { - shared_lock< shared_mutex > lk( mtx_); - return hwm_; - } - - std::size_t lower_bound() const - { - shared_lock< shared_mutex > lk( mtx_); - return lwm_; - } - - void put( value_type const& va) - { - unique_lock< shared_mutex > lk( mtx_); - put_( va, lk); - } - - template< typename TimeDuration > - void put( - value_type const& va, - TimeDuration const& rel_time) - { - unique_lock< shared_mutex > lk( mtx_); - put_( va, rel_time, lk); - } - - bool try_take( callable & ca) - { - unique_lock< shared_mutex > lk( mtx_); - return try_take_( ca); - } -}; - -}} - -#include - -#endif // BOOST_TASKS_BOUNDED_PRIO_QUEUE_H diff --git a/boost/task/bounded_smart_queue.hpp b/boost/task/bounded_smart_queue.hpp deleted file mode 100644 index b982372a..00000000 --- a/boost/task/bounded_smart_queue.hpp +++ /dev/null @@ -1,249 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_TASKS_BOUNDED_SMART_QUEUE_H -#define BOOST_TASKS_BOUNDED_SMART_QUEUE_H - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace tasks { - -template< - typename Attr, - typename Comp, - typename Enq = detail::replace_oldest, - typename Deq = detail::take_oldest -> -class bounded_smart_queue -{ -public: - typedef detail::has_attribute attribute_tag_type; - typedef Attr attribute_type; - - struct value_type - { - callable ca; - attribute_type attr; - - value_type( - callable const& ca_, - attribute_type const& attr_) : - ca( ca_), attr( attr_) - { BOOST_ASSERT( ! ca.empty() ); } - - void swap( value_type & other) - { - ca.swap( other.ca); - std::swap( attr, other.attr); - } - }; - -private: - typedef multi_index::multi_index_container< - value_type, - multi_index::indexed_by< - multi_index::ordered_non_unique< - multi_index::member< - value_type, - Attr, - & value_type::attr - >, - Comp - > - > - > queue_type; - typedef typename queue_type::template nth_index< 0 >::type queue_index; - - enum state - { - ACTIVE = 0, - DEACTIVE - }; - - atomic< state > state_; - queue_type queue_; - queue_index & idx_; - mutable shared_mutex mtx_; - condition not_full_cond_; - Enq enq_op_; - Deq deq_op_; - std::size_t hwm_; - std::size_t lwm_; - fast_semaphore & fsem_; - - bool active_() const - { return ACTIVE == state_.load(); } - - void deactivate_() - { state_.store( DEACTIVE); } - - bool empty_() const - { return queue_.empty(); } - - bool full_() const - { return size_() >= hwm_; } - - std::size_t size_() const - { return queue_.size(); } - - void put_( - value_type const& va, - unique_lock< shared_mutex > & lk) - { - if ( full_() ) - { - not_full_cond_.wait( - lk, - bind( - & bounded_smart_queue::producers_activate_, - this) ); - } - if ( ! active_() ) - throw task_rejected("queue is not active"); - enq_op_( idx_, va); - fsem_.post(); - } - - template< typename TimeDuration > - void put_( - value_type const& va, - TimeDuration const& rel_time, - unique_lock< shared_mutex > & lk) - { - if ( full_() ) - { - if ( ! not_full_cond_.timed_wait( - lk, - rel_time, - bind( - & bounded_smart_queue::producers_activate_, - this) ) ) - throw task_rejected("timed out"); - } - if ( ! active_() ) - throw task_rejected("queue is not active"); - enq_op_( idx_, va); - fsem_.post(); - } - - bool try_take_( callable & ca) - { - if ( empty_() ) - return false; - deq_op_( idx_, ca); - bool valid = ! ca.empty(); - if ( valid && size_() <= lwm_) - { - if ( lwm_ == hwm_) - not_full_cond_.notify_one(); - else - // more than one producer could be waiting - // in order to submit an task - not_full_cond_.notify_all(); - } - return valid; - } - - bool producers_activate_() const - { return ! active_() || ! full_(); } - -public: - bounded_smart_queue( - fast_semaphore & fsem, - high_watermark const& hwm, - low_watermark const& lwm) : - state_( ACTIVE), - queue_(), - idx_( queue_.get< 0 >() ), - mtx_(), - not_full_cond_(), - enq_op_(), - deq_op_(), - hwm_( hwm), - lwm_( lwm), - fsem_( fsem) - { - if ( lwm_ > hwm_ ) - throw invalid_watermark(); - } - - bool active() const - { return active_(); } - - void deactivate() - { - unique_lock< shared_mutex > lk( mtx_); - deactivate_(); - not_full_cond_.notify_all(); - } - - bool empty() const - { - shared_lock< shared_mutex > lk( mtx_); - return empty_(); - } - - std::size_t upper_bound() const - { - shared_lock< shared_mutex > lk( mtx_); - return hwm_; - } - - std::size_t lower_bound() const - { - shared_lock< shared_mutex > lk( mtx_); - return lwm_; - } - - void put( value_type const& va) - { - unique_lock< shared_mutex > lk( mtx_); - put_( va, lk); - } - - template< typename TimeDuration > - void put( - value_type const& va, - TimeDuration const& rel_time) - { - unique_lock< shared_mutex > lk( mtx_); - put_( va, rel_time, lk); - } - - bool try_take( callable & ca) - { - unique_lock< shared_mutex > lk( mtx_); - return try_take_( ca); - } -}; - -}} - -#include - -#endif // BOOST_TASKS_BOUNDED_SMART_QUEUE_H diff --git a/boost/task/callable.hpp b/boost/task/callable.hpp deleted file mode 100755 index 379ce4bf..00000000 --- a/boost/task/callable.hpp +++ /dev/null @@ -1,165 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_TASKS_CALLABLE_H -#define BOOST_TASKS_CALLABLE_H - -#include -#include -#include -#include -#include - -#include -#include - -#include - -# if defined(BOOST_MSVC) -# pragma warning(push) -# pragma warning(disable:4251 4275) -# endif - -namespace boost { -namespace tasks { -namespace detail { - -struct BOOST_TASKS_DECL callable_base -{ - atomic< unsigned int > use_count; - - callable_base() : - use_count( 0) - {} - - virtual ~callable_base() {} - - virtual void run() = 0; - - virtual void reset( shared_ptr< thread > const&) = 0; - - inline friend void intrusive_ptr_add_ref( callable_base * p) - { p->use_count.fetch_add( 1, memory_order_relaxed); } - - inline friend void intrusive_ptr_release( callable_base * p) - { - if ( p->use_count.fetch_sub( 1, memory_order_release) == 1) - { - atomic_thread_fence( memory_order_acquire); - delete p; - } - } -}; - -template< typename Task, typename Promise > -class callable_object : public callable_base -{ -private: - Task t_; - context ctx_; - -public: -#ifdef BOOST_HAS_RVALUE_REFS - callable_object( - Task && t, - Promise && prom, - context const& ctx) : - t_( t), ctx_( ctx) - { t_.set_promise( prom); } -#else - callable_object( - BOOST_RV_REF( Task) t, - boost::detail::thread_move_t< Promise > prom, - context const& ctx) : - t_( t), ctx_( ctx) - { t_.set_promise( prom); } -#endif - - callable_object( - BOOST_RV_REF( Task) t, - BOOST_RV_REF( Promise) prom, - context const& ctx) : - t_( t), ctx_( ctx) - { t_.set_promise( prom); } - - void run() - { t_(); } - - void reset( shared_ptr< thread > const& thrd) - { ctx_.reset( thrd); } -}; - -} - -class BOOST_TASKS_DECL callable -{ -private: - intrusive_ptr< detail::callable_base > base_; - -public: - callable(); - -#ifdef BOOST_HAS_RVALUE_REFS - template< typename Task, typename Promise > - callable( - Task && t, - Promise && prom, - context const& ctx) : - base_( new detail::callable_object< Task, Promise >( t, prom, ctx) ) - {} -#else - template< typename Task, typename Promise > - callable( - BOOST_RV_REF( Task) t, - boost::detail::thread_move_t< Promise > prom, - context const& ctx) : - base_( new detail::callable_object< Task, Promise >( t, prom, ctx) ) - {} -#endif - - template< typename Task, typename Promise > - callable( - BOOST_RV_REF( Task) t, - BOOST_RV_REF( Promise) prom, - context const& ctx) : - base_( new detail::callable_object< Task, Promise >( t, prom, ctx) ) - {} - - void operator()(); - - bool empty() const; - - void clear(); - - void reset( shared_ptr< thread > const&); - - void swap( callable &); -}; - -class context_guard : private noncopyable -{ -private: - callable & ca_; - -public: - context_guard( callable & ca, shared_ptr< thread > const& thrd) : - ca_( ca) - { ca_.reset( thrd); } - - ~context_guard() - { ca_.clear(); } -}; - -}} - -# if defined(BOOST_MSVC) -# pragma warning(pop) -# endif - -#include - -#endif // BOOST_TASKS_CALLABLE_H - diff --git a/boost/task/context.hpp b/boost/task/context.hpp deleted file mode 100644 index f85bbd53..00000000 --- a/boost/task/context.hpp +++ /dev/null @@ -1,94 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_TASKS_CONTEXT_H -#define BOOST_TASKS_CONTEXT_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -# if defined(BOOST_MSVC) -# pragma warning(push) -# pragma warning(disable:4251 4275) -# endif - -namespace boost { -namespace tasks { -namespace detail { - -class BOOST_TASKS_DECL context_base : private noncopyable -{ -private: - atomic< unsigned int > use_count_; - bool requested_; - mutex mtx_; - shared_ptr< thread > thrd_; - - void reset_( shared_ptr< thread > const& thrd); - - void interrupt_(); - -public: - context_base(); - - void reset( shared_ptr< thread > const& thrd); - - void interrupt(); - - bool interruption_requested(); - - inline friend void intrusive_ptr_add_ref( context_base * p) - { p->use_count_.fetch_add( 1, memory_order_relaxed); } - - inline friend void intrusive_ptr_release( context_base * p) - { - if ( p->use_count_.fetch_sub( 1, memory_order_release) == 1) - { - atomic_thread_fence( memory_order_acquire); - delete p; - } - } -}; - -} - -class BOOST_TASKS_DECL context -{ -private: - intrusive_ptr< detail::context_base > base_; - -public: - context(); - - void reset( shared_ptr< thread > const& thrd); - - void interrupt(); - - bool interruption_requested(); - - void swap( context & other); -}; - -}} - -# if defined(BOOST_MSVC) -# pragma warning(pop) -# endif - -#include - -#endif // BOOST_TASKS_DETAIL_context_H diff --git a/boost/task/detail/bind_processor.hpp b/boost/task/detail/bind_processor.hpp deleted file mode 100644 index 01b7d0ef..00000000 --- a/boost/task/detail/bind_processor.hpp +++ /dev/null @@ -1,37 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_TASKS_DETAIL_BIND_PROCESSOR_H -#define BOOST_TASKS_DETAIL_BIND_PROCESSOR_H - -#include - -# if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) -# define BOOST_HAS_PROCESSOR_BINDINGS 1 -# include -# elif defined(linux) || defined(__linux) || defined(__linux__) -# define BOOST_HAS_PROCESSOR_BINDINGS 1 -# include -# elif defined(__IBMCPP__) || defined(_AIX) -# define BOOST_HAS_PROCESSOR_BINDINGS 1 -# include -# elif defined(__hpux) -# define BOOST_HAS_PROCESSOR_BINDINGS 1 -# include -# elif defined(sun) || defined(__sun) -# define BOOST_HAS_PROCESSOR_BINDINGS 1 -# include -# elif defined(__FreeBSD__) -#include -# if (__FreeBSD_version >= 701000) -# define BOOST_HAS_PROCESSOR_BINDINGS 1 -# include -# endif -# else -# undef BOOST_HAS_PROCESSOR_BINDINGS -# endif - -#endif // BOOST_TASKS_DETAIL_BIND_PROCESSOR_H diff --git a/boost/task/detail/bind_processor_aix.hpp b/boost/task/detail/bind_processor_aix.hpp deleted file mode 100644 index 27d51f32..00000000 --- a/boost/task/detail/bind_processor_aix.hpp +++ /dev/null @@ -1,52 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_TASKS_DETAIL_BIND_PROCESSOR_AIX_H -#define BOOST_TASKS_DETAIL_BIND_PROCESSOR_AIX_H - -extern "C" -{ -#include -#include -} - -#include -#include -#include - -#include - -namespace boost { -namespace this_thread { - -inline -void bind_to_processor( unsigned int n) -{ - BOOST_ASSERT( n >= 0); - BOOST_ASSERT( n < boost::thread::hardware_concurrency() ); - - if ( ::bindprocessor( BINDTHREAD, ::thread_self(), static_cast< cpu_t >( n) ) == -1) - throw boost::system::system_error( - boost::system::error_code( - errno, - boost::system::system_category() ) ); -} - -inline -void bind_to_any_processor() -{ - if ( ::bindprocessor( BINDTHREAD, ::thread_self(), PROCESSOR_CLASS_ANY) == -1) - throw boost::system::system_error( - boost::system::error_code( - errno, - boost::system::system_category() ) ); -} - -}} - -#include - -#endif // BOOST_TASKS_DETAIL_BIND_PROCESSOR_AIX_H diff --git a/boost/task/detail/bind_processor_freebsd.hpp b/boost/task/detail/bind_processor_freebsd.hpp deleted file mode 100755 index 0f577ab5..00000000 --- a/boost/task/detail/bind_processor_freebsd.hpp +++ /dev/null @@ -1,63 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_TASKS_DETAIL_BIND_PROCESSOR_FREEBSD_H -#define BOOST_TASKS_DETAIL_BIND_PROCESSOR_FREEBSD_H - -extern "C" -{ -#include -#include -} - -#include -#include -#include - -#include - -namespace boost { -namespace this_thread { - -inline -void bind_to_processor( unsigned int n) -{ - BOOST_ASSERT( n >= 0); - BOOST_ASSERT( n < boost::thread::hardware_concurrency() ); - - cpuset_t cpuset; - CPU_ZERO( & cpuset); - CPU_SET( n, & cpuset); - - if ( ::cpuset_setaffinity( CPU_LEVEL_WHICH, CPU_WHICH_TID, -1, sizeof( cpuset), & cpuset) == -1) - throw boost::system::system_error( - boost::system::error_code( - errno, - boost::system::system_category() ) ); -} - -inline -void bind_to_any_processor() -{ - cpuset_t cpuset; - CPU_ZERO( & cpuset); - - unsigned int max( boost::thread::hardware_concurrency() ); - for ( unsigned int i( 0); i < max; ++i) - CPU_SET( i, & cpuset); - - if ( ::cpuset_setaffinity( CPU_LEVEL_WHICH, CPU_WHICH_TID, -1, sizeof( cpuset), & cpuset) == -1) - throw boost::system::system_error( - boost::system::error_code( - errno, - boost::system::system_category() ) ); -} - -}} - -#include - -#endif // BOOST_TASKS_DETAIL_BIND_PROCESSOR_FREEBSD_H diff --git a/boost/task/detail/bind_processor_hpux.hpp b/boost/task/detail/bind_processor_hpux.hpp deleted file mode 100644 index 7a816097..00000000 --- a/boost/task/detail/bind_processor_hpux.hpp +++ /dev/null @@ -1,65 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_TASKS_DETAIL_BIND_PROCESSOR_HPUX_H -#define BOOST_TASKS_DETAIL_BIND_PROCESSOR_HPUX_H - -extern "C" -{ -#include -} - -#include -#include -#include - -#include - -namespace boost { -namespace this_thread { - -inline -void bind_to_processor( unsigned int n) -{ - BOOST_ASSERT( n >= 0); - BOOST_ASSERT( n < boost::thread::hardware_concurrency() ); - - ::pthread_spu_t spu; - int errno_( - ::pthread_processor_bind_np( - PTHREAD_BIND_FORCED_NP, - & spu, - static_cast< pthread_spu_t >( n), - PTHREAD_SELFTID_NP) ); - if ( errno_ != 0) - throw boost::system::system_error( - boost::system::error_code( - errno_, - boost::system::system_category() ) ); -} - -inline -void bind_to_any_processor() -{ - ::pthread_spu_t spu; - int errno_( - ::pthread_processor_bind_np( - PTHREAD_BIND_FORCED_NP, - & spu, - PTHREAD_SPUFLOAT_NP, - PTHREAD_SELFTID_NP) ); - if ( errno_ != 0) - throw boost::system::system_error( - boost::system::error_code( - errno_, - boost::system::system_category() ) ); -} - -}} - -#include - -#endif // BOOST_TASKS_DETAIL_BIND_PROCESSOR_HPUX_H diff --git a/boost/task/detail/bind_processor_linux.hpp b/boost/task/detail/bind_processor_linux.hpp deleted file mode 100644 index 13e09385..00000000 --- a/boost/task/detail/bind_processor_linux.hpp +++ /dev/null @@ -1,66 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_TASKS_DETAIL_BIND_PRCESSOR_LINUX_H -#define BOOST_TASKS_DETAIL_BIND_PRCESSOR_LINUX_H - -extern "C" -{ -#include -#include -} - -#include -#include -#include - -#include - -namespace boost { -namespace this_thread { - -inline -void bind_to_processor( unsigned int n) -{ - BOOST_ASSERT( n >= 0); - BOOST_ASSERT( n < CPU_SETSIZE); - BOOST_ASSERT( n < boost::thread::hardware_concurrency() ); - - cpu_set_t cpuset; - CPU_ZERO( & cpuset); - CPU_SET( n, & cpuset); - - int errno_( ::pthread_setaffinity_np( ::pthread_self(), sizeof( cpuset), & cpuset) ); - if ( errno_ != 0) - throw boost::system::system_error( - boost::system::error_code( - errno_, - boost::system::system_category() ) ); -} - -inline -void bind_to_any_processor() -{ - cpu_set_t cpuset; - CPU_ZERO( & cpuset); - - unsigned int max( boost::thread::hardware_concurrency() ); - for ( unsigned int i( 0); i < max; ++i) - CPU_SET( i, & cpuset); - - int errno_( ::pthread_setaffinity_np( ::pthread_self(), sizeof( cpuset), & cpuset) ); - if ( errno_ != 0) - throw boost::system::system_error( - boost::system::error_code( - errno_, - boost::system::system_category() ) ); -} - -}} - -#include - -#endif // BOOST_TASKS_DETAIL_BIND_PRCESSOR_LINUX_H diff --git a/boost/task/detail/bind_processor_solaris.hpp b/boost/task/detail/bind_processor_solaris.hpp deleted file mode 100644 index eaa40e84..00000000 --- a/boost/task/detail/bind_processor_solaris.hpp +++ /dev/null @@ -1,53 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_TASKS_DETAIL_BIND_PROCESSOR_SOLARIS_H -#define BOOST_TASKS_DETAIL_BIND_PROCESSOR_SOLARIS_H - -extern "C" -{ -#include -#include -#include -} - -#include -#include -#include - -#include - -namespace boost { -namespace this_thread { - -inline -void bind_to_processor( unsigned int n) -{ - BOOST_ASSERT( n >= 0); - BOOST_ASSERT( n < boost::thread::hardware_concurrency() ); - - if ( ::processor_bind( P_LWPID, P_MYID, static_cast< processorid_t >( n), 0) == -1) - throw boost::system::system_error( - boost::system::error_code( - errno, - boost::system::system_category() ) ); -} - -inline -void bind_to_any_processor() -{ - if ( ::processor_bind( P_LWPID, P_MYID, PBIND_NONE, 0) == -1) - throw boost::system::system_error( - boost::system::error_code( - errno, - boost::system::system_category() ) ); -} - -}} - -#include - -#endif // BOOST_TASKS_DETAIL_BIND_PROCESSOR_SOLARIS_H diff --git a/boost/task/detail/bind_processor_windows.hpp b/boost/task/detail/bind_processor_windows.hpp deleted file mode 100644 index c864c08c..00000000 --- a/boost/task/detail/bind_processor_windows.hpp +++ /dev/null @@ -1,55 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_TASKS_DETAIL_BIND_PROCESSOR_WINDOWS_H -#define BOOST_TASKS_DETAIL_BIND_PROCESSOR_WINDOWS_H - -extern "C" -{ -#include -} - -#include -#include -#include - -#include - -namespace boost { -namespace this_thread { - -inline -void bind_to_processor( unsigned int n) -{ - BOOST_ASSERT( n >= 0); - BOOST_ASSERT( n < boost::thread::hardware_concurrency() ); - - if ( ::SetThreadAffinityMask( ::GetCurrentThread(), ( DWORD_PTR)1 << n) == 0) - throw boost::system::system_error( - boost::system::error_code( - ::GetLastError(), - boost::system::system_category() ) ); -} - -inline -void bind_to_any_processor() -{ - DWORD_PTR ptr( 1); - for ( unsigned int i( 0); i < boost::thread::hardware_concurrency(); ++i) - ptr = ptr << i; - - if ( ::SetThreadAffinityMask( ::GetCurrentThread(), ptr) == 0) - throw boost::system::system_error( - boost::system::error_code( - ::GetLastError(), - boost::system::system_category() ) ); -} - -}} - -#include - -#endif // BOOST_TASKS_DETAIL_BIND_PROCESSOR_WINDOWS_H diff --git a/boost/task/detail/config.hpp b/boost/task/detail/config.hpp deleted file mode 100644 index f1629b29..00000000 --- a/boost/task/detail/config.hpp +++ /dev/null @@ -1,80 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// this file is based on config.hpp of boost.thread - -#ifndef BOOST_TASKS_DETAIL_CONFIG_H -#define BOOST_TASKS_DETAIL_CONFIG_H - -#include -#include - -# if BOOST_WORKAROUND(__BORLANDC__, < 0x600) -# pragma warn -8008 // Condition always true/false -# pragma warn -8080 // Identifier declared but never used -# pragma warn -8057 // Parameter never used -# pragma warn -8066 // Unreachable code -# endif - -# if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_TASKS_DYN_LINK) -# undef BOOST_TASKS_USE_LIB -# define BOOST_TASKS_USE_DLL -# endif - -# if defined(BOOST_TASKS_BUILD_DLL) //Build dll -# elif defined(BOOST_TASKS_BUILD_LIB) //Build lib -# elif defined(BOOST_TASKS_USE_DLL) //Use dll -# elif defined(BOOST_TASKS_USE_LIB) //Use lib -# else //Use default -# if defined(BOOST_TASKS_PLATFORM_WIN32) -# if defined(BOOST_MSVC) || defined(BOOST_INTEL_WIN) - //For compilers supporting auto-tss cleanup - //with Boost.Threads lib, use Boost.Threads lib -# define BOOST_TASKS_USE_LIB -# else - //For compilers not yet supporting auto-tss cleanup - //with Boost.Threads lib, use Boost.Threads dll -# define BOOST_TASKS_USE_DLL -# endif -# else -# define BOOST_TASKS_USE_LIB -# endif -# endif - -# if defined(BOOST_HAS_DECLSPEC) -# if defined(BOOST_TASKS_BUILD_DLL) //Build dll -# define BOOST_TASKS_DECL __declspec(dllexport) -# elif defined(BOOST_TASKS_USE_DLL) //Use dll -# define BOOST_TASKS_DECL __declspec(dllimport) -# else -# define BOOST_TASKS_DECL -# endif -# else -# define BOOST_TASKS_DECL -# endif - -// Automatically link to the correct build variant where possible. -# if ! defined(BOOST_ALL_NO_LIB) && ! defined(BOOST_TASKS_NO_LIB) && ! defined(BOOST_TASKS_BUILD_DLL) && ! defined(BOOST_TASKS_BUILD_LIB) - -// Tell the autolink to link dynamically, this will get undef'ed by auto_link.hpp -# if defined(BOOST_TASKS_USE_DLL) -# define BOOST_DYN_LINK -# endif - -// Set the name of our library, this will get undef'ed by auto_link.hpp -# if defined(BOOST_TASKS_LIB_NAME) -# define BOOST_LIB_NAME BOOST_TASKS_LIB_NAME -# else -# define BOOST_LIB_NAME boost_task -# endif - -// If we're importing code from a dll, then tell auto_link.hpp about it -// And include the header that does the work -#include -# endif // auto-linking disabled - -#endif // BOOST_TASKS_DETAIL_CONFIG_H - diff --git a/boost/task/detail/future_traits.hpp b/boost/task/detail/future_traits.hpp deleted file mode 100644 index ecd1970b..00000000 --- a/boost/task/detail/future_traits.hpp +++ /dev/null @@ -1,82 +0,0 @@ -// (C) Copyright 2008-9 Anthony Williams -// -// Distributed under the Boost Software License, Version 1.0. (See -// accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_TASKS_DETAIL_FUTURE_TRAITSHPP -#define BOOST_TASKS_DETAIL_FUTURE_TRAITSHPP - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -namespace boost { -namespace tasks { -namespace detail { - -template -struct future_traits -{ - typedef boost::scoped_ptr storage_type; -#ifdef BOOST_HAS_RVALUE_REFS - typedef T const& source_reference_type; - struct dummy; - typedef typename boost::mpl::if_,dummy&,T&&>::type rvalue_source_type; - typedef typename boost::mpl::if_,T,T&&>::type move_dest_type; -#else - typedef T& source_reference_type; - typedef typename boost::mpl::if_, BOOST_RV_REF( T),T const&>::type rvalue_source_type; - typedef typename boost::mpl::if_,BOOST_RV_REF( T),T>::type move_dest_type; -#endif - - static void init(storage_type& storage,source_reference_type t) - { storage.reset(new T(t)); } - - static void init(storage_type& storage,rvalue_source_type t) - { storage.reset(new T(static_cast(t))); } - - static void cleanup(storage_type& storage) - { storage.reset(); } -}; - -template -struct future_traits -{ - typedef T* storage_type; - typedef T& source_reference_type; - struct rvalue_source_type {}; - typedef T& move_dest_type; - - static void init(storage_type& storage,T& t) - { storage=&t; } - - static void cleanup(storage_type& storage) - { storage=0; } -}; - -template<> -struct future_traits -{ - typedef bool storage_type; - typedef void move_dest_type; - - static void init(storage_type& storage) - { storage=true; } - - static void cleanup(storage_type& storage) - { storage=false; } -}; - -}}} - -#endif // BOOST_TASKS_DETAIL_FUTURE_TRAITS_H diff --git a/boost/task/detail/meta.hpp b/boost/task/detail/meta.hpp deleted file mode 100644 index b3639d20..00000000 --- a/boost/task/detail/meta.hpp +++ /dev/null @@ -1,27 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_TASKS_DETAIL_INFO_H -#define BOOST_TASKS_DETAIL_INFO_H - -#include - -namespace boost { -namespace tasks { -namespace detail { - -struct has_attribute -{}; - -struct has_no_attribute -{}; - -}}} - -#include - -#endif // BOOST_TASKS_DETAIL_INFO_H - diff --git a/boost/task/detail/pool_base.hpp b/boost/task/detail/pool_base.hpp deleted file mode 100755 index d17baeba..00000000 --- a/boost/task/detail/pool_base.hpp +++ /dev/null @@ -1,369 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_TASKS_DETAIL_POOL_BASE_H -#define BOOST_TASKS_DETAIL_POOL_BASE_H - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace tasks { -namespace detail { - -template< - typename Queue, - typename UMS -> -class pool_base -{ -private: - friend class worker; - template< typename T, typename Z > - friend class worker_object; - template< typename T, typename Z > - friend void intrusive_ptr_add_ref( pool_base< T, Z > * p); - template< typename T, typename Z > - friend void intrusive_ptr_release( pool_base< T, Z > * p); - - typedef Queue queue_type; - typedef typename queue_type::value_type value_type; - typedef UMS ums_type; - - enum state - { - ACTIVE = 0, - DEACTIVE - }; - - fast_semaphore fsem_; - atomic< unsigned int > use_count_; - worker_group wg_; - shared_mutex mtx_wg_; - atomic< state > state_; - queue_type queue_; - atomic< bool > shtdwn_; - atomic< bool > shtdwn_now_; - - void worker_entry_() - { - shared_lock< shared_mutex > lk( mtx_wg_); - typename detail::worker_group::iterator i( wg_.find( this_thread::get_id() ) ); - lk.unlock(); - BOOST_ASSERT( i != wg_.end() ); - - worker w( * i); - w.run(); - } - - void create_worker_( - poolsize const& psize, - stacksize const& stack_size) - { - wg_.insert( - worker( - * this, - psize, - stack_size, - boost::bind( - & pool_base::worker_entry_, - this) ) ); - } - -# if defined(BOOST_HAS_PROCESSOR_BINDINGS) - void worker_entry_( std::size_t n) - { - this_thread::bind_to_processor( n); - worker_entry_(); - } - - void create_worker_( - poolsize const& psize, - stacksize const& stack_size, - std::size_t n) - { - wg_.insert( - worker( - * this, - psize, - stack_size, - boost::bind( - & pool_base::worker_entry_, - this, - n) ) ); - } -# endif - - std::size_t size_() const - { return wg_.size(); } - - bool deactivated_() const - { return DEACTIVE == state_.load(); } - - bool deactivate_() - { return ACTIVE == state_.exchange( DEACTIVE); } - -public: - explicit pool_base( - poolsize const& psize, - stacksize const& stack_size) : - fsem_( 0), - use_count_( 0), - wg_(), - mtx_wg_(), - state_( ACTIVE), - queue_( fsem_), - shtdwn_( false), - shtdwn_now_( false) - { - lock_guard< shared_mutex > lk( mtx_wg_); - for ( std::size_t i( 0); i < psize; ++i) - create_worker_( psize, stack_size); - } - - explicit pool_base( - poolsize const& psize, - high_watermark const& hwm, - low_watermark const& lwm, - stacksize const& stack_size) : - fsem_( 0), - use_count_( 0), - wg_(), - mtx_wg_(), - state_( ACTIVE), - queue_( fsem_, hwm, lwm), - shtdwn_( false), - shtdwn_now_( false) - { - lock_guard< shared_mutex > lk( mtx_wg_); - for ( std::size_t i( 0); i < psize; ++i) - create_worker_( psize, stack_size); - } - -# if defined(BOOST_HAS_PROCESSOR_BINDINGS) - explicit pool_base( stacksize const& stack_size) : - fsem_( 0), - use_count_( 0), - wg_(), - mtx_wg_(), - state_( ACTIVE), - queue_( fsem_), - shtdwn_( false), - shtdwn_now_( false) - { - poolsize psize( thread::hardware_concurrency() ); - BOOST_ASSERT( psize > 0); - lock_guard< shared_mutex > lk( mtx_wg_); - for ( std::size_t i( 0); i < psize; ++i) - create_worker_( psize, stack_size, i); - } - - explicit pool_base( - high_watermark const& hwm, - low_watermark const& lwm, - stacksize const& stack_size) : - fsem_( 0), - use_count_( 0), - wg_(), - mtx_wg_(), - state_( ACTIVE), - queue_( fsem_, hwm, lwm), - shtdwn_( false), - shtdwn_now_( false) - { - poolsize psize( thread::hardware_concurrency() ); - BOOST_ASSERT( psize > 0); - lock_guard< shared_mutex > lk( mtx_wg_); - for ( std::size_t i( 0); i < psize; ++i) - create_worker_( psize, stack_size, i); - } -# endif - - ~pool_base() - { shutdown(); } - - void interrupt_all_worker() - { - if ( deactivated_() ) return; - - shared_lock< shared_mutex > lk( mtx_wg_); - wg_.interrupt_all(); - } - - void shutdown() - { - if ( deactivated_() || ! deactivate_() ) return; - - queue_.deactivate(); - fsem_.deactivate(); - shared_lock< shared_mutex > lk( mtx_wg_); - shtdwn_.store( true); - wg_.join_all(); - } - - const void shutdown_now() - { - if ( deactivated_() || ! deactivate_() ) return; - - queue_.deactivate(); - fsem_.deactivate(); - shared_lock< shared_mutex > lk( mtx_wg_); - shtdwn_now_.store( true); - wg_.interrupt_all(); - wg_.join_all(); - } - - std::size_t size() - { - shared_lock< shared_mutex > lk( mtx_wg_); - return size_(); - } - - bool closed() - { return deactivated_(); } - - std::size_t upper_bound() - { return queue_.upper_bound(); } - - void upper_bound( high_watermark const& hwm) - { queue_.upper_bound( hwm); } - - std::size_t lower_bound() - { return queue_.lower_bound(); } - - void lower_bound( low_watermark const lwm) - { queue_.lower_bound( lwm); } - - template< typename R > - handle< R > submit( BOOST_RV_REF( task< R >) t) - { - if ( deactivated_() ) - throw task_rejected("pool is closed"); - - if ( this_task::runs_in_pool() ) - { - spin::promise< R > prom; - spin::shared_future< R > f( prom.get_future() ); - context ctx; - handle< R > h( f, ctx); - queue_.put( callable( t, boost::move( prom), ctx) ); - return h; - } - else - { - promise< R > prom; - shared_future< R > f( prom.get_future() ); - context ctx; - handle< R > h( f, ctx); - queue_.put( - callable( - t, -// TODO: workaround because thread_move_t will be abigous for move -#ifdef BOOST_HAS_RVALUE_REFS - boost::move( prom), -#else - boost::detail::thread_move_t< promise< R > >( prom), -#endif - ctx) ); - return h; - } - } - - template< typename R, typename Attr > - handle< R > submit( BOOST_RV_REF( task< R >) t, Attr const& attr) - { - if ( deactivated_() ) - throw task_rejected("pool is closed"); - - if ( this_task::runs_in_pool() ) - { - spin::promise< R > prom; - spin::shared_future< R > f( prom.get_future() ); - context ctx; - handle< R > h( f, ctx); - queue_.put( - value_type( - callable( t, boost::move( prom), ctx), - attr) ); - return h; - } - else - { - promise< R > prom; - shared_future< R > f( prom.get_future() ); - // TODO: if boost.thread uses boost.move - // use boost::move() - context ctx; - handle< R > h( f, ctx); - queue_.put( - value_type( - callable( - t, -// TODO: workaround because thread_move_t will be abigous for move -#ifdef BOOST_HAS_RVALUE_REFS - boost::move( prom), -#else - boost::detail::thread_move_t< promise< R > >( prom), -#endif - ctx), - attr) ); - return h; - } - } -}; - -template< - typename Queue, - typename UMS -> -void intrusive_ptr_add_ref( pool_base< Queue, UMS > * p) -{ p->use_count_.fetch_add( 1, memory_order_relaxed); } - -template< - typename Queue, - typename UMS -> -void intrusive_ptr_release( pool_base< Queue, UMS > * p) -{ - if ( p->use_count_.fetch_sub( 1, memory_order_release) == 1) - { - atomic_thread_fence( memory_order_acquire); - delete p; - } -} - -}}} - -#include - -#endif // BOOST_TASKS_DETAIL_POOL_BASE_H - diff --git a/boost/task/detail/smart.hpp b/boost/task/detail/smart.hpp deleted file mode 100755 index 2aa1947c..00000000 --- a/boost/task/detail/smart.hpp +++ /dev/null @@ -1,67 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_DETAIL_SMART_H -#define BOOST_DETAIL_SMART_H - -#include - -#include - -namespace boost { -namespace tasks { -namespace detail { - -struct replace_oldest -{ - template< - typename PrioIndex, - typename Value - > - void operator()( PrioIndex & idx, Value const& va) - { - typedef typename PrioIndex::iterator iterator; - iterator i( idx.find( va.attr) ); - if ( i == idx.end() ) - idx.insert( va); - else - idx.replace( i, va); - } -}; - -struct take_oldest -{ - class swapper - { - private: - callable & ca_; - - public: - swapper( callable & ca) : - ca_( ca) - {} - - template< typename Value > - void operator()( Value & va) - { ca_.swap( va.ca); } - }; - - template< typename PrioIndex > - void operator()( PrioIndex & idx, callable & ca) - { - typedef typename PrioIndex::iterator iterator; - iterator i( idx.begin() ); - BOOST_ASSERT( i != idx.end() ); - idx.modify( i, swapper( ca) ); - idx.erase( i); - } -}; - -}}} - -#include - -#endif // BOOST_TASKS_DETAIL_SMART_H diff --git a/boost/task/detail/worker.hpp b/boost/task/detail/worker.hpp deleted file mode 100644 index 45c6a7f7..00000000 --- a/boost/task/detail/worker.hpp +++ /dev/null @@ -1,279 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_TASKS_DETAIL_WORKER_H -#define BOOST_TASKS_DETAIL_WORKER_H - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include - -# if defined(BOOST_MSVC) -# pragma warning(push) -# pragma warning(disable:4251 4275) -# endif - -namespace boost { -namespace tasks { -namespace detail { - -struct worker_base -{ - virtual ~worker_base() {} - - virtual const thread::id get_id() const = 0; - - virtual void join() const = 0; - - virtual void interrupt() const = 0; - - virtual void put( callable const&) = 0; - - virtual bool try_steal( callable &) = 0; - - virtual void run() = 0; - - virtual void yield() = 0; -}; - -template< - typename Pool, - typename Worker -> -class worker_object : public worker_base, - private noncopyable -{ -private: - class random_idx - { - private: - rand48 rng_; - uniform_int<> six_; - variate_generator< rand48 &, uniform_int<> > die_; - - public: - random_idx( std::size_t size) : - rng_(), - six_( 0, size - 1), - die_( rng_, six_) - {} - - std::size_t operator()() - { return die_(); } - }; - - typedef shared_ptr< thread > thread_t; - - Pool & pool_; - thread_t thrd_; - tasklets::scheduler< - typename Pool::ums_type > * sched_;// TODO: make not as pointer if WIN32 Fiber API is replaced by assembler - - wsq wsq_; - bool shtdwn_; - std::size_t stack_size_; - random_idx rnd_idx_; - - void execute_( callable & ca) - { - BOOST_ASSERT( ! ca.empty() ); - { - context_guard lk( ca, thrd_); - ca(); - } - ca.clear(); - BOOST_ASSERT( ca.empty() ); - } - - bool try_take_global_callable_( callable & ca) - { return pool_.queue_.try_take( ca); } - - bool try_take_local_callable_( callable & ca) - { return wsq_.try_take( ca); } - - bool try_steal_other_callable_( callable & ca) - { - std::size_t idx( rnd_idx_() ); - for ( std::size_t j( 0); j < pool_.wg_.size(); ++j) - { - Worker other( pool_.wg_[idx]); - if ( this_thread::get_id() == other.get_id() ) continue; - if ( ++idx >= pool_.wg_.size() ) idx = 0; - if ( other.try_steal( ca) ) - return true; - } - return false; - } - - void run_() - { - while ( ! shutdown_() ) - { - callable ca; - if ( try_take_local_callable_( ca) || - try_steal_other_callable_( ca) || - try_take_global_callable_( ca) ) - { - execute_( ca); - if ( 0 < sched_->ready() ) return; - } - else - { - if ( 0 < sched_->ready() ) return; - pool_.fsem_.wait(); - } - } - } - - bool shutdown_() - { - if ( shutdown__() && pool_.queue_.empty() && 0 == sched_->ready() ) - return true; - else if ( shutdown_now__() ) - return true; - return false; - } - - bool shutdown__() - { - if ( ! shtdwn_) - shtdwn_ = pool_.shtdwn_; - return shtdwn_; - } - - bool shutdown_now__() - { return pool_.shtdwn_now_; } - -public: - worker_object( - Pool & pool, - poolsize const& psize, - stacksize const& stack_size, - function< void() > const& fn) : - pool_( pool), - thrd_( new thread( fn) ), - sched_(), - wsq_( pool_.fsem_), - shtdwn_( false), - stack_size_( stack_size), - rnd_idx_( psize) - { BOOST_ASSERT( ! fn.empty() ); } - - ~worker_object() - { delete sched_; } - - const thread::id get_id() const - { return thrd_->get_id(); } - - void join() const - { thrd_->join(); } - - void - interrupt() const - { thrd_->interrupt(); } - - void put( callable const& ca) - { - BOOST_ASSERT( ! ca.empty() ); - wsq_.put( ca); - } - - bool try_steal( callable & ca) - { return wsq_.try_steal( ca); } - - void run() - { -// TODO: remove if WIN32 Fiber API is replaced by assembler - sched_ = new tasklets::scheduler< typename Pool::ums_type >(); - - BOOST_ASSERT( get_id() == this_thread::get_id() ); - - sched_->submit_tasklet( - tasklets::make_tasklet( - bind( - & worker_object::run_, - this), - stack_size_) ); - while ( ! shutdown_() ) - sched_->run(); - } - - void yield() - { - sched_->submit_tasklet( - tasklets::make_tasklet( - bind( - & worker_object::run_, - this), - stack_size_) ); - this_tasklet::yield(); - } -}; - -class BOOST_TASKS_DECL worker -{ -private: - static thread_specific_ptr< worker > tss_; - - shared_ptr< worker_base > impl_; - -public: - template< typename Pool > - worker( - Pool & pool, - poolsize const& psize, - stacksize const& stack_size, - function< void() > const& fn) : - impl_( - new worker_object< Pool, worker >( - pool, - psize, - stack_size, - fn) ) - {} - - const thread::id get_id() const; - - void join() const; - - void interrupt() const; - - void put( callable const&); - - bool try_steal( callable &); - - void run(); - - void yield(); - - static worker * tss_get(); -}; - -}}} - -# if defined(BOOST_MSVC) -# pragma warning(pop) -# endif - -#include - -#endif // BOOST_TASKS_DETAIL_WORKER_H - diff --git a/boost/task/detail/worker_group.hpp b/boost/task/detail/worker_group.hpp deleted file mode 100644 index db917544..00000000 --- a/boost/task/detail/worker_group.hpp +++ /dev/null @@ -1,101 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_TASKS_DETAIL_WORKER_GROUP_H -#define BOOST_TASKS_DETAIL_WORKER_GROUP_H - -#include - -#include -#include -#include -#include -#include - -#include -#include - -#include - -# if defined(BOOST_MSVC) -# pragma warning(push) -# pragma warning(disable:4251 4275) -# endif - -namespace boost { -namespace tasks { -namespace detail { - -class BOOST_TASKS_DECL worker_group -{ -private: - struct id_idx_tag {}; - struct rnd_idx_tag {}; - - typedef multi_index::multi_index_container< - worker, - multi_index::indexed_by< - multi_index::ordered_unique< - multi_index::tag< id_idx_tag >, - multi_index::const_mem_fun< - worker, - const thread::id, - & worker::get_id - > - >, - multi_index::random_access< multi_index::tag< rnd_idx_tag > > - > - > container; - - typedef container::index< id_idx_tag >::type id_idx; - typedef container::index< rnd_idx_tag >::type rnd_idx; - - container cont_; - id_idx & id_idx_; - rnd_idx & rnd_idx_; - - -public: - typedef id_idx::iterator iterator; - typedef id_idx::const_iterator const_iterator; - - worker_group(); - - ~worker_group(); - - std::size_t size() const; - - bool empty() const; - - const worker operator[]( std::size_t pos) const; - - const iterator begin(); - const const_iterator begin() const; - - const iterator end(); - const const_iterator end() const; - - const const_iterator find( thread::id const& id) const; - - void insert( worker const& w); - - iterator erase( iterator const& i); - - void join_all(); - - void interrupt_all(); -}; - -}}} - -# if defined(BOOST_MSVC) -# pragma warning(pop) -# endif - -#include - -#endif // BOOST_TASKS_DETAIL_WORKER_GROUP_H - diff --git a/boost/task/detail/wsq.hpp b/boost/task/detail/wsq.hpp deleted file mode 100644 index c5876195..00000000 --- a/boost/task/detail/wsq.hpp +++ /dev/null @@ -1,65 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_TASKS_DETAIL_WSQ_H -#define BOOST_TASKS_DETAIL_WSQ_H - -#include -#include -#include -#include - -#include -#include -#include - -#include - -# if defined(BOOST_MSVC) -# pragma warning(push) -# pragma warning(disable:4251 4275) -# endif - -namespace boost { -namespace tasks { -namespace detail { - -class BOOST_TASKS_DECL wsq : private noncopyable -{ -private: - const int initial_size_; - shared_array< callable > array_; - int capacity_; - int mask_; - atomic< unsigned int > head_idx_; - atomic< unsigned int > tail_idx_; - recursive_mutex mtx_; - fast_semaphore & fsem_; - -public: - wsq( fast_semaphore & fsem); - - bool empty() const; - - std::size_t size() const; - - void put( callable const&); - - bool try_take( callable &); - - bool try_steal( callable &); -}; - -}}} - -# if defined(BOOST_MSVC) -# pragma warning(pop) -# endif - -#include - -#endif // BOOST_TASKS_DETAIL_WSQ_H - diff --git a/boost/task/exceptions.hpp b/boost/task/exceptions.hpp deleted file mode 100644 index 5daeab86..00000000 --- a/boost/task/exceptions.hpp +++ /dev/null @@ -1,105 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_TASKS_EXCEPTIONS_H -#define BOOST_TASKS_EXCEPTIONS_H - -#include -#include - -#include - -namespace boost { -namespace tasks { - -class invalid_poolsize : public std::invalid_argument -{ -public: - invalid_poolsize() : - std::invalid_argument("core poolsize must be greater than zero") - {} -}; - -class invalid_stacksize : public std::invalid_argument -{ -public: - invalid_stacksize() : - std::invalid_argument("stacksize must be greater than zero") - {} -}; - -class invalid_watermark : public std::invalid_argument -{ -public: - invalid_watermark() : - std::invalid_argument("invalid watermark") - {} -}; - -class task_uninitialized : public std::logic_error -{ -public: - task_uninitialized() : - std::logic_error("task uninitialized") - {} -}; - -class task_already_executed : public std::logic_error -{ -public: - task_already_executed() : - std::logic_error("task already executed") - {} -}; - -class task_moved : public std::logic_error -{ -public: - task_moved() : - std::logic_error("task moved") - {} -}; - -class broken_task : public std::logic_error -{ -public: - broken_task() : - std::logic_error("broken task") - {} -}; - -struct task_interrupted -{}; - -class task_rejected : public std::runtime_error -{ -public: - task_rejected( std::string const& msg) : - std::runtime_error( msg) - {} -}; - -class pool_moved : public std::logic_error -{ -public: - pool_moved() : - std::logic_error("pool moved") - {} -}; - -class lock_error : public std::logic_error -{ -public: - lock_error() : - std::logic_error("lock invalid") - {} -}; - -}} - -#include - -#endif // BOOST_TASKS_EXCEPTIONS_H diff --git a/boost/task/fast_semaphore.hpp b/boost/task/fast_semaphore.hpp deleted file mode 100755 index da91a272..00000000 --- a/boost/task/fast_semaphore.hpp +++ /dev/null @@ -1,48 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_TASK_FAST_SEMAPHORE_H -#define BOOST_TASK_FAST_SEMAPHORE_H - -#include - -#include -#include - -#include - -#include - -namespace boost { -namespace tasks { - -class BOOST_TASKS_DECL fast_semaphore : private boost::noncopyable -{ -private: - unsigned int spin_count_; - atomic< int > sem_count_; - atomic< bool > sem_active_; - semaphore sem_; - -public: - fast_semaphore( int, unsigned int = 0); - - ~fast_semaphore(); - - void post( int = 1); - - void wait(); - - bool try_wait(); - - void deactivate(); -}; - -}} - -#include - -#endif // BOOST_TASK_FAST_SEMAPHORE_H diff --git a/boost/task/handle.hpp b/boost/task/handle.hpp deleted file mode 100644 index d25854db..00000000 --- a/boost/task/handle.hpp +++ /dev/null @@ -1,285 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) -// -// parts are based on boost.future by Anthony Williams - -#ifndef BOOST_TASKS_HANDLE_H -#define BOOST_TASKS_HANDLE_H - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -namespace boost { -namespace tasks { -namespace detail { - -template< typename R > -struct handle_base -{ - template< typename X > - friend void intrusive_ptr_add_ref( handle_base< X > *); - template< typename X > - friend void intrusive_ptr_release( handle_base< X > *); - - typedef intrusive_ptr< handle_base > ptr; - - atomic< unsigned int > use_count; - - virtual ~handle_base() {} - - virtual void interrupt() = 0; - - virtual void interrupt_and_wait() = 0; - - virtual bool interrupt_and_wait_until( system_time const& abs_time) = 0; - - virtual bool interruption_requested() = 0; - - virtual R get() = 0; - - virtual bool is_ready() const = 0; - - virtual bool has_value() const = 0; - - virtual bool has_exception() const = 0; - - virtual void wait() const = 0; - - virtual bool wait_until( system_time const& abs_time) const = 0; -}; - -template< typename R > -void intrusive_ptr_add_ref( handle_base< R > * p) -{ p->use_count.fetch_add( 1, memory_order_relaxed); } - -template< typename R > -void intrusive_ptr_release( handle_base< R > * p) -{ - if ( p->use_count.fetch_sub( 1, memory_order_release) == 1) - { - atomic_thread_fence( memory_order_acquire); - delete p; - } -} - -template< typename R, typename F > -class handle_object : public handle_base< R > -{ -private: - F fut_; - context ctx_; - -public: - handle_object() : - fut_(), - ctx_() - {} - - handle_object( - F const& fut, - context const& ctx) : - fut_( fut), - ctx_( ctx) - {} - - void interrupt() - { ctx_.interrupt(); } - - void interrupt_and_wait() - { - interrupt(); - wait(); - } - - bool interrupt_and_wait_until( system_time const& abs_time) - { - interrupt(); - return wait_until( abs_time); - } - - bool interruption_requested() - { return ctx_.interruption_requested(); } - - R get() - { - try - { return fut_.get(); } - catch ( future_uninitialized const&) - { throw task_uninitialized(); } - catch ( broken_promise const&) - { throw broken_task(); } - catch ( promise_already_satisfied const&) - { throw task_already_executed(); } - } - - bool is_ready() const - { return fut_.is_ready(); } - - bool has_value() const - { return fut_.has_value(); } - - bool has_exception() const - { return fut_.has_exception(); } - - void wait() const - { - try - { fut_.wait(); } - catch ( future_uninitialized const&) - { throw task_uninitialized(); } - catch ( broken_promise const&) - { throw broken_task(); } - catch ( thread_interrupted const&) - { throw task_interrupted(); } - } - - bool wait_until( system_time const& abs_time) const - { - try - { return fut_.timed_wait_until( abs_time); } - catch ( future_uninitialized const&) - { throw task_uninitialized(); } - catch ( broken_promise const&) - { throw broken_task(); } - catch ( thread_interrupted const&) - { throw task_interrupted(); } - } -}; - -} - -template< typename T > -struct is_handle_type; - -template< typename R > -class handle -{ -private: - intrusive_ptr< detail::handle_base< R > > base_; - -public: - handle() : - base_( new detail::handle_object< R, spin::shared_future< R > >() ) - {} - - template< typename F > - handle( - F const& fut, - context const& ctx) : - base_( new detail::handle_object< R, F >( fut, ctx) ) - {} - - void interrupt() - { base_->interrupt(); } - - void interrupt_and_wait() - { base_->interrupt_and_wait(); } - - bool interrupt_and_wait_until( system_time const& abs_time) - { return base_->interrupt_and_wait_until( abs_time); } - - template< typename TimeDuration > - bool interrupt_and_wait_for( TimeDuration const& rel_time) - { return interrupt_and_wait_until( get_system_time() + rel_time); } - - bool interruption_requested() - { return base_->interruption_requested(); } - - R get() - { return base_->get(); } - - bool is_ready() const - { return base_->is_ready(); } - - bool has_value() const - { return base_->has_value(); } - - bool has_exception() const - { return base_->has_exception(); } - - void wait() const - { base_->wait(); } - - bool wait_until( system_time const& abs_time) const - { return base_->wait_until( abs_time); } - - template< typename TimeDuration > - bool wait_for( TimeDuration const& rel_time) const - { return wait_until( get_system_time() + rel_time); } - - void swap( handle< R > & other) - { base_.swap( other.base_); } -}; - -template< typename T > -struct is_handle_type -{ BOOST_STATIC_CONSTANT( bool, value = false); }; - -template< typename T > -struct is_handle_type< handle< T > > -{ - BOOST_STATIC_CONSTANT( bool, value = true); -}; - -template< typename Iterator > -typename disable_if< is_handle_type< Iterator >, void >::type waitfor_all( - Iterator begin, Iterator end) -{ - for ( Iterator i = begin; i != end; ++i) - i->wait(); -} - -template< typename R1, typename R2 > -void waitfor_all( handle< R1 > & h1, handle< R2 > & h2) -{ - h1.wait(); - h2.wait(); -} - -template< typename R1, typename R2, typename R3 > -void waitfor_all( handle< R1 > & h1, handle< R2 > & h2, handle< R3 > & h3) -{ - h1.wait(); - h2.wait(); - h3.wait(); -} - -template< typename R1, typename R2, typename R3, typename R4 > -void waitfor_all( - handle< R1 > & h1, handle< R2 > & h2, handle< R3 > & h3, handle< R4 > & h4) -{ - h1.wait(); - h2.wait(); - h3.wait(); - h4.wait(); -} - -template< typename R1, typename R2, typename R3, typename R4, typename R5 > -void waitfor_all( - handle< R1 > & h1, handle< R2 > & h2, handle< R3 > & h3, handle< R4 > & h4, - handle< R5 > & h5) -{ - h1.wait(); - h2.wait(); - h3.wait(); - h4.wait(); - h5.wait(); -} - -}} - -#include - -#endif // BOOST_TASKS_HANDLE_H diff --git a/boost/task/meta.hpp b/boost/task/meta.hpp deleted file mode 100644 index fe60eaea..00000000 --- a/boost/task/meta.hpp +++ /dev/null @@ -1,40 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_TASKS_META_H -#define BOOST_TASKS_META_H - -#include -#include - -#include - -#include - -namespace boost { -namespace tasks { - -template< typename Pool > -struct has_attribute : public mpl::bool_< - is_same< - detail::has_attribute, - typename Pool::queue_type::attribute_tag_type - >::value -> -{}; - -template< typename Pool > -struct attribute_type -{ - typedef typename Pool::queue_type::attribute_type type; -}; - -}} - -#include - -#endif // BOOST_TASKS_META_H - diff --git a/boost/task/new_thread.hpp b/boost/task/new_thread.hpp deleted file mode 100755 index 0b591cee..00000000 --- a/boost/task/new_thread.hpp +++ /dev/null @@ -1,94 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_TASKS_NEW_THREAD_H -#define BOOST_TASKS_NEW_THREAD_H - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace tasks { -namespace detail { - -struct joiner -{ - void operator()( thread * thrd) - { - try - { - BOOST_ASSERT( thrd); - BOOST_ASSERT( thrd->joinable() ); - thrd->join(); - } - catch (...) - {} - delete thrd; - } -}; - -} - -struct new_thread -{ - template< typename R > - handle< R > operator()( BOOST_RV_REF( task< R >) t) - { - if ( this_task::runs_in_pool() ) - { - spin::promise< R > prom; - spin::shared_future< R > f( prom.get_future() ); - context ctx1, ctx2; - handle< R > h( f, ctx1); - callable ca( t, boost::move( prom), ctx2); - shared_ptr< thread > thrd( - new thread( ca), - detail::joiner() ); - ctx1.reset( thrd); - return h; - } - else - { - promise< R > prom; - shared_future< R > f( prom.get_future() ); - context ctx1, ctx2; - handle< R > h( f, ctx1); - callable ca( - t, -// TODO: workaround because thread_move_t will be abigous for move -#ifdef BOOST_HAS_RVALUE_REFS - boost::move( prom), -#else - boost::detail::thread_move_t< promise< R > >( prom), -#endif - ctx2); - shared_ptr< thread > thrd( - new thread( ca), - detail::joiner() ); - ctx1.reset( thrd); - return h; - } - } -}; - -}} - -#include - -#endif // BOOST_TASKS_NEW_THREAD_H diff --git a/boost/task/own_thread.hpp b/boost/task/own_thread.hpp deleted file mode 100755 index 86c3c92f..00000000 --- a/boost/task/own_thread.hpp +++ /dev/null @@ -1,66 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_TASKS_OWN_THREAD_H -#define BOOST_TASKS_OWN_THREAD_H - -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace tasks { - -struct own_thread -{ - template< typename R > - handle< R > operator()( BOOST_RV_REF( task< R >) t) - { - if ( this_task::runs_in_pool() ) - { - spin::promise< R > prom; - spin::shared_future< R > f( prom.get_future() ); - context ctx; - handle< R > h( f, ctx); - callable ca( t, boost::move( prom), ctx); - ca(); - return h; - } - else - { - promise< R > prom; - shared_future< R > f( prom.get_future() ); - context ctx; - handle< R > h( f, ctx); - callable ca( - t, -// TODO: workaround because thread_move_t will be abigous for move -#ifdef BOOST_HAS_RVALUE_REFS - boost::move( prom), -#else - boost::detail::thread_move_t< promise< R > >( prom), -#endif - ctx); - ca(); - return h; - } - } -}; - -}} - -#include - -#endif // BOOST_TASKS_OWN_THREAD_H diff --git a/boost/task/poolsize.hpp b/boost/task/poolsize.hpp deleted file mode 100644 index c0af86d3..00000000 --- a/boost/task/poolsize.hpp +++ /dev/null @@ -1,43 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_TASKS_POOLSIZE_H -#define BOOST_TASKS_POOLSIZE_H - -#include - -#include - -#include - -# if defined(BOOST_MSVC) -# pragma warning(push) -# pragma warning(disable:4251 4275) -# endif - -namespace boost { -namespace tasks { - -class BOOST_TASKS_DECL poolsize -{ -private: - std::size_t value_; - -public: - explicit poolsize( std::size_t value); - - operator std::size_t () const; -}; - -}} - -# if defined(BOOST_MSVC) -# pragma warning(pop) -# endif - -#include - -#endif // BOOST_TASKS_POOLSIZE_H diff --git a/boost/task/semaphore.hpp b/boost/task/semaphore.hpp deleted file mode 100755 index f4ba5449..00000000 --- a/boost/task/semaphore.hpp +++ /dev/null @@ -1,64 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_TASK_SEMAPHORE_H -#define BOOST_TASK_SEMAPHORE_H - -#include - -extern "C" -{ -# if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(__CYGWIN__) -#include -# else -#include -# endif -} - -#include - -#include - -#include - -# if defined(BOOST_MSVC) -# pragma warning(push) -# pragma warning(disable:4251 4275) -# endif - -namespace boost { -namespace tasks { - -class BOOST_TASKS_DECL semaphore : private boost::noncopyable -{ -private: -# if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(__CYGWIN__) - HANDLE handle_; -# else - int handle_; -# endif -public: - semaphore( int); - - ~semaphore(); - - void post( int = 1); - - void wait(); - - bool try_wait(); -}; - -}} - -# if defined(BOOST_MSVC) -# pragma warning(pop) -# endif - - -#include - -#endif // BOOST_TASK_SEMAPHORE_H diff --git a/boost/task/spin/auto_reset_event.hpp b/boost/task/spin/auto_reset_event.hpp deleted file mode 100644 index 50c79db3..00000000 --- a/boost/task/spin/auto_reset_event.hpp +++ /dev/null @@ -1,49 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_TASKS_SPIN_AUTO_RESET_EVENT_H -#define BOOST_TASKS_SPIN_AUTO_RESET_EVENT_H - -#include -#include -#include - -#include - -namespace boost { -namespace tasks { -namespace spin { - -class BOOST_TASKS_DECL auto_reset_event : private noncopyable -{ -private: - enum state - { - SET = 0, - RESET - }; - - atomic< state > state_; - -public: - explicit auto_reset_event( bool = false); - - void set(); - - void wait(); - - bool try_wait(); - - bool timed_wait( system_time const&); - - template< typename TimeDuration > - bool timed_wait( TimeDuration const& rel_time) - { return timed_wait( get_system_time() + rel_time); } -}; - -}}} - -#endif // BOOST_TASKS_SPIN_AUTO_RESET_EVENT_H diff --git a/boost/task/spin/barrier.hpp b/boost/task/spin/barrier.hpp deleted file mode 100644 index 6acae2a6..00000000 --- a/boost/task/spin/barrier.hpp +++ /dev/null @@ -1,39 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_TASKS_SPIN_BARRIER_H -#define BOOST_TASKS_SPIN_BARRIER_H - -#include - -#include - -#include -#include -#include - -namespace boost { -namespace tasks { -namespace spin { - -class BOOST_TASKS_DECL barrier : private noncopyable -{ -private: - std::size_t initial_; - std::size_t current_; - bool cycle_; - mutex mtx_; - condition cond_; - -public: - barrier( std::size_t); - - bool wait(); -}; - -}}} - -#endif // BOOST_TASKS_SPIN_BARRIER_H diff --git a/boost/task/spin/bounded_channel.hpp b/boost/task/spin/bounded_channel.hpp deleted file mode 100644 index 84a5ca5c..00000000 --- a/boost/task/spin/bounded_channel.hpp +++ /dev/null @@ -1,398 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_TASKS_SPIN_BOUNDED_CHANNEL_H -#define BOOST_TASKS_SPIN_BOUNDED_CHANNEL_H - -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -namespace boost { -namespace tasks { -namespace spin { -namespace detail { - -template< typename T > -struct bounded_channel_base_node -{ - typedef intrusive_ptr< bounded_channel_base_node > ptr; - - atomic< std::size_t > use_count; - T va; - ptr next; - - bounded_channel_base_node() : - use_count( 0), - va(), - next() - {} -}; - -template< typename T > -void intrusive_ptr_add_ref( bounded_channel_base_node< T > * p) -{ p->use_count.fetch_add( 1, memory_order_relaxed); } - -template< typename T > -void intrusive_ptr_release( bounded_channel_base_node< T > * p) -{ - if ( p->use_count.fetch_sub( 1, memory_order_release) == 1) - { - atomic_thread_fence( memory_order_acquire); - delete p; - } -} - -template< typename T > -class bounded_channel_base : private noncopyable -{ -public: - typedef optional< T > value_type; - -private: - typedef bounded_channel_base_node< value_type > node_type; - - template< typename X > - friend void intrusive_ptr_add_ref( bounded_channel_base< X > * p); - template< typename X > - friend void intrusive_ptr_release( bounded_channel_base< X > * p); - - enum state - { - ACTIVE = 0, - DEACTIVE - }; - - atomic< state > state_; - atomic< std::size_t > count_; - typename node_type::ptr head_; - mutable mutex head_mtx_; - typename node_type::ptr tail_; - mutable mutex tail_mtx_; - condition not_empty_cond_; - condition not_full_cond_; - unsigned int hwm_; - unsigned int lwm_; - atomic< std::size_t > use_count_; - - bool active_() const - { return ACTIVE == state_.load(); } - - void deactivate_() - { state_.store( DEACTIVE); } - - std::size_t size_() const - { return count_.load(); } - - bool empty_() const - { return head_ == get_tail_(); } - - bool full_() const - { return size_() >= hwm_; } - - typename node_type::ptr get_tail_() const - { - mutex::scoped_lock lk( tail_mtx_); - typename node_type::ptr tmp = tail_; - return tmp; - } - - typename node_type::ptr pop_head_() - { - typename node_type::ptr old_head = head_; - head_ = old_head->next; - count_.fetch_sub( 1); - return old_head; - } - -public: - bounded_channel_base( - std::size_t hwm, - std::size_t lwm) : - state_( ACTIVE), - count_( 0), - head_( new node_type() ), - head_mtx_(), - tail_( head_), - tail_mtx_(), - not_empty_cond_(), - not_full_cond_(), - hwm_( hwm), - lwm_( lwm), - use_count_( 0) - { - if ( hwm_ < lwm_) - throw invalid_watermark(); - } - - bounded_channel_base( std::size_t wm) : - state_( ACTIVE), - count_( 0), - head_( new node_type() ), - head_mtx_(), - tail_( head_), - tail_mtx_(), - not_empty_cond_(), - not_full_cond_(), - hwm_( wm), - lwm_( wm), - use_count_( 0) - {} - - std::size_t upper_bound() const - { return hwm_; } - - std::size_t lower_bound() const - { return lwm_; } - - bool active() const - { return active_(); } - - void deactivate() - { - mutex::scoped_lock head_lk( head_mtx_); - mutex::scoped_lock tail_lk( tail_mtx_); - not_empty_cond_.notify_all(); - not_full_cond_.notify_all(); - deactivate_(); - } - - bool empty() const - { - mutex::scoped_lock lk( head_mtx_); - return empty_(); - } - - void put( T const& t) - { - typename node_type::ptr new_node( new node_type() ); - { - mutex::scoped_lock lk( tail_mtx_); - - if ( full_() ) - { - while ( active_() && full_() ) - not_full_cond_.wait( lk); - } - - if ( ! active_() ) - throw std::runtime_error("queue is not active"); - - tail_->va = t; - tail_->next = new_node; - tail_ = new_node; - count_.fetch_add( 1); - } - not_empty_cond_.notify_one(); - } - - bool put( T const& t, system_time const& abs_time) - { - typename node_type::ptr new_node( new node_type() ); - { - mutex::scoped_lock lk( tail_mtx_); - - if ( full_() ) - { - while ( active_() && full_() ) - if ( ! not_full_cond_.timed_wait( lk, abs_time) ); - return false; - } - - if ( ! active_() ) - throw std::runtime_error("queue is not active"); - - tail_->va = t; - tail_->next = new_node; - tail_ = new_node; - count_.fetch_add( 1); - } - not_empty_cond_.notify_one(); - return true; - } - - bool take( value_type & va) - { - mutex::scoped_lock lk( head_mtx_); - bool empty = empty_(); - if ( ! active_() && empty) - return false; - if ( empty) - { - try - { - while ( active_() && empty_() ) - not_empty_cond_.wait( lk); - } - catch ( task_interrupted const&) - { return false; } - } - if ( ! active_() && empty_() ) - return false; - swap( va, head_->va); - pop_head_(); - if ( size_() <= lwm_) - { - if ( lwm_ == hwm_) - not_full_cond_.notify_one(); - else - // more than one producer could be waiting - // for submiting an action object - not_full_cond_.notify_all(); - } - return va; - } - - bool take( value_type & va, system_time const& abs_time) - { - mutex::scoped_lock lk( head_mtx_); - bool empty = empty_(); - if ( ! active_() && empty) - return false; - if ( empty) - { - try - { - while ( active_() && empty_() ) - if ( ! not_empty_cond_.timed_wait( lk, abs_time) ) - return false; - } - catch ( task_interrupted const&) - { return false; } - } - if ( ! active_() && empty_() ) - return false; - swap( va, head_->va); - pop_head_(); - if ( size_() <= lwm_) - { - if ( lwm_ == hwm_) - not_full_cond_.notify_one(); - else - // more than one producer could be waiting - // for submiting an action object - not_full_cond_.notify_all(); - } - return va; - } - - bool try_take( value_type & va) - { - mutex::scoped_lock lk( head_mtx_); - if ( empty_() ) - return false; - swap( va, head_->va); - pop_head_(); - bool valid = va; - if ( valid && size_() <= lwm_) - { - if ( lwm_ == hwm_) - not_full_cond_.notify_one(); - else - // more than one producer could be waiting - // in order to submit an task - not_full_cond_.notify_all(); - } - return valid; - } -}; - -template< typename T > -void intrusive_ptr_add_ref( bounded_channel_base< T > * p) -{ p->use_count_.fetch_add( 1, memory_order_relaxed); } - -template< typename T > -void intrusive_ptr_release( bounded_channel_base< T > * p) -{ - if ( p->use_count_.fetch_sub( 1, memory_order_release) == 1) - { - atomic_thread_fence( memory_order_acquire); - delete p; - } -} - -} - -template< typename T > -class bounded_channel -{ -private: - typedef typename detail::bounded_channel_base< T >::value_type value_type; - - intrusive_ptr< detail::bounded_channel_base< T > > base_; - -public: - bounded_channel( - std::size_t hwm, - std::size_t lwm) : - base_( new detail::bounded_channel_base< T >( hwm, lwm) ) - {} - - bounded_channel( std::size_t wm) : - base_( new detail::bounded_channel_base< T >( wm) ) - {} - - void upper_bound( std::size_t hwm) - { base_->upper_bound( hwm); } - - std::size_t upper_bound() const - { return base_->upper_bound(); } - - void lower_bound( std::size_t lwm) - { base_->lower_bound( lwm); } - - std::size_t lower_bound() const - { return base_->lower_bound(); } - - bool active() const - { return base_->active(); } - - void deactivate() - { base_->deactivate(); } - - bool empty() const - { return base_->empty(); } - - void put( T const& t) - { base_->put( t); } - - bool put( T const& t, system_time const& abs_time) - { return base_->put( t, abs_time); } - - template< typename TimeDuration > - bool put( T const& t, TimeDuration const& rel_time) - { return base_->put( t, get_system_time() + rel_time); } - - bool take( value_type & va) - { return base_->take( va);} - - bool take( value_type & va, system_time const& abs_time) - { return base_->take( va, abs_time);} - - template< typename TimeDuration > - bool take( value_type & va, TimeDuration const& rel_time) - { return base_->take( va, get_system_time() + rel_time);} - - bool try_take( value_type & va) - { return base_->try_take( va); } -}; - -}}} - -#include - -#endif // BOOST_TASKS_SPIN_BOUNDED_CHANNEL_H diff --git a/boost/task/spin/condition.hpp b/boost/task/spin/condition.hpp deleted file mode 100644 index ddbe1108..00000000 --- a/boost/task/spin/condition.hpp +++ /dev/null @@ -1,293 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) -// -// based on boost::interprocess::sync::interprocess_condition - -#ifndef BOOST_TASKS_SPIN_CONDITION_H -#define BOOST_TASKS_SPIN_CONDITION_H - -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -namespace boost { -namespace tasks { -namespace spin { - -class BOOST_TASKS_DECL condition : private noncopyable -{ -private: - enum command - { - SLEEPING = 0, - NOTIFY_ONE, - NOTIFY_ALL - }; - - atomic< command > cmd_; - atomic< std::size_t > waiters_; - mutex enter_mtx_; - mutex check_mtx_; - - void notify_( command); - -public: - condition(); - - void notify_one(); - - void notify_all(); - - void wait( unique_lock< mutex > & lk) - { - if ( ! lk) - throw lock_error(); - wait( * lk.mutex() ); - } - - template< typename Pred > - void wait( unique_lock< mutex > & lk, Pred pred) - { - if ( ! lk) - throw lock_error(); - - while ( ! pred() ) - wait( * lk.mutex() ); - } - - bool timed_wait( unique_lock< mutex > & lk, system_time const& abs_time) - { - if ( abs_time.is_infinity() ) - { - wait( lk); - return true; - } - - if ( ! lk) - throw lock_error(); - return timed_wait( * lk.mutex(), abs_time); - } - - template< typename Pred > - bool timed_wait( unique_lock< mutex > & lk, system_time const& abs_time, Pred pred) - { - if ( abs_time.is_infinity() ) - { - wait( lk, pred); - return true; - } - - if ( ! lk) - throw lock_error(); - - while ( ! pred() ) - if ( ! timed_wait( * lk.mutex(), abs_time) ) - return pred(); - return true; - } - - template< typename TimeDuration > - bool timed_wait( unique_lock< mutex > & lk, TimeDuration const& rel_time) - { return timed_wait( lk, get_system_time() + rel_time); } - - template< - typename TimeDuration, - typename Pred - > - bool timed_wait( unique_lock< mutex > & lk, TimeDuration const& rel_time, Pred pred) - { return timed_wait( lk, get_system_time() + rel_time, pred); } - - template< typename LockType > - void wait( LockType & lt) - { - { - mutex::scoped_lock lk( enter_mtx_); - BOOST_ASSERT( lk); - waiters_.fetch_add( 1); - lt.unlock(); - } - - bool unlock_enter_mtx = false; - for (;;) - { - while ( SLEEPING == cmd_.load() ) - { - this_thread::interruption_point(); - if ( this_task::runs_in_pool() ) - this_task::yield(); - else - this_thread::yield(); - this_thread::interruption_point(); - } - - mutex::scoped_lock lk( check_mtx_); - BOOST_ASSERT( lk); - - command expected = NOTIFY_ONE; - cmd_.compare_exchange_strong( expected, SLEEPING); - if ( SLEEPING == expected) - continue; - else if ( NOTIFY_ONE == expected) - { - unlock_enter_mtx = true; - waiters_.fetch_sub( 1); - break; - } - else - { - unlock_enter_mtx = 1 == waiters_.fetch_sub( 1); - if ( unlock_enter_mtx) - { - expected = NOTIFY_ALL; - cmd_.compare_exchange_strong( expected, SLEEPING); - } - break; - } - } - - if ( unlock_enter_mtx) - enter_mtx_.unlock(); - - lt.lock(); - } - - template< - typename LockType, - typename Pred - > - void wait( LockType & lt, Pred pred) - { - while ( ! pred() ) - wait( lt); - } - - template< typename LockType > - bool timed_wait( LockType & lt, system_time const& abs_time) - { - if ( abs_time.is_infinity() ) - { - wait( lt); - return true; - } - - if ( get_system_time() >= abs_time) return false; - - { - mutex::scoped_lock lk( enter_mtx_, abs_time); - BOOST_ASSERT( lk); - waiters_.fetch_add( 1); - lt.unlock(); - } - - bool timed_out = false, unlock_enter_mtx = false; - for (;;) - { - while ( SLEEPING == cmd_.load() ) - { - this_thread::interruption_point(); - if ( this_task::runs_in_pool() ) - this_task::yield(); - else - this_thread::yield(); - this_thread::interruption_point(); - - if ( get_system_time() >= abs_time) - { - timed_out = enter_mtx_.try_lock(); - if ( ! timed_out) - continue; - break; - } - } - - if ( timed_out) - { - waiters_.fetch_sub( 1); - unlock_enter_mtx = true; - break; - } - else - { - mutex::scoped_lock lk( check_mtx_); - BOOST_ASSERT( lk); - - command expected = NOTIFY_ONE; - cmd_.compare_exchange_strong( expected, SLEEPING); - if ( SLEEPING == expected) - continue; - else if ( NOTIFY_ONE == expected) - { - unlock_enter_mtx = true; - waiters_.fetch_sub( 1); - break; - } - else - { - unlock_enter_mtx = 1 == waiters_.fetch_sub( 1); - if ( unlock_enter_mtx) - { - expected = NOTIFY_ALL; - cmd_.compare_exchange_strong( expected, SLEEPING); - } - break; - } - } - } - - if ( unlock_enter_mtx) - enter_mtx_.unlock(); - - lt.lock(); - - return ! timed_out; - } - - template< - typename LockType, - typename Pred - > - bool timed_wait( LockType & lt, system_time const& abs_time, Pred pred) - { - if ( abs_time.is_infinity() ) - { - wait( lt, pred); - return true; - } - - while ( ! pred() ) - if ( ! wait( lt, abs_time) ) - return pred(); - return true; - } - - template< - typename LockType, - typename TimeDuration - > - bool timed_wait( LockType & lt, TimeDuration const& rel_time) - { return timed_wait( lt, get_system_time() + rel_time); } - - template< - typename LockType, - typename TimeDuration, - typename Pred - > - bool timed_wait( LockType & lt, TimeDuration const& rel_time, Pred pred) - { return timed_wait( lt, get_system_time() + rel_time, pred); } -}; - -}}} - -#endif // BOOST_TASKS_SPIN_CONDITION_H diff --git a/boost/task/spin/count_down_event.hpp b/boost/task/spin/count_down_event.hpp deleted file mode 100644 index e13044e6..00000000 --- a/boost/task/spin/count_down_event.hpp +++ /dev/null @@ -1,50 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_TASKS_SPIN_COUNT_DOWN_EVENT_H -#define BOOST_TASKS_SPIN_COUNT_DOWN_EVENT_H - -#include - -#include -#include -#include - -#include - -namespace boost { -namespace tasks { -namespace spin { - -class BOOST_TASKS_DECL count_down_event : private noncopyable -{ -private: - std::size_t initial_; - atomic< std::size_t > current_; - -public: - explicit count_down_event( std::size_t); - - std::size_t initial() const; - - std::size_t current() const; - - bool is_set() const; - - void set(); - - void wait(); - - bool timed_wait( system_time const&); - - template< typename TimeDuration > - bool timed_wait( TimeDuration const& rel_time) - { return timed_wait( get_system_time() + rel_time); } -}; - -}}} - -#endif // BOOST_TASKS_SPIN_COUNT_DOWN_EVENT_H diff --git a/boost/task/spin/future.hpp b/boost/task/spin/future.hpp deleted file mode 100644 index a556f88f..00000000 --- a/boost/task/spin/future.hpp +++ /dev/null @@ -1,1125 +0,0 @@ -// (C) Copyright 2008-9 Anthony Williams -// -// Distributed under the Boost Software License, Version 1.0. (See -// accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_TASKS_SPIN_FUTURE_HPP -#define BOOST_TASKS_SPIN_FUTURE_HPP - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -namespace boost { -namespace tasks { - -namespace future_state { - - enum state { uninitialized, waiting, ready, moved }; - -} - -namespace spin { -namespace detail { - -struct future_object_base -{ - boost::exception_ptr exception; - bool done; - mutex mtx; - spin::condition waiters; - typedef std::list waiter_list; - waiter_list external_waiters; - boost::function callback; - - future_object_base(): - done(false) - {} - - virtual ~future_object_base() - {} - - waiter_list::iterator register_external_waiter(spin::condition& cv) - { - boost::unique_lock lock(mtx); - do_callback(lock); - return external_waiters.insert(external_waiters.end(),&cv); - } - - void remove_external_waiter(waiter_list::iterator it) - { - boost::lock_guard lock(mtx); - external_waiters.erase(it); - } - - void mark_finished_internal() - { - done=true; - waiters.notify_all(); - for(waiter_list::const_iterator it=external_waiters.begin(), - end=external_waiters.end();it!=end;++it) - { - (*it)->notify_all(); - } - } - - struct relocker - { - boost::unique_lock& lock; - - relocker(boost::unique_lock& lock_): - lock(lock_) - { - lock.unlock(); - } - ~relocker() - { - lock.lock(); - } - }; - - void do_callback(boost::unique_lock& lock) - { - if(callback && !done) - { - boost::function local_callback=callback; - relocker relock(lock); - local_callback(); - } - } - - - void wait(bool rethrow=true) - { - boost::unique_lock lock(mtx); - do_callback(lock); - while(!done) - { - waiters.wait(lock); - } - if(rethrow && exception) - { - boost::rethrow_exception(exception); - } - } - - bool timed_wait_until(boost::system_time const& target_time) - { - boost::unique_lock lock(mtx); - do_callback(lock); - while(!done) - { - bool const success=waiters.timed_wait(lock,target_time); - if(!success && !done) - { - return false; - } - } - return true; - } - - void mark_exceptional_finish_internal(boost::exception_ptr const& e) - { - exception=e; - mark_finished_internal(); - } - void mark_exceptional_finish() - { - boost::lock_guard lock(mtx); - mark_exceptional_finish_internal(boost::current_exception()); - } - - bool has_value() - { - boost::lock_guard lock(mtx); - return done && !exception; - } - bool has_exception() - { - boost::lock_guard lock(mtx); - return done && exception; - } - - template - void set_wait_callback(F f,U* u) - { - callback=boost::bind(f,boost::ref(*u)); - } - -private: - future_object_base(future_object_base const&); - future_object_base& operator=(future_object_base const&); -}; - -template -struct future_object: future_object_base -{ - typedef typename tasks::detail::future_traits::storage_type storage_type; - typedef typename tasks::detail::future_traits::source_reference_type source_reference_type; - typedef typename tasks::detail::future_traits::rvalue_source_type rvalue_source_type; - typedef typename tasks::detail::future_traits::move_dest_type move_dest_type; - - storage_type result; - - future_object(): - result(0) - {} - - void mark_finished_with_result_internal(source_reference_type result_) - { - tasks::detail::future_traits::init(result,result_); - mark_finished_internal(); - } - void mark_finished_with_result_internal(rvalue_source_type result_) - { - tasks::detail::future_traits::init(result,static_cast(result_)); - mark_finished_internal(); - } - - void mark_finished_with_result(source_reference_type result_) - { - boost::lock_guard lock(mtx); - mark_finished_with_result_internal(result_); - } - void mark_finished_with_result(rvalue_source_type result_) - { - boost::lock_guard lock(mtx); - mark_finished_with_result_internal(result_); - } - - move_dest_type get() - { - wait(); - return *result; - } - - future_state::state get_state() - { - boost::lock_guard guard(mtx); - if(!done) - { - return future_state::waiting; - } - else - { - return future_state::ready; - } - } - -private: - future_object(future_object const&); - future_object& operator=(future_object const&); -}; - -template<> -struct future_object: future_object_base -{ - future_object() - {} - - void mark_finished_with_result_internal() - { - mark_finished_internal(); - } - - void mark_finished_with_result() - { - boost::lock_guard lock(mtx); - mark_finished_with_result_internal(); - } - - void get() - { - wait(); - } - - future_state::state get_state() - { - boost::lock_guard guard(mtx); - if(!done) - { - return future_state::waiting; - } - else - { - return future_state::ready; - } - } - -private: - future_object(future_object const&); - future_object& operator=(future_object const&); -}; - -class future_waiter -{ - struct registered_waiter - { - boost::shared_ptr future; - detail::future_object_base::waiter_list::iterator wait_iterator; - unsigned index; - - registered_waiter(boost::shared_ptr const& future_, - detail::future_object_base::waiter_list::iterator wait_iterator_, - unsigned index_): - future(future_),wait_iterator(wait_iterator_),index(index_) - {} - - }; - - struct all_futures_lock - { - unsigned count; - boost::scoped_array > locks; - - all_futures_lock(std::vector& futures): - count(futures.size()),locks(new boost::unique_lock[count]) - { - for(unsigned i=0;i(futures[i].future->mtx); - } - } - - void lock() - { - boost::lock(locks.get(),locks.get()+count); - } - - void unlock() - { - for(unsigned i=0;i futures; - unsigned future_count; - -public: - future_waiter(): - future_count(0) - {} - - template - void add(F& f) - { - if(f.future) - { - futures.push_back(registered_waiter(f.future,f.future->register_external_waiter(cv),future_count)); - } - ++future_count; - } - - unsigned wait() - { - all_futures_lock lk(futures); - for(;;) - { - for(unsigned i=0;idone) - { - return futures[i].index; - } - } - cv.wait(lk); - } - } - - ~future_waiter() - { - for(unsigned i=0;iremove_external_waiter(futures[i].wait_iterator); - } - } - -}; - -} - -template -class unique_future; - -template -class shared_future; - -template -struct is_future_type -{ - BOOST_STATIC_CONSTANT(bool, value=false); -}; - -template -struct is_future_type > -{ - BOOST_STATIC_CONSTANT(bool, value=true); -}; - -template -struct is_future_type > -{ - BOOST_STATIC_CONSTANT(bool, value=true); -}; - -template -typename boost::disable_if,void>::type wait_for_all(Iterator begin,Iterator end) -{ - for(Iterator current=begin;current!=end;++current) - { - current->wait(); - } -} - -template -typename boost::enable_if,void>::type wait_for_all(F1& f1,F2& f2) -{ - f1.wait(); - f2.wait(); -} - -template -void wait_for_all(F1& f1,F2& f2,F3& f3) -{ - f1.wait(); - f2.wait(); - f3.wait(); -} - -template -void wait_for_all(F1& f1,F2& f2,F3& f3,F4& f4) -{ - f1.wait(); - f2.wait(); - f3.wait(); - f4.wait(); -} - -template -void wait_for_all(F1& f1,F2& f2,F3& f3,F4& f4,F5& f5) -{ - f1.wait(); - f2.wait(); - f3.wait(); - f4.wait(); - f5.wait(); -} - -template -typename boost::disable_if,Iterator>::type wait_for_any(Iterator begin,Iterator end) -{ - detail::future_waiter waiter; - for(Iterator current=begin;current!=end;++current) - { - waiter.add(*current); - } - return boost::next(begin,waiter.wait()); -} - -template -typename boost::enable_if,unsigned>::type wait_for_any(F1& f1,F2& f2) -{ - detail::future_waiter waiter; - waiter.add(f1); - waiter.add(f2); - return waiter.wait(); -} - -template -unsigned wait_for_any(F1& f1,F2& f2,F3& f3) -{ - detail::future_waiter waiter; - waiter.add(f1); - waiter.add(f2); - waiter.add(f3); - return waiter.wait(); -} - -template -unsigned wait_for_any(F1& f1,F2& f2,F3& f3,F4& f4) -{ - detail::future_waiter waiter; - waiter.add(f1); - waiter.add(f2); - waiter.add(f3); - waiter.add(f4); - return waiter.wait(); -} - -template -unsigned wait_for_any(F1& f1,F2& f2,F3& f3,F4& f4,F5& f5) -{ - detail::future_waiter waiter; - waiter.add(f1); - waiter.add(f2); - waiter.add(f3); - waiter.add(f4); - waiter.add(f5); - return waiter.wait(); -} - -template -class promise; - -template -class packaged_task; - -template -class unique_future -{ - typedef boost::shared_ptr > future_ptr; - - BOOST_MOVABLE_BUT_NOT_COPYABLE( unique_future); - - future_ptr future; - - friend class shared_future; - friend class promise; - friend class packaged_task; - friend class detail::future_waiter; - - typedef typename tasks::detail::future_traits::move_dest_type move_dest_type; - - unique_future(future_ptr future_): - future(future_) - {} - -public: - typedef future_state::state state; - - unique_future() - {} - - ~unique_future() - {} - - unique_future( BOOST_RV_REF( unique_future) other): - future(other.future) - { - other.future.reset(); - } - - unique_future& operator=( BOOST_RV_REF( unique_future) other) - { - future=other.future; - other.future.reset(); - return *this; - } - - void swap(unique_future& other) - { - future.swap(other.future); - } - - // retrieving the value - move_dest_type get() - { - if(!future) - { - throw future_uninitialized(); - } - - return future->get(); - } - - // functions to check state, and wait for ready - state get_state() const - { - if(!future) - { - return future_state::uninitialized; - } - return future->get_state(); - } - - - bool is_ready() const - { - return get_state()==future_state::ready; - } - - bool has_exception() const - { - return future && future->has_exception(); - } - - bool has_value() const - { - return future && future->has_value(); - } - - void wait() const - { - if(!future) - { - throw future_uninitialized(); - } - future->wait(false); - } - - template - bool timed_wait(Duration const& rel_time) const - { - return timed_wait_until(boost::get_system_time()+rel_time); - } - - bool timed_wait_until(boost::system_time const& abs_time) const - { - if(!future) - { - throw future_uninitialized(); - } - return future->timed_wait_until(abs_time); - } -}; - -template -class shared_future -{ - typedef boost::shared_ptr > future_ptr; - - BOOST_COPYABLE_AND_MOVABLE( shared_future); - - future_ptr future; - - friend class detail::future_waiter; - friend class promise; - friend class packaged_task; - - shared_future(future_ptr future_): - future(future_) - {} - -public: - shared_future(shared_future const& other): - future(other.future) - {} - - typedef future_state::state state; - - shared_future() - {} - - ~shared_future() - {} - - shared_future& operator=( BOOST_COPY_ASSIGN_REF( shared_future) other) - { - future=other.future; - return *this; - } - - shared_future( BOOST_RV_REF( shared_future) other): - future(other.future) - { - other->future.reset(); - } - shared_future( BOOST_RV_REF( unique_future) other): - future(other.future) - { - other.future.reset(); - } - shared_future& operator=(BOOST_RV_REF( shared_future) other) - { - future.swap(other.future); - other.future.reset(); - return *this; - } - shared_future& operator=( BOOST_RV_REF( unique_future) other) - { - future.swap(other.future); - other.future.reset(); - return *this; - } - - void swap(shared_future& other) - { - future.swap(other.future); - } - - // retrieving the value - R get() - { - if(!future) - { - throw future_uninitialized(); - } - - return future->get(); - } - - // functions to check state, and wait for ready - state get_state() const - { - if(!future) - { - return future_state::uninitialized; - } - return future->get_state(); - } - - - bool is_ready() const - { - return get_state()==future_state::ready; - } - - bool has_exception() const - { - return future && future->has_exception(); - } - - bool has_value() const - { - return future && future->has_value(); - } - - void wait() const - { - if(!future) - { - throw future_uninitialized(); - } - future->wait(false); - } - - template - bool timed_wait(Duration const& rel_time) const - { - return timed_wait_until(boost::get_system_time()+rel_time); - } - - bool timed_wait_until(boost::system_time const& abs_time) const - { - if(!future) - { - throw future_uninitialized(); - } - return future->timed_wait_until(abs_time); - } -}; - -template -class promise -{ - typedef boost::shared_ptr > future_ptr; - - BOOST_MOVABLE_BUT_NOT_COPYABLE( promise); - - future_ptr future; - bool future_obtained; - - void lazy_init() - { - if(!future) - { - future_obtained=false; - future.reset(new detail::future_object); - } - } - -public: -// template explicit promise(Allocator a); - - promise(): - future(),future_obtained(false) - {} - - ~promise() - { - if(future) - { - boost::lock_guard lock(future->mtx); - - if(!future->done) - { - future->mark_exceptional_finish_internal(boost::copy_exception(broken_promise())); - } - } - } - - promise( BOOST_RV_REF( promise) rhs): - future(rhs.future),future_obtained(rhs.future_obtained) - { - rhs.future.reset(); - } - promise & operator=( BOOST_RV_REF( promise) rhs) - { - future=rhs.future; - future_obtained=rhs.future_obtained; - rhs.future.reset(); - return *this; - } - - void swap(promise& other) - { - future.swap(other.future); - std::swap(future_obtained,other.future_obtained); - } - - // Result retrieval - unique_future get_future() - { - lazy_init(); - if(future_obtained) - { - throw future_already_retrieved(); - } - future_obtained=true; - return unique_future(future); - } - - void set_value(typename tasks::detail::future_traits::source_reference_type r) - { - lazy_init(); - boost::lock_guard lock(future->mtx); - if(future->done) - { - throw promise_already_satisfied(); - } - future->mark_finished_with_result_internal(r); - } - -// void set_value(R && r); - void set_value(typename tasks::detail::future_traits::rvalue_source_type r) - { - lazy_init(); - boost::lock_guard lock(future->mtx); - if(future->done) - { - throw promise_already_satisfied(); - } - future->mark_finished_with_result_internal(static_cast::rvalue_source_type>(r)); - } - - void set_exception(boost::exception_ptr p) - { - lazy_init(); - boost::lock_guard lock(future->mtx); - if(future->done) - { - throw promise_already_satisfied(); - } - future->mark_exceptional_finish_internal(p); - } - - template - void set_wait_callback(F f) - { - lazy_init(); - future->set_wait_callback(f,this); - } - -}; - -template <> -class promise -{ - typedef boost::shared_ptr > future_ptr; - - BOOST_MOVABLE_BUT_NOT_COPYABLE( promise); - - future_ptr future; - bool future_obtained; - - void lazy_init() - { - if(!future) - { - future_obtained=false; - future.reset(new detail::future_object); - } - } -public: - promise(): - future(),future_obtained(false) - {} - - ~promise() - { - if(future) - { - boost::lock_guard lock(future->mtx); - - if(!future->done) - { - future->mark_exceptional_finish_internal(boost::copy_exception(broken_promise())); - } - } - } - - promise( BOOST_RV_REF( promise) rhs): - future(rhs.future),future_obtained(rhs.future_obtained) - { - rhs.future.reset(); - } - promise & operator=( BOOST_RV_REF( promise) rhs) - { - future=rhs.future; - future_obtained=rhs.future_obtained; - rhs.future.reset(); - return *this; - } - - void swap(promise& other) - { - future.swap(other.future); - std::swap(future_obtained,other.future_obtained); - } - - // Result retrieval - unique_future get_future() - { - lazy_init(); - - if(future_obtained) - { - throw future_already_retrieved(); - } - future_obtained=true; - return unique_future(future); - } - - void set_value() - { - lazy_init(); - boost::lock_guard lock(future->mtx); - if(future->done) - { - throw promise_already_satisfied(); - } - future->mark_finished_with_result_internal(); - } - - void set_exception(boost::exception_ptr p) - { - lazy_init(); - boost::lock_guard lock(future->mtx); - if(future->done) - { - throw promise_already_satisfied(); - } - future->mark_exceptional_finish_internal(p); - } - - template - void set_wait_callback(F f) - { - lazy_init(); - future->set_wait_callback(f,this); - } -}; - -namespace detail { - -template -struct task_base: - detail::future_object -{ - bool started; - - task_base(): - started(false) - {} - - void run() - { - { - boost::lock_guard lk(this->mtx); - if(started) - { - throw task_already_started(); - } - started=true; - } - do_run(); - } - - void owner_destroyed() - { - boost::lock_guard lk(this->mtx); - if(!started) - { - started=true; - this->mark_exceptional_finish_internal(boost::copy_exception(broken_promise())); - } - } - - virtual void do_run()=0; -}; - - -template -struct task_object: - task_base -{ - F f; - task_object(F const& f_): - f(f_) - {} - task_object( BOOST_RV_REF( F) f_): - f(f_) - {} - - void do_run() - { - try - { - this->mark_finished_with_result(f()); - } - catch(...) - { - this->mark_exceptional_finish(); - } - } -}; - -template -struct task_object: - task_base -{ - F f; - task_object(F const& f_): - f(f_) - {} - task_object( BOOST_RV_REF( F) f_): - f(f_) - {} - - void do_run() - { - try - { - f(); - this->mark_finished_with_result(); - } - catch(...) - { - this->mark_exceptional_finish(); - } - } -}; - -} - - -template -class packaged_task -{ - BOOST_MOVABLE_BUT_NOT_COPYABLE( packaged_task); - - boost::shared_ptr > task; - bool future_obtained; - -public: - packaged_task(): - future_obtained(false) - {} - - // construction and destruction - template - explicit packaged_task(F const& f): - task(new detail::task_object(f)),future_obtained(false) - {} - explicit packaged_task(R(*f)()): - task(new detail::task_object(f)),future_obtained(false) - {} - - template - explicit packaged_task( BOOST_RV_REF( F) f): - task(new detail::task_object(f)),future_obtained(false) - {} - -// template -// explicit packaged_task(F const& f, Allocator a); -// template -// explicit packaged_task(F&& f, Allocator a); - - - ~packaged_task() - { - if(task) - { - task->owner_destroyed(); - } - } - - packaged_task( BOOST_RV_REF( packaged_task) other): - future_obtained(other.future_obtained) - { - task.swap(other.task); - other.future_obtained=false; - } - packaged_task& operator=( BOOST_RV_REF( packaged_task) other) - { - packaged_task temp(other); - swap(temp); - return *this; - } - - void swap(packaged_task& other) - { - task.swap(other.task); - std::swap(future_obtained,other.future_obtained); - } - - // result retrieval - unique_future get_future() - { - if(!task) - { - throw task_moved(); - } - else if(!future_obtained) - { - future_obtained=true; - return unique_future(task); - } - else - { - throw future_already_retrieved(); - } - } - - - // execution - void operator()() - { - if(!task) - { - throw task_moved(); - } - task->run(); - } - - template - void set_wait_callback(F f) - { - task->set_wait_callback(f,this); - } -}; - -}}} - -#endif // BOOST_TASKS_SPIN_FUTURE_H diff --git a/boost/task/spin/manual_reset_event.hpp b/boost/task/spin/manual_reset_event.hpp deleted file mode 100644 index dc0238ab..00000000 --- a/boost/task/spin/manual_reset_event.hpp +++ /dev/null @@ -1,56 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_TASKS_SPIN_MANUAL_RESET_EVENT_H -#define BOOST_TASKS_SPIN_MANUAL_RESET_EVENT_H - -#include - -#include -#include -#include - -#include -#include - -namespace boost { -namespace tasks { -namespace spin { - -class BOOST_TASKS_DECL manual_reset_event : private noncopyable -{ -private: - enum state - { - SET = 0, - RESET - }; - - atomic< state > state_; - atomic< std::size_t > waiters_; - mutex enter_mtx_; - -public: - explicit manual_reset_event( bool = false); - - void set(); - - void reset(); - - void wait(); - - bool try_wait(); - - bool timed_wait( system_time const&); - - template< typename TimeDuration > - bool timed_wait( TimeDuration const& rel_time) - { return timed_wait( get_system_time() + rel_time); } -}; - -}}} - -#endif // BOOST_TASKS_SPIN_MANUAL_RESET_EVENT_H diff --git a/boost/task/spin/mutex.hpp b/boost/task/spin/mutex.hpp deleted file mode 100644 index 57907e04..00000000 --- a/boost/task/spin/mutex.hpp +++ /dev/null @@ -1,56 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) -// -// based on boost::interprocess::sync::interprocess_spin::mutex - -#ifndef BOOST_TASKS_SPIN_MUTEX_H -#define BOOST_TASKS_SPIN_MUTEX_H - -#include -#include -#include -#include - -#include - -namespace boost { -namespace tasks { -namespace spin { - -class BOOST_TASKS_DECL mutex : private noncopyable -{ -private: - enum state - { - LOCKED = 0, - UNLOCKED - }; - - atomic< state > state_; - -public: - typedef unique_lock< mutex > scoped_lock; - - mutex(); - - void lock(); - - bool try_lock(); - - bool timed_lock( system_time const& abs_time); - - template< typename TimeDuration > - bool timed_lock( TimeDuration const& rel_time) - { return timed_lock( get_system_time() + rel_time); } - - void unlock(); -}; - -typedef mutex try_mutex; - -}}} - -#endif // BOOST_TASKS_SPIN_MUTEX_H diff --git a/boost/task/spin/unbounded_channel.hpp b/boost/task/spin/unbounded_channel.hpp deleted file mode 100644 index 6bf70795..00000000 --- a/boost/task/spin/unbounded_channel.hpp +++ /dev/null @@ -1,273 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_TASKS_SPIN_UNBOUNDED_CHANNEL_H -#define BOOST_TASKS_SPIN_UNBOUNDED_CHANNEL_H - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -namespace boost { -namespace tasks { -namespace spin { -namespace detail { - -template< typename T > -struct unbounded_channel_base_node -{ - typedef intrusive_ptr< unbounded_channel_base_node > ptr; - - atomic< std::size_t > use_count; - T va; - ptr next; - - unbounded_channel_base_node() : - use_count( 0), - va(), - next() - {} -}; - -template< typename T > -void intrusive_ptr_add_ref( unbounded_channel_base_node< T > * p) -{ p->use_count.fetch_add( 1, memory_order_relaxed); } - -template< typename T > -void intrusive_ptr_release( unbounded_channel_base_node< T > * p) -{ - if ( p->use_count.fetch_sub( 1, memory_order_release) == 1) - { - atomic_thread_fence( memory_order_acquire); - delete p; - } -} - -template< typename T > -class unbounded_channel_base : private noncopyable -{ -public: - typedef optional< T > value_type; - -private: - typedef unbounded_channel_base_node< value_type > node_type; - - template< typename X > - friend void intrusive_ptr_add_ref( unbounded_channel_base< X > * p); - template< typename X > - friend void intrusive_ptr_release( unbounded_channel_base< X > * p); - - enum state - { - ACTIVE = 0, - DEACTIVE - }; - - atomic< state > state_; - typename node_type::ptr head_; - mutable mutex head_mtx_; - typename node_type::ptr tail_; - mutable mutex tail_mtx_; - condition not_empty_cond_; - atomic< std::size_t > use_count_; - - bool active_() const - { return ACTIVE == state_.load(); } - - void deactivate_() - { state_.store( DEACTIVE); } - - bool empty_() const - { return head_ == get_tail_(); } - - typename node_type::ptr get_tail_() const - { - mutex::scoped_lock lk( tail_mtx_); - typename node_type::ptr tmp = tail_; - return tmp; - } - - typename node_type::ptr pop_head_() - { - typename node_type::ptr old_head = head_; - head_ = old_head->next; - return old_head; - } - -public: - unbounded_channel_base() : - state_( ACTIVE), - head_( new node_type() ), - head_mtx_(), - tail_( head_), - tail_mtx_(), - not_empty_cond_(), - use_count_( 0) - {} - - bool active() const - { return active_(); } - - void deactivate() - { - mutex::scoped_lock lk( head_mtx_); - deactivate_(); - not_empty_cond_.notify_all(); - } - - bool empty() const - { - mutex::scoped_lock lk( head_mtx_); - return empty_(); - } - - void put( T const& t) - { - typename node_type::ptr new_node( new node_type() ); - { - mutex::scoped_lock lk( tail_mtx_); - - if ( ! active_() ) - throw std::runtime_error("queue is not active"); - - tail_->va = t; - tail_->next = new_node; - tail_ = new_node; - } - not_empty_cond_.notify_one(); - } - - bool take( value_type & va) - { - mutex::scoped_lock lk( head_mtx_); - bool empty = empty_(); - if ( ! active_() && empty) - return false; - if ( empty) - { - try - { - while ( active_() && empty_() ) - not_empty_cond_.wait( lk); - } - catch ( task_interrupted const&) - { return false; } - } - - if ( ! active_() && empty_() ) - return false; - swap( va, head_->va); - pop_head_(); - return va; - } - - bool take( value_type & va, system_time const& abs_time) - { - mutex::scoped_lock lk( head_mtx_); - bool empty = empty_(); - if ( ! active_() && empty) - return false; - if ( empty) - { - try - { - while ( active_() && empty_() ) - if ( ! not_empty_cond_.timed_wait( lk, abs_time) ) - return false; - } - catch ( task_interrupted const&) - { return false; } - } - if ( ! active_() && empty_() ) - return false; - swap( va, head_->va); - pop_head_(); - return va; - } - - bool try_take( value_type & va) - { - mutex::scoped_lock lk( head_mtx_); - if ( empty_() ) - return false; - swap( va, head_->va); - pop_head_(); - return va; - } -}; - -template< typename T > -void intrusive_ptr_add_ref( unbounded_channel_base< T > * p) -{ p->use_count_.fetch_add( 1, memory_order_relaxed); } - -template< typename T > -void intrusive_ptr_release( unbounded_channel_base< T > * p) -{ - if ( p->use_count_.fetch_sub( 1, memory_order_release) == 1) - { - atomic_thread_fence( memory_order_acquire); - delete p; - } -} - -} - -template< typename T > -class unbounded_channel -{ -private: - typedef typename detail::unbounded_channel_base< T >::value_type value_type; - - intrusive_ptr< detail::unbounded_channel_base< T > > base_; - -public: - unbounded_channel() : - base_( new detail::unbounded_channel_base< T >() ) - {} - - bool active() const - { return base_->active(); } - - void deactivate() - { base_->deactivate(); } - - bool empty() - { return base_->empty(); } - - void put( T const& t) - { base_->put( t); } - - bool take( value_type & va) - { return base_->take( va); } - - bool take( value_type & va, system_time const& abs_time) - { return base_->take( va, abs_time); } - - template< typename TimeDuration > - bool take( value_type & va, TimeDuration const& rel_time) - { return base_->take( va, get_system_time() + rel_time); } - - bool try_take( value_type & va) - { return base_->try_take( va); } -}; - -}}} - -#include - -#endif // BOOST_TASKS_SPIN_UNBOUNDED_CHANNEL_H diff --git a/boost/task/stacksize.hpp b/boost/task/stacksize.hpp deleted file mode 100755 index f07c467d..00000000 --- a/boost/task/stacksize.hpp +++ /dev/null @@ -1,43 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_TASKS_STACKSIZE_H -#define BOOST_TASKS_STACKSIZE_H - -#include - -#include - -#include - -# if defined(BOOST_MSVC) -# pragma warning(push) -# pragma warning(disable:4251 4275) -# endif - -namespace boost { -namespace tasks { - -class BOOST_TASKS_DECL stacksize -{ -private: - std::size_t value_; - -public: - explicit stacksize( std::size_t value); - - operator std::size_t () const; -}; - -}} - -# if defined(BOOST_MSVC) -# pragma warning(pop) -# endif - -#include - -#endif // BOOST_TASKS_STACKSIZE_H diff --git a/boost/task/static_pool.hpp b/boost/task/static_pool.hpp deleted file mode 100644 index 8ab67cfe..00000000 --- a/boost/task/static_pool.hpp +++ /dev/null @@ -1,208 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_TASKS_STATIC_POOL_H -#define BOOST_TASKS_STATIC_POOL_H - -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace tasks { - -template< - typename Queue, - typename UMS = tasklets::round_robin -> -class static_pool -{ -public: - typedef Queue queue_type; - typedef UMS ums_type; - -private: - typedef detail::pool_base< queue_type, ums_type > base_type; - - template< typename T, typename X > - friend class detail::worker_object; - - BOOST_MOVABLE_BUT_NOT_COPYABLE( static_pool); - -# if defined(BOOST_HAS_PROCESSOR_BINDINGS) - struct tag_bind_to_processors {}; -# endif - - intrusive_ptr< base_type > pool_; - -public: - static_pool() : - pool_() - {} - - explicit static_pool( - poolsize const& psize, - stacksize const& stack_size = stacksize( tasklet::default_stacksize) ) : - pool_( new base_type( psize, stack_size) ) - {} - - explicit static_pool( - poolsize const& psize, - high_watermark const& hwm, - low_watermark const& lwm, - stacksize const& stack_size = stacksize( tasklet::default_stacksize) ) : - pool_( new base_type( psize, hwm, lwm, stack_size) ) - {} - -# if defined(BOOST_HAS_PROCESSOR_BINDINGS) - explicit static_pool( - tag_bind_to_processors, - stacksize const& stack_size = stacksize( tasklet::default_stacksize) ) : - pool_( new base_type( stack_size) ) - {} - - explicit static_pool( - tag_bind_to_processors, - high_watermark const& hwm, - low_watermark const& lwm, - stacksize const& stack_size = stacksize( tasklet::default_stacksize) ) : - pool_( new base_type( hwm, lwm, stack_size) ) - {} - - static tag_bind_to_processors bind_to_processors() - { return tag_bind_to_processors(); } -# endif - - static_pool( BOOST_RV_REF( static_pool) other) : - pool_() - { pool_.swap( other.pool_); } - - static_pool & operator=( BOOST_RV_REF( static_pool) other) - { - static_pool tmp( other); - swap( tmp); - return * this; - } - - void interrupt_all_worker() - { - if ( ! pool_) - throw pool_moved(); - pool_->interrupt_all_worker(); - } - - void shutdown() - { - if ( ! pool_) - throw pool_moved(); - pool_->shutdown(); - } - - const void shutdown_now() - { - if ( ! pool_) - throw pool_moved(); - pool_->shutdown_now(); - } - - std::size_t size() - { - if ( ! pool_) - throw pool_moved(); - return pool_->size(); - } - - bool closed() - { - if ( ! pool_) - throw pool_moved(); - return pool_->closed(); - } - - std::size_t upper_bound() - { - if ( ! pool_) - throw pool_moved(); - return pool_->upper_bound(); - } - - void upper_bound( high_watermark const& hwm) - { - if ( ! pool_) - throw pool_moved(); - pool_->upper_bound( hwm); - } - - std::size_t lower_bound() - { - if ( ! pool_) - throw pool_moved(); - return pool_->lower_bound(); - } - - void lower_bound( low_watermark const lwm) - { - if ( ! pool_) - throw pool_moved(); - pool_->lower_bound( lwm); - } - - template< typename R > - handle< R > submit( task< R > t) - { - if ( ! pool_) - throw pool_moved(); - return pool_->submit( boost::move( t) ); - } - - template< typename R, typename Attr > - handle< R > submit( task< R > t, Attr const& attr) - { - if ( ! pool_) - throw pool_moved(); - return pool_->submit( boost::move( t), attr); - } - - typedef typename shared_ptr< base_type >::unspecified_bool_type unspecified_bool_type; - - operator unspecified_bool_type() const // throw() - { return pool_; } - - bool operator!() const // throw() - { return ! pool_; } - - void swap( static_pool & other) // throw() - { pool_.swap( other.pool_); } -}; - -} - -template< typename Queue, typename UMS > -void swap( tasks::static_pool< Queue, UMS > & l, tasks::static_pool< Queue, UMS > & r) -{ return l.swap( r); } - -} - -#include - -#endif // BOOST_TASKS_STATIC_POOL_H - diff --git a/boost/task/task.hpp b/boost/task/task.hpp deleted file mode 100644 index ec5ed05c..00000000 --- a/boost/task/task.hpp +++ /dev/null @@ -1,497 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_TASKS_TASK_H -#define BOOST_TASKS_TASK_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -namespace boost { -namespace tasks { -namespace detail { - -template< typename R > -struct promise_adaptor -{ - template< typename X > - friend void intrusive_ptr_add_ref( promise_adaptor< X > *); - template< typename X > - friend void intrusive_ptr_release( promise_adaptor< X > *); - - typedef intrusive_ptr< promise_adaptor > ptr; - - atomic< unsigned int > use_count; - - virtual ~promise_adaptor() {} - - virtual void set_value( - typename tasks::detail::future_traits< R >::source_reference_type) = 0; - - virtual void set_value( - typename tasks::detail::future_traits< R >::rvalue_source_type) = 0; - - virtual void set_exception( exception_ptr) = 0; -}; - -template<> -struct promise_adaptor< void > -{ - template< typename X > - friend void intrusive_ptr_add_ref( promise_adaptor< X > *); - template< typename X > - friend void intrusive_ptr_release( promise_adaptor< X > *); - - typedef intrusive_ptr< promise_adaptor > ptr; - - atomic< unsigned int > use_count; - - virtual ~promise_adaptor() {} - - virtual void set_value() = 0; - - virtual void set_exception( exception_ptr) = 0; -}; - -template< typename R > -void intrusive_ptr_add_ref( promise_adaptor< R > * p) -{ p->use_count.fetch_add( 1, memory_order_relaxed); } - -template< typename R > -void intrusive_ptr_release( promise_adaptor< R > * p) -{ - if ( p->use_count.fetch_sub( 1, memory_order_release) == 1) - { - atomic_thread_fence( memory_order_acquire); - delete p; - } -} - -template< typename R, template< typename > class Promise > -class promise_wrapper; - -template< typename R > -class promise_wrapper< R, promise > : public promise_adaptor< R > -{ -private: - promise< R > prom_; - -public: -#ifdef BOOST_HAS_RVALUE_REFS - promise_wrapper( promise< R > && prom) : - prom_( prom) - {} -#else - promise_wrapper( boost::detail::thread_move_t< promise< R > > prom) : - prom_( prom) - {} -#endif - - void set_value( - typename tasks::detail::future_traits< R >::source_reference_type r) - { prom_.set_value( r); }; - - void set_value( - typename tasks::detail::future_traits< R >::rvalue_source_type r) - { prom_.set_value( r); }; - - void set_exception( exception_ptr p) - { prom_.set_exception( p); } -}; - -template<> -class promise_wrapper< void, promise > : public promise_adaptor< void > -{ -private: - promise< void > prom_; - -public: -#ifdef BOOST_HAS_RVALUE_REFS - promise_wrapper( promise< void > && prom) : - prom_( prom) - {} -#else - promise_wrapper( boost::detail::thread_move_t< promise< void > > prom) : - prom_( prom) - {} -#endif - - void set_value() - { prom_.set_value(); }; - - void set_exception( exception_ptr p) - { prom_.set_exception( p); } -}; - -template< typename R > -class promise_wrapper< R, spin::promise > : public promise_adaptor< R > -{ -private: - spin::promise< R > prom_; - -public: - promise_wrapper() : - prom_() - {} - - promise_wrapper( BOOST_RV_REF( spin::promise< R >) prom) : - prom_( prom) - {} - - void set_value( - typename tasks::detail::future_traits< R >::source_reference_type r) - { prom_.set_value( r); }; - - void set_value( - typename tasks::detail::future_traits< R >::rvalue_source_type r) - { prom_.set_value( r); }; - - void set_exception( exception_ptr p) - { prom_.set_exception( p); } -}; - -template<> -class promise_wrapper< void, spin::promise > : public promise_adaptor< void > -{ -private: - spin::promise< void > prom_; - -public: - promise_wrapper() : - prom_() - {} - - promise_wrapper( BOOST_RV_REF( spin::promise< void >) prom) : - prom_( prom) - {} - - void set_value() - { prom_.set_value(); }; - - void set_exception( exception_ptr p) - { prom_.set_exception( p); } -}; - -template< typename R > -class task_base -{ -private: - template< typename X > - friend void intrusive_ptr_add_ref( task_base< X > *); - template< typename X > - friend void intrusive_ptr_release( task_base< X > *); - - atomic< unsigned int > use_count_; - -protected: - bool done_; - typename promise_adaptor< R >::ptr prom_; - - virtual void do_run() = 0; - -public: - task_base() : - done_( false), - prom_( new promise_wrapper< R, spin::promise >() ) - {} - - virtual ~task_base() {} - - void run() - { - if ( this->done_) throw task_already_executed(); - do_run(); - done_ = true; - } - - void set_promise( typename promise_adaptor< R >::ptr prom) - { prom_ = prom; } -}; - -template< typename R > -void intrusive_ptr_add_ref( task_base< R > * p) -{ p->use_count_.fetch_add( 1, memory_order_relaxed); } - -template< typename R > -void intrusive_ptr_release( task_base< R > * p) -{ - if ( p->use_count_.fetch_sub( 1, memory_order_release) == 1) - { - atomic_thread_fence( memory_order_acquire); - delete p; - } -} - -template< typename R, typename Fn > -class task_wrapper : public task_base< R > -{ -private: - Fn fn_; - - void do_run() - { - try - { this->prom_->set_value( fn_() ); } - catch ( promise_already_satisfied const&) - { throw task_already_executed(); } - catch ( thread_interrupted const&) - { this->prom_->set_exception( copy_exception( task_interrupted() ) ); } - catch ( task_interrupted const& e) - { this->prom_->set_exception( copy_exception( e) ); } - catch ( boost::exception const& e) - { this->prom_->set_exception( copy_exception( e) ); } - catch ( std::ios_base::failure const& e) - { this->prom_->set_exception( copy_exception( e) ); } - catch ( std::domain_error const& e) - { this->prom_->set_exception( copy_exception( e) ); } - catch ( std::invalid_argument const& e) - { this->prom_->set_exception( copy_exception( e) ); } - catch ( std::length_error const& e) - { this->prom_->set_exception( copy_exception( e) ); } - catch ( std::out_of_range const& e) - { this->prom_->set_exception( copy_exception( e) ); } - catch ( std::logic_error const& e) - { this->prom_->set_exception( copy_exception( e) ); } - catch ( std::overflow_error const& e) - { this->prom_->set_exception( copy_exception( e) ); } - catch ( std::range_error const& e) - { this->prom_->set_exception( copy_exception( e) ); } - catch ( std::underflow_error const& e) - { this->prom_->set_exception( copy_exception( e) ); } - catch ( std::runtime_error const& e) - { this->prom_->set_exception( copy_exception( e) ); } - catch ( std::bad_alloc const& e) - { this->prom_->set_exception( copy_exception( e) ); } - catch ( std::bad_cast const& e) - { this->prom_->set_exception( copy_exception( e) ); } - catch ( std::bad_typeid const& e) - { this->prom_->set_exception( copy_exception( e) ); } - catch ( std::bad_exception const& e) - { this->prom_->set_exception( copy_exception( e) ); } - catch (...) - { this->prom_->set_exception( current_exception() ); } - } - -public: - task_wrapper( Fn const& fn) : - task_base< R >(), fn_( fn) - {} -}; - -template< typename Fn > -class task_wrapper< void, Fn > : public task_base< void > -{ -private: - Fn fn_; - - void do_run() - { - try - { - fn_(); - this->prom_->set_value(); - } - catch ( promise_already_satisfied const&) - { throw task_already_executed(); } - catch ( thread_interrupted const&) - { this->prom_->set_exception( copy_exception( task_interrupted() ) ); } - catch ( task_interrupted const& e) - { this->prom_->set_exception( copy_exception( e) ); } - catch ( boost::exception const& e) - { this->prom_->set_exception( copy_exception( e) ); } - catch ( std::ios_base::failure const& e) - { this->prom_->set_exception( copy_exception( e) ); } - catch ( std::domain_error const& e) - { this->prom_->set_exception( copy_exception( e) ); } - catch ( std::invalid_argument const& e) - { this->prom_->set_exception( copy_exception( e) ); } - catch ( std::length_error const& e) - { this->prom_->set_exception( copy_exception( e) ); } - catch ( std::out_of_range const& e) - { this->prom_->set_exception( copy_exception( e) ); } - catch ( std::logic_error const& e) - { this->prom_->set_exception( copy_exception( e) ); } - catch ( std::overflow_error const& e) - { this->prom_->set_exception( copy_exception( e) ); } - catch ( std::range_error const& e) - { this->prom_->set_exception( copy_exception( e) ); } - catch ( std::underflow_error const& e) - { this->prom_->set_exception( copy_exception( e) ); } - catch ( std::runtime_error const& e) - { this->prom_->set_exception( copy_exception( e) ); } - catch ( std::bad_alloc const& e) - { this->prom_->set_exception( copy_exception( e) ); } - catch ( std::bad_cast const& e) - { this->prom_->set_exception( copy_exception( e) ); } - catch ( std::bad_typeid const& e) - { this->prom_->set_exception( copy_exception( e) ); } - catch ( std::bad_exception const& e) - { this->prom_->set_exception( copy_exception( e) ); } - catch (...) - { this->prom_->set_exception( current_exception() ); } - } - -public: - task_wrapper( Fn const& fn) : - task_base< void >(), fn_( fn) - {} -}; - -} - -template< typename R > -class task -{ -private: - template< typename T, typename P > - friend class detail::callable_object; - - BOOST_MOVABLE_BUT_NOT_COPYABLE( task); - - intrusive_ptr< detail::task_base< R > > task_; - -// TODO: if boost.thread uses boost.move -// re-work set_promise -#ifdef BOOST_HAS_RVALUE_REFS - void set_promise( promise< R > && prom) - { - if ( ! task_) throw task_moved(); - task_->set_promise( - new detail::promise_wrapper< R, promise >( prom) ); - } -#else - void set_promise( boost::detail::thread_move_t< promise< R > > prom) - { - if ( ! task_) throw task_moved(); - task_->set_promise( - new detail::promise_wrapper< R, promise >( prom) ); - } -#endif - - void set_promise( BOOST_RV_REF( spin::promise< R >) prom) - { - if ( ! task_) throw task_moved(); - task_->set_promise( - new detail::promise_wrapper< R, spin::promise >( prom) ); - } - -public: - task() : - task_() - {} - - explicit task( R( * fn)()) : - task_( new detail::task_wrapper< R, R( *)() >( fn) ) - {} - - template< typename Fn > - explicit task( BOOST_RV_REF( Fn) fn) : - task_( new detail::task_wrapper< R, Fn >( fn) ) - {} - - task( BOOST_RV_REF( task) other) : - task_() - { task_.swap( other.task_); } - - task & operator=( BOOST_RV_REF( task) other) - { - task tmp( other); - swap( tmp); - return * this; - } - -# ifndef BOOST_TASKS_MAX_ARITY -# define BOOST_TASKS_MAX_ARITY 10 -# endif - -# define BOOST_TASKS_ARG(z, n, unused) \ - BOOST_PP_CAT(A, n) BOOST_PP_CAT(a, n) -# define BOOST_ENUM_TASK_ARGS(n) BOOST_PP_ENUM(n, BOOST_TASKS_ARG, ~) - -# define BOOST_TASKS_CTOR(z, n, unused) \ -template< \ - typename Fn, \ - BOOST_PP_ENUM_PARAMS(n, typename A) \ -> \ -explicit task( Fn fn, BOOST_ENUM_TASK_ARGS(n)) \ - : task_( \ - new detail::task_wrapper< R, function< R() > >( \ - bind( fn, BOOST_PP_ENUM_PARAMS(n, a)) ) ) \ - {} - -BOOST_PP_REPEAT_FROM_TO( 1, BOOST_TASKS_MAX_ARITY, BOOST_TASKS_CTOR, ~) - -# undef BOOST_TASKS_CTOR - - void operator()() - { - if ( ! task_) throw task_moved(); - task_->run(); - } - - typedef typename shared_ptr< detail::task_base< R > >::unspecified_bool_type - unspecified_bool_type; - - operator unspecified_bool_type() const // throw() - { return task_; } - - bool operator!() const // throw() - { return ! task_; } - - void swap( task & other) // throw() - { task_.swap( other.task_); } -}; - -template< typename Fn > -task< typename result_of< Fn() >::type > make_task( Fn fn) -{ return task< typename boost::result_of< Fn() >::type >( fn); } - -# define BOOST_TASKS_MAKE_TASK_FUNCTION(z, n, unused) \ -template< \ - typename Fn, \ - BOOST_PP_ENUM_PARAMS(n, typename A) \ -> \ -task< typename result_of< Fn( BOOST_PP_ENUM_PARAMS(n, A)) >::type > \ -make_task( Fn fn, BOOST_ENUM_TASK_ARGS(n)) \ -{ \ - return task< \ - typename result_of< Fn( BOOST_PP_ENUM_PARAMS(n, A)) >::type >( \ - fn, BOOST_PP_ENUM_PARAMS(n, a)); \ -} - -BOOST_PP_REPEAT_FROM_TO(1,BOOST_TASKS_MAX_ARITY,BOOST_TASKS_MAKE_TASK_FUNCTION, ~) - -# undef BOOST_TASKS_MAKE_TASK_FUNCTION -# undef BOOST_ENUM_TASK_ARGS -# undef BOOST_TASKS_ARG -# undef BOOST_TASKS_MAX_ARITY - -} - -using tasks::task; - -template< typename R > -void swap( task< R > & l, task< R > & r) -{ return l.swap( r); } - -} - -#include - -#endif // BOOST_TASKS_TASK_H diff --git a/boost/task/unbounded_fifo.hpp b/boost/task/unbounded_fifo.hpp deleted file mode 100644 index 216fdb8f..00000000 --- a/boost/task/unbounded_fifo.hpp +++ /dev/null @@ -1,135 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_TASKS_UNBOUNDED_FIFO_H -#define BOOST_TASKS_UNBOUNDED_FIFO_H - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -namespace boost { -namespace tasks { - -class unbounded_fifo -{ -public: - typedef detail::has_no_attribute attribute_tag_type; - typedef callable value_type; - -private: - struct node - { - typedef shared_ptr< node > sptr_t; - - value_type va; - sptr_t next; - }; - - enum state - { - ACTIVE = 0, - DEACTIVE - }; - - atomic< state > state_; - node::sptr_t head_; - mutable mutex head_mtx_; - node::sptr_t tail_; - mutable mutex tail_mtx_; - fast_semaphore & fsem_; - - bool active_() const - { return ACTIVE == state_.load(); } - - void deactivate_() - { state_.store( DEACTIVE); } - - bool empty_() const - { return head_ == get_tail_(); } - - node::sptr_t get_tail_() const - { - lock_guard< mutex > lk( tail_mtx_); - node::sptr_t tmp = tail_; - return tmp; - } - - node::sptr_t pop_head_() - { - node::sptr_t old_head = head_; - head_ = old_head->next; - return old_head; - } - -public: - unbounded_fifo( fast_semaphore & fsem) : - state_( ACTIVE), - head_( new node), - head_mtx_(), - tail_( head_), - tail_mtx_(), - fsem_( fsem) - {} - - bool active() const - { return active_(); } - - void deactivate() - { - unique_lock< mutex > lk( head_mtx_); - deactivate_(); - } - - bool empty() const - { - unique_lock< mutex > lk( head_mtx_); - return empty_(); - } - - void put( value_type const& va) - { - node::sptr_t new_node( new node); - { - unique_lock< mutex > lk( tail_mtx_); - if ( ! active_() ) - throw task_rejected("queue is not active"); - tail_->va = va; - tail_->next = new_node; - tail_ = new_node; - } - fsem_.post(); - } - - bool try_take( value_type & va) - { - unique_lock< mutex > lk( head_mtx_); - if ( empty_() ) - return false; - va.swap( head_->va); - pop_head_(); - return ! va.empty(); - } -}; - -}} - -#include - -#endif // BOOST_TASKS_UNBOUNDED_FIFO_H diff --git a/boost/task/unbounded_prio_queue.hpp b/boost/task/unbounded_prio_queue.hpp deleted file mode 100644 index 13251b27..00000000 --- a/boost/task/unbounded_prio_queue.hpp +++ /dev/null @@ -1,152 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_TASKS_UNBOUNDED_PRIO_QUEUE_H -#define BOOST_TASKS_UNBOUNDED_PRIO_QUEUE_H - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -namespace boost { -namespace tasks { - -template< - typename Attr, - typename Comp = std::less< Attr > -> -class unbounded_prio_queue -{ -public: - typedef detail::has_attribute attribute_tag_type; - typedef Attr attribute_type; - - struct value_type - { - callable ca; - attribute_type attr; - - value_type( - callable const& ca_, - attribute_type const& attr_) : - ca( ca_), attr( attr_) - { BOOST_ASSERT( ! ca.empty() ); } - - void swap( value_type & other) - { - ca.swap( other.ca); - std::swap( attr, other.attr); - } - }; - -private: - struct compare : public std::binary_function< value_type, value_type, bool > - { - bool operator()( value_type const& va1, value_type const& va2) - { return Comp()( va1.attr, va2.attr); } - }; - - typedef std::priority_queue< - value_type, - std::deque< value_type >, - compare - > queue_type; - - enum state - { - ACTIVE = 0, - DEACTIVE - }; - - atomic< state > state_; - queue_type queue_; - mutable shared_mutex mtx_; - fast_semaphore & fsem_; - - bool active_() const - { return ACTIVE == state_.load(); } - - void deactivate_() - { state_.store( DEACTIVE); } - - bool empty_() const - { return queue_.empty(); } - - void put_( value_type const& va) - { - if ( ! active_() ) - throw task_rejected("queue is not active"); - queue_.push( va); - fsem_.post(); - } - - bool try_take_( callable & ca) - { - if ( empty_() ) - return false; - callable tmp( queue_.top().ca); - queue_.pop(); - ca.swap( tmp); - return ! ca.empty(); - } - -public: - unbounded_prio_queue( fast_semaphore & fsem) : - state_( ACTIVE), - queue_(), - mtx_(), - fsem_( fsem) - {} - - bool active() const - { return active_(); } - - void deactivate() - { - unique_lock< shared_mutex > lk( mtx_); - deactivate_(); - } - - bool empty() const - { - shared_lock< shared_mutex > lk( mtx_); - return empty_(); - } - - void put( value_type const& va) - { - unique_lock< shared_mutex > lk( mtx_); - put_( va); - } - - bool try_take( callable & ca) - { - unique_lock< shared_mutex > lk( mtx_); - return try_take_( ca); - } -}; - -}} - -#include - -#endif // BOOST_TASKS_UNBOUNDED_PRIO_QUEUE_H diff --git a/boost/task/unbounded_smart_queue.hpp b/boost/task/unbounded_smart_queue.hpp deleted file mode 100644 index 24244d0a..00000000 --- a/boost/task/unbounded_smart_queue.hpp +++ /dev/null @@ -1,163 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_TASKS_UNBOUNDED_SMART_QUEUE_H -#define BOOST_TASKS_UNBOUNDED_SMART_QUEUE_H - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace tasks { - -template< - typename Attr, - typename Comp, - typename Enq = detail::replace_oldest, - typename Deq = detail::take_oldest -> -class unbounded_smart_queue -{ -public: - typedef detail::has_attribute attribute_tag_type; - typedef Attr attribute_type; - - struct value_type - { - callable ca; - attribute_type attr; - - value_type( - callable const& ca_, - attribute_type const& attr_) : - ca( ca_), attr( attr_) - { BOOST_ASSERT( ! ca.empty() ); } - - void swap( value_type & other) - { - ca.swap( other.ca); - std::swap( attr, other.attr); - } - }; - -private: - typedef multi_index::multi_index_container< - value_type, - multi_index::indexed_by< - multi_index::ordered_non_unique< - multi_index::member< - value_type, - Attr, - & value_type::attr - >, - Comp - > - > - > queue_type; - typedef typename queue_type::template nth_index< 0 >::type queue_index; - - enum state - { - ACTIVE = 0, - DEACTIVE - }; - - atomic< state > state_; - queue_type queue_; - queue_index & idx_; - mutable shared_mutex mtx_; - Enq enq_op_; - Deq deq_op_; - fast_semaphore & fsem_; - - bool active_() const - { return ACTIVE == state_.load(); } - - void deactivate_() - { state_.store( DEACTIVE); } - - bool empty_() const - { return queue_.empty(); } - - void put_( value_type const& va) - { - if ( ! active_() ) - throw task_rejected("queue is not active"); - enq_op_( idx_, va); - fsem_.post(); - } - - bool try_take_( callable & ca) - { - if ( empty_() ) - return false; - deq_op_( idx_, ca); - return ! ca.empty(); - } - -public: - unbounded_smart_queue( fast_semaphore & fsem) : - state_( ACTIVE), - queue_(), - idx_( queue_.get< 0 >() ), - mtx_(), - enq_op_(), - deq_op_(), - fsem_( fsem) - {} - - bool active() const - { return active_(); } - - void deactivate() - { - unique_lock< shared_mutex > lk( mtx_); - deactivate_(); - } - - bool empty() const - { - shared_lock< shared_mutex > lk( mtx_); - return empty_(); - } - - void put( value_type const& va) - { - unique_lock< shared_mutex > lk( mtx_); - put_( va); - } - - bool try_take( callable & ca) - { - unique_lock< shared_mutex > lk( mtx_); - return try_take_( ca); - } -}; - -}} - -#include - -#endif // BOOST_TASKS_UNBOUNDED_SMART_QUEUE_H diff --git a/boost/task/utility.hpp b/boost/task/utility.hpp deleted file mode 100644 index 3cb64e57..00000000 --- a/boost/task/utility.hpp +++ /dev/null @@ -1,44 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt)txt) - -#ifndef BOOST_TASKS_UTILITY_H -#define BOOST_TASKS_UTILITY_H - -#include -#include - -#include - -#include - -namespace boost { -namespace this_task { - -inline -void yield() -{ - tasks::detail::worker * w( tasks::detail::worker::tss_get() ); - BOOST_ASSERT( w); - w->yield(); -} - -inline -bool runs_in_pool() -{ return tasks::detail::worker::tss_get() != 0; } - -inline -thread::id worker_id() -{ - tasks::detail::worker * w( tasks::detail::worker::tss_get() ); - BOOST_ASSERT( w); - return w->get_id(); -} - -}} - -#include - -#endif // BOOST_TASKS_UTILITY_H diff --git a/boost/task/watermark.hpp b/boost/task/watermark.hpp deleted file mode 100644 index 829e1cc2..00000000 --- a/boost/task/watermark.hpp +++ /dev/null @@ -1,54 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_TASKS_WATER_MARK_H -#define BOOST_TASKS_WATER_MARK_H - -#include - -#include - -#include - -# if defined(BOOST_MSVC) -# pragma warning(push) -# pragma warning(disable:4251 4275) -# endif - -namespace boost { -namespace tasks { - -class BOOST_TASKS_DECL high_watermark -{ -private: - std::size_t value_; - -public: - explicit high_watermark( std::size_t value); - - operator std::size_t () const; -}; - -class BOOST_TASKS_DECL low_watermark -{ -private: - std::size_t value_; - -public: - explicit low_watermark( std::size_t value); - - operator std::size_t () const; -}; - -}} - -# if defined(BOOST_MSVC) -# pragma warning(pop) -# endif - -#include - -#endif // BOOST_TASKS_WATER_MARK_H diff --git a/boost/tasklet.hpp b/boost/tasklet.hpp deleted file mode 100644 index d3901708..00000000 --- a/boost/tasklet.hpp +++ /dev/null @@ -1,27 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_TASKLET_H -#define BOOST_TASKLET_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#endif // BOOST_TASKLET_H diff --git a/boost/tasklet/auto_reset_event.hpp b/boost/tasklet/auto_reset_event.hpp deleted file mode 100644 index 3cc9330c..00000000 --- a/boost/tasklet/auto_reset_event.hpp +++ /dev/null @@ -1,59 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_TASKLETS_AUTO_RESET_EVENT_H -#define BOOST_TASKLETS_AUTO_RESET_EVENT_H - -#include -#include -#include - -#include - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_PREFIX -#endif - -# if defined(BOOST_MSVC) -# pragma warning(push) -# pragma warning(disable:4355 4251 4275) -# endif - -namespace boost { -namespace tasklets { - -class BOOST_TASKLET_DECL auto_reset_event : private noncopyable -{ -private: - enum state - { - SET = 0, - RESET - }; - - atomic< state > state_; - -public: - explicit auto_reset_event( bool = false); - - void set(); - - void wait(); - - bool try_wait(); -}; - -}} - -# if defined(BOOST_MSVC) -# pragma warning(pop) -# endif - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_SUFFIX -#endif - -#endif // BOOST_TASKLETS_AUTO_RESET_EVENT_H diff --git a/boost/tasklet/barrier.hpp b/boost/tasklet/barrier.hpp deleted file mode 100644 index 9efb14c9..00000000 --- a/boost/tasklet/barrier.hpp +++ /dev/null @@ -1,56 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_TASKLETS_BARRIER_H -#define BOOST_TASKLETS_BARRIER_H - -#include - -#include -#include - -#include -#include -#include - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_PREFIX -#endif - -# if defined(BOOST_MSVC) -# pragma warning(push) -# pragma warning(disable:4275) -# endif - -namespace boost { -namespace tasklets { - -class BOOST_TASKLET_DECL barrier : private noncopyable -{ -private: - std::size_t initial_; - std::size_t current_; - bool cycle_; - mutex mtx_; - condition cond_; - -public: - barrier( std::size_t); - - bool wait(); -}; - -}} - -# if defined(BOOST_MSVC) -# pragma warning(pop) -# endif - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_SUFFIX -#endif - -#endif // BOOST_TASKLETS_BARRIER_H diff --git a/boost/tasklet/bounded_channel.hpp b/boost/tasklet/bounded_channel.hpp deleted file mode 100644 index 0af58560..00000000 --- a/boost/tasklet/bounded_channel.hpp +++ /dev/null @@ -1,265 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_TASKLETS_BOUNDED_CHANNEL_H -#define BOOST_TASKLETS_BOUNDED_CHANNEL_H - -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_PREFIX -#endif - -namespace boost { -namespace tasklets { -namespace detail { - -template< typename T > -struct bounded_channel_node -{ - typedef intrusive_ptr< bounded_channel_node > ptr; - - atomic< std::size_t > use_count; - T va; - ptr next; - - bounded_channel_node() : - use_count( 0), - va(), - next() - {} -}; - -template< typename T > -void intrusive_ptr_add_ref( bounded_channel_node< T > * p) -{ p->use_count.fetch_add( 1, memory_order_relaxed); } - -template< typename T > -void intrusive_ptr_release( bounded_channel_node< T > * p) -{ - if ( p->use_count.fetch_sub( 1, memory_order_release) == 1) - { - atomic_thread_fence( memory_order_acquire); - delete p; - } -} - -} - -template< typename T > -class bounded_channel : private noncopyable -{ -public: - typedef optional< T > value_type; - -private: - typedef detail::bounded_channel_node< value_type > node_type; - - template< typename X > - friend void intrusive_ptr_add_ref( bounded_channel< X > * p); - template< typename X > - friend void intrusive_ptr_release( bounded_channel< X > * p); - - enum state - { - ACTIVE = 0, - DEACTIVE - }; - - atomic< state > state_; - atomic< std::size_t > count_; - typename node_type::ptr head_; - mutable mutex head_mtx_; - typename node_type::ptr tail_; - mutable mutex tail_mtx_; - condition not_empty_cond_; - condition not_full_cond_; - unsigned int hwm_; - unsigned int lwm_; - atomic< std::size_t > use_count_; - - bool active_() const - { return ACTIVE == state_.load(); } - - void deactivate_() - { state_.store( DEACTIVE); } - - std::size_t size_() const - { return count_.load(); } - - bool empty_() const - { return head_ == get_tail_(); } - - bool full_() const - { return size_() >= hwm_; } - - typename node_type::ptr get_tail_() const - { - mutex::scoped_lock lk( tail_mtx_); - typename node_type::ptr tmp = tail_; - return tmp; - } - - typename node_type::ptr pop_head_() - { - typename node_type::ptr old_head = head_; - head_ = old_head->next; - count_.fetch_sub( 1); - return old_head; - } - -public: - bounded_channel( - std::size_t hwm, - std::size_t lwm) : - state_( ACTIVE), - count_( 0), - head_( new node_type() ), - head_mtx_(), - tail_( head_), - tail_mtx_(), - not_empty_cond_(), - not_full_cond_(), - hwm_( hwm), - lwm_( lwm), - use_count_( 0) - { - if ( hwm_ < lwm_) - throw invalid_watermark(); - } - - bounded_channel( std::size_t wm) : - state_( ACTIVE), - count_( 0), - head_( new node_type() ), - head_mtx_(), - tail_( head_), - tail_mtx_(), - not_empty_cond_(), - not_full_cond_(), - hwm_( wm), - lwm_( wm), - use_count_( 0) - {} - - std::size_t upper_bound() const - { return hwm_; } - - std::size_t lower_bound() const - { return lwm_; } - - bool active() const - { return active_(); } - - void deactivate() - { - mutex::scoped_lock head_lk( head_mtx_); - mutex::scoped_lock tail_lk( tail_mtx_); - deactivate_(); - not_empty_cond_.notify_all(); - not_full_cond_.notify_all(); - } - - bool empty() const - { - mutex::scoped_lock lk( head_mtx_); - return empty_(); - } - - void put( T const& t) - { - typename node_type::ptr new_node( new node_type() ); - { - mutex::scoped_lock lk( tail_mtx_); - - if ( full_() ) - { - while ( active_() && full_() ) - not_full_cond_.wait( lk); - } - - if ( ! active_() ) - throw std::runtime_error("queue is not active"); - - tail_->va = t; - tail_->next = new_node; - tail_ = new_node; - count_.fetch_add( 1); - } - not_empty_cond_.notify_one(); - } - - bool take( value_type & va) - { - mutex::scoped_lock lk( head_mtx_); - bool empty = empty_(); - if ( ! active_() && empty) - return false; - if ( empty) - { - try - { - while ( active_() && empty_() ) - not_empty_cond_.wait( lk); - } - catch ( tasklet_interrupted const&) - { return false; } - } - if ( ! active_() && empty_() ) - return false; - swap( va, head_->va); - pop_head_(); - if ( size_() <= lwm_) - { - if ( lwm_ == hwm_) - not_full_cond_.notify_one(); - else - // more than one producer could be waiting - // for submiting an action object - not_full_cond_.notify_all(); - } - return va; - } - - bool try_take( value_type & va) - { - mutex::scoped_lock lk( head_mtx_); - if ( empty_() ) - return false; - swap( va, head_->va); - pop_head_(); - bool valid = va; - if ( valid && size_() <= lwm_) - { - if ( lwm_ == hwm_) - not_full_cond_.notify_one(); - else - // more than one producer could be waiting - // in order to submit an task - not_full_cond_.notify_all(); - } - return valid; - } -}; - -}} - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_SUFFIX -#endif - -#endif // BOOST_TASKLETS_BOUNDED_CHANNEL_H diff --git a/boost/tasklet/condition.hpp b/boost/tasklet/condition.hpp deleted file mode 100644 index 692b9fc2..00000000 --- a/boost/tasklet/condition.hpp +++ /dev/null @@ -1,198 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) -// -// based on boost::interprocess::sync::interprocess_condition - -#ifndef BOOST_TASKLETS_CONDITION_H -#define BOOST_TASKLETS_CONDITION_H - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_PREFIX -#endif - -# if defined(BOOST_MSVC) -# pragma warning(push) -# pragma warning(disable:4355 4251 4275) -# endif - -namespace boost { -namespace tasklets { - -class BOOST_TASKLET_DECL condition : private noncopyable -{ -private: - enum command - { - SLEEPING = 0, - NOTIFY_ONE, - NOTIFY_ALL - }; - - struct ordered_idx_tag {}; - struct sequenced_idx_tag {}; - - typedef boost::multi_index::multi_index_container< - tasklet, - boost::multi_index::indexed_by< - boost::multi_index::ordered_unique< - boost::multi_index::tag< ordered_idx_tag >, - boost::multi_index::const_mem_fun< - tasklet, tasklet::id, & tasklet::get_id - > - >, - boost::multi_index::sequenced< - boost::multi_index::tag< sequenced_idx_tag > - > - > - > container; - - typedef container::index< ordered_idx_tag >::type ordered_idx; - typedef container::index< sequenced_idx_tag >::type sequenced_idx; - - object::id oid_; - container waiting_tasklets_; - ordered_idx & oidx_; - sequenced_idx & sidx_; - atomic< command > cmd_; - atomic< std::size_t > waiters_; - mutex enter_mtx_; - mutex check_mtx_; - spin_mutex mtx_; - -public: - condition(); - - ~condition(); - - void notify_one(); - - void notify_all(); - - void wait( unique_lock< mutex > & lk) - { - if ( ! lk) - throw lock_error(); - wait( * lk.mutex() ); - } - - template< typename Pred > - void wait( unique_lock< mutex > & lk, Pred pred) - { - if ( ! lk) - throw lock_error(); - - while ( ! pred() ) - wait( * lk.mutex() ); - } - - template< typename LockType > - void wait( LockType & lt) - { - { - mutex::scoped_lock lk( enter_mtx_); - BOOST_ASSERT( lk); - waiters_.fetch_add( 1); - lt.unlock(); - } - - bool unlock_enter_mtx = false; - for (;;) - { - { - spin_mutex::scoped_lock lk( mtx_); - if ( SLEEPING == cmd_.load() ) - { - if ( this_tasklet::runs_as_tasklet() ) - { - tasklet * f( strategy::active_tasklet); - BOOST_ASSERT( f); - oidx_.insert( * f); - BOOST_ASSERT( f->impl_->attached_strategy() ); - f->impl_->attached_strategy()->wait_for_object( oid_, lk); - continue; - } - else - { - lk.unlock(); - this_thread::yield(); - continue; - } - } - } - - mutex::scoped_lock lk( check_mtx_); - BOOST_ASSERT( lk); - - command expected = NOTIFY_ONE; - cmd_.compare_exchange_strong( expected, SLEEPING); - if ( SLEEPING == expected) - continue; - else if ( NOTIFY_ONE == expected) - { - unlock_enter_mtx = true; - waiters_.fetch_sub( 1); - break; - } - else - { - BOOST_ASSERT( NOTIFY_ALL == expected); - unlock_enter_mtx = 1 == waiters_.fetch_sub( 1); - if ( unlock_enter_mtx) - { - expected = NOTIFY_ALL; - cmd_.compare_exchange_strong( expected, SLEEPING); - } - break; - } - } - - if ( unlock_enter_mtx) - enter_mtx_.unlock(); - - lt.lock(); - } - - template< - typename LockType, - typename Pred - > - void wait( LockType & lt, Pred pred) - { - while ( ! pred() ) - wait( lt); - } -}; - -}} - -# if defined(BOOST_MSVC) -# pragma warning(pop) -# endif - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_SUFFIX -#endif - -#endif // BOOST_TASKLETS_CONDITION_H diff --git a/boost/tasklet/count_down_event.hpp b/boost/tasklet/count_down_event.hpp deleted file mode 100644 index 6479a26a..00000000 --- a/boost/tasklet/count_down_event.hpp +++ /dev/null @@ -1,60 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_TASKLETS_COUNT_DOWN_EVENT_H -#define BOOST_TASKLETS_COUNT_DOWN_EVENT_H - -#include - -#include -#include -#include - -#include - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_PREFIX -#endif - -# if defined(BOOST_MSVC) -# pragma warning(push) -# pragma warning(disable:4355 4251 4275) -# endif - -namespace boost { -namespace tasklets { - -class BOOST_TASKLET_DECL count_down_event : private noncopyable -{ -private: - std::size_t initial_; - atomic< std::size_t > current_; - -public: - explicit count_down_event( std::size_t); - - std::size_t initial() const; - - std::size_t current() const; - - bool is_set() const; - - void set(); - - void wait(); -}; - -}} - -# if defined(BOOST_MSVC) -# pragma warning(pop) -# endif - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_SUFFIX -#endif - -#endif // BOOST_TASKLETS_COUNT_DOWN_EVENT_H diff --git a/boost/tasklet/detail/config.hpp b/boost/tasklet/detail/config.hpp deleted file mode 100644 index 4ccabc11..00000000 --- a/boost/tasklet/detail/config.hpp +++ /dev/null @@ -1,41 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// this file is based on config.hpp of boost.thread - -#ifndef BOOST_TASKLETS_DETAIL_CONFIG_H -#define BOOST_TASKLETS_DETAIL_CONFIG_H - -#include -#include - -#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_TASKLET_DYN_LINK) -# if defined(BOOST_TASKLET_SOURCE) -# define BOOST_TASKLET_DECL BOOST_SYMBOL_EXPORT -# else -# define BOOST_TASKLET_DECL BOOST_SYMBOL_IMPORT -# endif -#else -# define BOOST_TASKLET_DECL -#endif - -#if ! defined(BOOST_TASKLET_SOURCE) && !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_TASKLET_NO_LIB) -# define BOOST_LIB_NAME boost_tasklet -# if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_TASKLET_DYN_LINK) -# define BOOST_DYN_LINK -# endif -# include -#endif - -#if defined(_MSC_VER) -# define BOOST_TASKLET_TSSDECL __declspec(thread) -#elif defined(__GNUC__) -# define BOOST_TASKLET_TSSDECL __thread -#else -# error "this platform is not supported" -#endif - -#endif // BOOST_TASKLETS_DETAIL_CONFIG_H diff --git a/boost/tasklet/detail/future_traits.hpp b/boost/tasklet/detail/future_traits.hpp deleted file mode 100644 index 4d7d12e4..00000000 --- a/boost/tasklet/detail/future_traits.hpp +++ /dev/null @@ -1,90 +0,0 @@ -// (C) Copyright 2008-9 Anthony Williams -// -// Distributed under the Boost Software License, Version 1.0. (See -// accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_TASKLETS_DETAIL_FUTURE_TRAITS_H -#define BOOST_TASKLETS_DETAIL_FUTURE_TRAITS_H - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_PREFIX -#endif - -namespace boost { -namespace tasklets { -namespace detail { - -template -struct future_traits -{ - typedef boost::scoped_ptr storage_type; -#ifdef BOOST_HAS_RVALUE_REFS - typedef T const& source_reference_type; - struct dummy; - typedef typename boost::mpl::if_,dummy&,T&&>::type rvalue_source_type; - typedef typename boost::mpl::if_,T,T&&>::type move_dest_type; -#else - typedef T& source_reference_type; - typedef typename boost::mpl::if_, BOOST_RV_REF( T),T const&>::type rvalue_source_type; - typedef typename boost::mpl::if_,BOOST_RV_REF( T),T>::type move_dest_type; -#endif - - static void init(storage_type& storage,source_reference_type t) - { storage.reset(new T(t)); } - - static void init(storage_type& storage,rvalue_source_type t) - { storage.reset(new T(static_cast(t))); } - - static void cleanup(storage_type& storage) - { storage.reset(); } -}; - -template -struct future_traits -{ - typedef T* storage_type; - typedef T& source_reference_type; - struct rvalue_source_type {}; - typedef T& move_dest_type; - - static void init(storage_type& storage,T& t) - { storage=&t; } - - static void cleanup(storage_type& storage) - { storage=0; } -}; - -template<> -struct future_traits -{ - typedef bool storage_type; - typedef void move_dest_type; - - static void init(storage_type& storage) - { storage=true; } - - static void cleanup(storage_type& storage) - { storage=false; } -}; - -}}} - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_SUFFIX -#endif - -#endif // BOOST_TASKLETS_DETAIL_FUTURE_TRAITS_H diff --git a/boost/tasklet/detail/interrupt_flags.hpp b/boost/tasklet/detail/interrupt_flags.hpp deleted file mode 100644 index a880f168..00000000 --- a/boost/tasklet/detail/interrupt_flags.hpp +++ /dev/null @@ -1,35 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_TASKLETS_DETAIL_INTERRUPT_FLAGS_H -#define BOOST_TASKLETS_DETAIL_INTERRUPT_FLAGS_H - -#include - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_PREFIX -#endif - -namespace boost { -namespace tasklets { -namespace detail { - -enum interrupt_t_ -{ - INTERRUPTION_DISABLED = 1 << 0, - INTERRUPTION_ENABLED = 1 << 1, - INTERRUPTION_BLOCKED = 1 << 2 -}; - -typedef char interrupt_type; - -}}} - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_SUFFIX -#endif - -#endif // BOOST_TASKLETS_DETAIL_INTERRUPT_FLAGS_H diff --git a/boost/tasklet/detail/state_flags.hpp b/boost/tasklet/detail/state_flags.hpp deleted file mode 100644 index 9f9c0787..00000000 --- a/boost/tasklet/detail/state_flags.hpp +++ /dev/null @@ -1,40 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_TASKLETS_DETAIL_STATE_FLAGS_H -#define BOOST_TASKLETS_DETAIL_STATE_FLAGS_H - -#include - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_PREFIX -#endif - -namespace boost { -namespace tasklets { -namespace detail { - -enum state_t_ -{ - STATE_NOT_STARTED = 1 << 0, - STATE_READY = 1 << 1, - STATE_RUNNING = 1 << 2, - STATE_WAIT_FOR_TASKLET = 1 << 3, - STATE_WAIT_FOR_OBJECT = 1 << 4, - STATE_TERMINATED = 1 << 5 -}; - -typedef char state_type; - -#define IS_ALIVE_BIT_MASK 0x1e - -}}} - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_SUFFIX -#endif - -#endif // BOOST_TASKLETS_DETAIL_STATE_FLAGS_H diff --git a/boost/tasklet/detail/tasklet_base.hpp b/boost/tasklet/detail/tasklet_base.hpp deleted file mode 100644 index 4cbdc967..00000000 --- a/boost/tasklet/detail/tasklet_base.hpp +++ /dev/null @@ -1,97 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_TASKLETS_DETAIL_TASKLET_BASE_H -#define BOOST_TASKLETS_DETAIL_TASKLET_BASE_H - -#include - -#include -#include -#include -#include - -#include -#include -#include - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_PREFIX -#endif - -namespace boost { -namespace tasklets { - -class strategy; - -namespace detail { - -BOOST_TASKLET_DECL void trampoline( void *); - -class BOOST_TASKLET_DECL tasklet_base : private noncopyable -{ -public: - typedef intrusive_ptr< tasklet_base > ptr; - - friend BOOST_TASKLET_DECL void trampoline( void *); - - template< typename AllocatorT > - tasklet_base( std::size_t stacksize, AllocatorT const& alloc) : - use_count_( 0), - fib_( trampoline, this, stacksize, alloc), - priority_( 0), - state_( STATE_NOT_STARTED), - interrupt_( INTERRUPTION_DISABLED), - st_( 0) - {} - - virtual ~tasklet_base() {} - - void run(); - - void yield(); - - int priority() const; - - void priority( int); - - state_type state() const; - - void state( state_type); - - interrupt_type & interrupt(); - - void interrupt( interrupt_type); - - strategy * attached_strategy(); - - void attached_strategy( strategy *); - - friend inline void intrusive_ptr_add_ref( tasklet_base * p) - { ++( p->use_count_); } - - friend inline void intrusive_ptr_release( tasklet_base * p) - { if ( 0 == --( p->use_count_) ) delete p; } - -protected: - virtual void exec() = 0; - -private: - std::size_t use_count_; - fiber fib_; - int priority_; - state_type state_; - interrupt_type interrupt_; - strategy * st_; -}; - -}}} - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_SUFFIX -#endif - -#endif // BOOST_TASKLETS_DETAIL_TASKLET_BASE_H diff --git a/boost/tasklet/detail/tasklet_object.hpp b/boost/tasklet/detail/tasklet_object.hpp deleted file mode 100644 index 091f7fad..00000000 --- a/boost/tasklet/detail/tasklet_object.hpp +++ /dev/null @@ -1,99 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_TASKLETS_DETAIL_TASKLET_OBJECT_H -#define BOOST_TASKLETS_DETAIL_TASKLET_OBJECT_H - -#include - -#include -#include -#include - -#include -#include - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_PREFIX -#endif - -namespace boost { -namespace tasklets { -namespace detail { - -template< typename Fn > -class tasklet_object : public tasklet_base -{ -private: - Fn fn_; - - tasklet_object( tasklet_object &); - tasklet_object & operator=( tasklet_object const&); - -public: - template< typename AllocatorT > - tasklet_object( Fn fn, std::size_t stacksize, AllocatorT const& alloc) : - tasklet_base( stacksize, alloc), - fn_( fn) - {} - - template< typename AllocatorT > - tasklet_object( BOOST_RV_REF( Fn) fn, std::size_t stacksize, AllocatorT const& alloc) : - tasklet_base( stacksize, alloc), - fn_( fn) - {} - - void exec() - { fn_(); } -}; - -template< typename Fn > -class tasklet_object< reference_wrapper< Fn > > : public tasklet_base -{ -private: - Fn & fn_; - - tasklet_object( tasklet_object &); - tasklet_object & operator=( tasklet_object const&); - -public: - template< typename AllocatorT > - tasklet_object( reference_wrapper< Fn > fn, std::size_t stacksize, AllocatorT const& alloc) : - tasklet_base( stacksize, alloc), - fn_( fn) - {} - - void exec() - { fn_(); } -}; - -template< typename Fn > -class tasklet_object< const reference_wrapper< Fn > > : public tasklet_base -{ -private: - Fn & fn_; - - tasklet_object( tasklet_object &); - tasklet_object & operator=( tasklet_object const&); - -public: - template< typename AllocatorT > - tasklet_object( const reference_wrapper< Fn > fn, std::size_t stacksize, AllocatorT const& alloc) : - tasklet_base( stacksize, alloc), - fn_( fn) - {} - - void exec() - { fn_(); } -}; - -}}} - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_SUFFIX -#endif - -#endif // BOOST_TASKLETS_DETAIL_TASKLET_OBJECT_H diff --git a/boost/tasklet/exceptions.hpp b/boost/tasklet/exceptions.hpp deleted file mode 100644 index c9958e57..00000000 --- a/boost/tasklet/exceptions.hpp +++ /dev/null @@ -1,127 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_TASKLETS_EXCEPTIONS_H -#define BOOST_TASKLETS_EXCEPTIONS_H - -#include -#include - -#include - -#include - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_PREFIX -#endif - -namespace boost { -namespace tasklets { - -class tasklet_error : public std::runtime_error -{ -public: - tasklet_error( std::string const& msg) : - std::runtime_error( msg) - {} -}; - -class tasklet_interrupted -{}; - -class tasklet_moved : public std::logic_error -{ -public: - tasklet_moved() : - std::logic_error("tasklet moved") - {} -}; - -class invalid_watermark : public std::runtime_error -{ -public: - invalid_watermark() : - std::runtime_error("invalid watermark") - {} -}; - -class lock_error : public std::logic_error -{ -public: - lock_error() : - std::logic_error("lock invalid") - {} -}; - -class scheduler_error : public std::runtime_error -{ -public: - scheduler_error( std::string const& msg) : - std::runtime_error( msg) - {} -}; - -class future_uninitialized : - public std::logic_error -{ -public: - future_uninitialized() : - std::logic_error("Future Uninitialized") - {} -}; - -class broken_promise : - public std::logic_error -{ -public: - broken_promise() : - std::logic_error("Broken promise") - {} -}; - -class future_already_retrieved : - public std::logic_error -{ -public: - future_already_retrieved() : - std::logic_error("Future already retrieved") - {} -}; - -class promise_already_satisfied : - public std::logic_error -{ -public: - promise_already_satisfied() : - std::logic_error("Promise already satisfied") - {} -}; - -class task_already_started : - public std::logic_error -{ -public: - task_already_started() : - std::logic_error("Task already started") - {} -}; - -class task_moved : - public std::logic_error -{ -public: - task_moved() : - std::logic_error("Task moved") - {} -}; - -}} - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_SUFFIX -#endif - -#endif // BOOST_TASKLETS_EXCEPTIONS_H diff --git a/boost/tasklet/future.hpp b/boost/tasklet/future.hpp deleted file mode 100644 index 7d4ed52e..00000000 --- a/boost/tasklet/future.hpp +++ /dev/null @@ -1,1080 +0,0 @@ -// (C) Copyright 2008-9 Anthony Williams -// -// Distributed under the Boost Software License, Version 1.0. (See -// accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_TASKLETS_FUTURE_HPP -#define BOOST_TASKLETS_FUTURE_HPP - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_PREFIX -#endif - -namespace boost { -namespace tasklets { - -namespace future_state { - - enum state { uninitialized, waiting, ready, moved }; - -} - -namespace detail { - -struct future_object_base -{ - boost::exception_ptr exception; - bool done; - mutex mtx; - condition waiters; - typedef std::list waiter_list; - waiter_list external_waiters; - boost::function callback; - - future_object_base(): - done(false) - {} - - virtual ~future_object_base() - {} - - waiter_list::iterator register_external_waiter(condition& cv) - { - boost::unique_lock lock(mtx); - do_callback(lock); - return external_waiters.insert(external_waiters.end(),&cv); - } - - void remove_external_waiter(waiter_list::iterator it) - { - boost::lock_guard lock(mtx); - external_waiters.erase(it); - } - - void mark_finished_internal() - { - done=true; - waiters.notify_all(); - for(waiter_list::const_iterator it=external_waiters.begin(), - end=external_waiters.end();it!=end;++it) - { - (*it)->notify_all(); - } - } - - struct relocker - { - boost::unique_lock& lock; - - relocker(boost::unique_lock& lock_): - lock(lock_) - { - lock.unlock(); - } - ~relocker() - { - lock.lock(); - } - }; - - void do_callback(boost::unique_lock& lock) - { - if(callback && !done) - { - boost::function local_callback=callback; - relocker relock(lock); - local_callback(); - } - } - - void wait(bool rethrow=true) - { - boost::unique_lock lock(mtx); - do_callback(lock); - while(!done) - { - waiters.wait(lock); - } - if(rethrow && exception) - { - boost::rethrow_exception(exception); - } - } - - void mark_exceptional_finish_internal(boost::exception_ptr const& e) - { - exception=e; - mark_finished_internal(); - } - void mark_exceptional_finish() - { - boost::lock_guard lock(mtx); - mark_exceptional_finish_internal(boost::current_exception()); - } - - bool has_value() - { - boost::lock_guard lock(mtx); - return done && !exception; - } - bool has_exception() - { - boost::lock_guard lock(mtx); - return done && exception; - } - - template - void set_wait_callback(F f,U* u) - { - callback=boost::bind(f,boost::ref(*u)); - } - -private: - future_object_base(future_object_base const&); - future_object_base& operator=(future_object_base const&); -}; - -template -struct future_object: future_object_base -{ - typedef typename tasklets::detail::future_traits::storage_type storage_type; - typedef typename tasklets::detail::future_traits::source_reference_type source_reference_type; - typedef typename tasklets::detail::future_traits::rvalue_source_type rvalue_source_type; - typedef typename tasklets::detail::future_traits::move_dest_type move_dest_type; - - storage_type result; - - future_object(): - result(0) - {} - - void mark_finished_with_result_internal(source_reference_type result_) - { - tasklets::detail::future_traits::init(result,result_); - mark_finished_internal(); - } - void mark_finished_with_result_internal(rvalue_source_type result_) - { - tasklets::detail::future_traits::init(result,static_cast(result_)); - mark_finished_internal(); - } - - void mark_finished_with_result(source_reference_type result_) - { - boost::lock_guard lock(mtx); - mark_finished_with_result_internal(result_); - } - void mark_finished_with_result(rvalue_source_type result_) - { - boost::lock_guard lock(mtx); - mark_finished_with_result_internal(result_); - } - - move_dest_type get() - { - wait(); - return *result; - } - - future_state::state get_state() - { - boost::lock_guard guard(mtx); - if(!done) - { - return future_state::waiting; - } - else - { - return future_state::ready; - } - } - -private: - future_object(future_object const&); - future_object& operator=(future_object const&); -}; - -template<> -struct future_object: future_object_base -{ - future_object() - {} - - void mark_finished_with_result_internal() - { - mark_finished_internal(); - } - - void mark_finished_with_result() - { - boost::lock_guard lock(mtx); - mark_finished_with_result_internal(); - } - - void get() - { - wait(); - } - - future_state::state get_state() - { - boost::lock_guard guard(mtx); - if(!done) - { - return future_state::waiting; - } - else - { - return future_state::ready; - } - } - -private: - future_object(future_object const&); - future_object& operator=(future_object const&); -}; - -class future_waiter -{ - struct registered_waiter - { - boost::shared_ptr future; - detail::future_object_base::waiter_list::iterator wait_iterator; - unsigned index; - - registered_waiter(boost::shared_ptr const& future_, - detail::future_object_base::waiter_list::iterator wait_iterator_, - unsigned index_): - future(future_),wait_iterator(wait_iterator_),index(index_) - {} - - }; - - struct all_futures_lock - { - unsigned count; - boost::scoped_array > locks; - - all_futures_lock(std::vector& futures): - count(futures.size()),locks(new boost::unique_lock[count]) - { - for(unsigned i=0;i(futures[i].future->mtx); - } - } - - void lock() - { - boost::lock(locks.get(),locks.get()+count); - } - - void unlock() - { - for(unsigned i=0;i futures; - unsigned future_count; - -public: - future_waiter(): - future_count(0) - {} - - template - void add(F& f) - { - if(f.future) - { - futures.push_back(registered_waiter(f.future,f.future->register_external_waiter(cv),future_count)); - } - ++future_count; - } - - unsigned wait() - { - all_futures_lock lk(futures); - for(;;) - { - for(unsigned i=0;idone) - { - return futures[i].index; - } - } - cv.wait(lk); - } - } - - ~future_waiter() - { - for(unsigned i=0;iremove_external_waiter(futures[i].wait_iterator); - } - } - -}; - -} - -template -class unique_future; - -template -class shared_future; - -template -struct is_future_type -{ - BOOST_STATIC_CONSTANT(bool, value=false); -}; - -template -struct is_future_type > -{ - BOOST_STATIC_CONSTANT(bool, value=true); -}; - -template -struct is_future_type > -{ - BOOST_STATIC_CONSTANT(bool, value=true); -}; - -template -typename boost::disable_if,void>::type wait_for_all(Iterator begin,Iterator end) -{ - for(Iterator current=begin;current!=end;++current) - { - current->wait(); - } -} - -template -typename boost::enable_if,void>::type wait_for_all(F1& f1,F2& f2) -{ - f1.wait(); - f2.wait(); -} - -template -void wait_for_all(F1& f1,F2& f2,F3& f3) -{ - f1.wait(); - f2.wait(); - f3.wait(); -} - -template -void wait_for_all(F1& f1,F2& f2,F3& f3,F4& f4) -{ - f1.wait(); - f2.wait(); - f3.wait(); - f4.wait(); -} - -template -void wait_for_all(F1& f1,F2& f2,F3& f3,F4& f4,F5& f5) -{ - f1.wait(); - f2.wait(); - f3.wait(); - f4.wait(); - f5.wait(); -} - -template -typename boost::disable_if,Iterator>::type wait_for_any(Iterator begin,Iterator end) -{ - detail::future_waiter waiter; - for(Iterator current=begin;current!=end;++current) - { - waiter.add(*current); - } - return boost::next(begin,waiter.wait()); -} - -template -typename boost::enable_if,unsigned>::type wait_for_any(F1& f1,F2& f2) -{ - detail::future_waiter waiter; - waiter.add(f1); - waiter.add(f2); - return waiter.wait(); -} - -template -unsigned wait_for_any(F1& f1,F2& f2,F3& f3) -{ - detail::future_waiter waiter; - waiter.add(f1); - waiter.add(f2); - waiter.add(f3); - return waiter.wait(); -} - -template -unsigned wait_for_any(F1& f1,F2& f2,F3& f3,F4& f4) -{ - detail::future_waiter waiter; - waiter.add(f1); - waiter.add(f2); - waiter.add(f3); - waiter.add(f4); - return waiter.wait(); -} - -template -unsigned wait_for_any(F1& f1,F2& f2,F3& f3,F4& f4,F5& f5) -{ - detail::future_waiter waiter; - waiter.add(f1); - waiter.add(f2); - waiter.add(f3); - waiter.add(f4); - waiter.add(f5); - return waiter.wait(); -} - -template -class promise; - -template -class packaged_task; - -template -class unique_future -{ - typedef boost::shared_ptr > future_ptr; - - BOOST_MOVABLE_BUT_NOT_COPYABLE( unique_future); - - future_ptr future; - - friend class shared_future; - friend class promise; - friend class packaged_task; - friend class detail::future_waiter; - - typedef typename tasklets::detail::future_traits::move_dest_type move_dest_type; - - unique_future(future_ptr future_): - future(future_) - {} - -public: - typedef future_state::state state; - - unique_future() - {} - - ~unique_future() - {} - - unique_future( BOOST_RV_REF( unique_future) other): - future(other.future) - { other.future.reset(); } - - unique_future& operator=( BOOST_RV_REF( unique_future) other) - { - future=other.future; - other.future.reset(); - return *this; - } - - void swap(unique_future& other) - { future.swap(other.future); } - - // retrieving the value - move_dest_type get() - { - if(!future) - { - throw future_uninitialized(); - } - - return future->get(); - } - - // functions to check state, and wait for ready - state get_state() const - { - if(!future) - { - return future_state::uninitialized; - } - return future->get_state(); - } - - - bool is_ready() const - { - return get_state()==future_state::ready; - } - - bool has_exception() const - { - return future && future->has_exception(); - } - - bool has_value() const - { - return future && future->has_value(); - } - - void wait() const - { - if(!future) - { - throw future_uninitialized(); - } - future->wait(false); - } -}; - -template -class shared_future -{ - typedef boost::shared_ptr > future_ptr; - - BOOST_COPYABLE_AND_MOVABLE( shared_future); - - future_ptr future; - - friend class detail::future_waiter; - friend class promise; - friend class packaged_task; - - shared_future(future_ptr future_): - future(future_) - {} - -public: - shared_future(shared_future const& other): - future(other.future) - {} - - typedef future_state::state state; - - shared_future() - {} - - ~shared_future() - {} - - shared_future& operator=( BOOST_COPY_ASSIGN_REF( shared_future) other) - { - future=other.future; - return *this; - } - - shared_future( BOOST_RV_REF( shared_future) other): - future(other.future) - { - other.future.reset(); - } - - shared_future( BOOST_RV_REF( unique_future) other): - future(other.future) - { - other.future.reset(); - } - - shared_future& operator=(BOOST_RV_REF( shared_future) other) - { - future.swap(other.future); - other.future.reset(); - return *this; - } - shared_future& operator=( BOOST_RV_REF( unique_future) other) - { - future.swap(other.future); - other.future.reset(); - return *this; - } - - void swap(shared_future& other) - { - future.swap(other.future); - } - - // retrieving the value - R get() - { - if(!future) - { - throw future_uninitialized(); - } - - return future->get(); - } - - // functions to check state, and wait for ready - state get_state() const - { - if(!future) - { - return future_state::uninitialized; - } - return future->get_state(); - } - - bool is_ready() const - { - return get_state()==future_state::ready; - } - - bool has_exception() const - { - return future && future->has_exception(); - } - - bool has_value() const - { - return future && future->has_value(); - } - - void wait() const - { - if(!future) - { - throw future_uninitialized(); - } - future->wait(false); - } -}; - -template -class promise -{ - typedef boost::shared_ptr > future_ptr; - - BOOST_MOVABLE_BUT_NOT_COPYABLE( promise); - - future_ptr future; - bool future_obtained; - - void lazy_init() - { - if(!future) - { - future_obtained=false; - future.reset(new detail::future_object); - } - } - -public: -// template explicit promise(Allocator a); - - promise(): - future(),future_obtained(false) - {} - - ~promise() - { - if(future) - { - boost::lock_guard lock(future->mtx); - - if(!future->done) - { - future->mark_exceptional_finish_internal(boost::copy_exception(broken_promise())); - } - } - } - - promise( BOOST_RV_REF( promise) rhs): - future(rhs.future),future_obtained(rhs.future_obtained) - { - rhs.future.reset(); - } - promise & operator=( BOOST_RV_REF( promise) rhs) - { - future=rhs.future; - future_obtained=rhs.future_obtained; - rhs.future.reset(); - return *this; - } - - void swap(promise& other) - { - future.swap(other.future); - std::swap(future_obtained,other.future_obtained); - } - - // Result retrieval - unique_future get_future() - { - lazy_init(); - if(future_obtained) - { - throw future_already_retrieved(); - } - future_obtained=true; - return unique_future(future); - } - - void set_value(typename tasklets::detail::future_traits::source_reference_type r) - { - lazy_init(); - boost::lock_guard lock(future->mtx); - if(future->done) - { - throw promise_already_satisfied(); - } - future->mark_finished_with_result_internal(r); - } - -// void set_value(R && r); - void set_value(typename tasklets::detail::future_traits::rvalue_source_type r) - { - lazy_init(); - boost::lock_guard lock(future->mtx); - if(future->done) - { - throw promise_already_satisfied(); - } - future->mark_finished_with_result_internal(static_cast::rvalue_source_type>(r)); - } - - void set_exception(boost::exception_ptr p) - { - lazy_init(); - boost::lock_guard lock(future->mtx); - if(future->done) - { - throw promise_already_satisfied(); - } - future->mark_exceptional_finish_internal(p); - } - - template - void set_wait_callback(F f) - { - lazy_init(); - future->set_wait_callback(f,this); - } - -}; - -template <> -class promise -{ - typedef boost::shared_ptr > future_ptr; - - BOOST_MOVABLE_BUT_NOT_COPYABLE( promise); - - future_ptr future; - bool future_obtained; - - void lazy_init() - { - if(!future) - { - future_obtained=false; - future.reset(new detail::future_object); - } - } -public: - promise(): - future(),future_obtained(false) - {} - - ~promise() - { - if(future) - { - boost::lock_guard lock(future->mtx); - - if(!future->done) - { - future->mark_exceptional_finish_internal(boost::copy_exception(broken_promise())); - } - } - } - - promise( BOOST_RV_REF( promise) rhs): - future(rhs.future),future_obtained(rhs.future_obtained) - { - rhs.future.reset(); - } - promise & operator=( BOOST_RV_REF( promise) rhs) - { - future=rhs.future; - future_obtained=rhs.future_obtained; - rhs.future.reset(); - return *this; - } - - void swap(promise& other) - { - future.swap(other.future); - std::swap(future_obtained,other.future_obtained); - } - - // Result retrieval - unique_future get_future() - { - lazy_init(); - - if(future_obtained) - { - throw future_already_retrieved(); - } - future_obtained=true; - return unique_future(future); - } - - void set_value() - { - lazy_init(); - boost::lock_guard lock(future->mtx); - if(future->done) - { - throw promise_already_satisfied(); - } - future->mark_finished_with_result_internal(); - } - - void set_exception(boost::exception_ptr p) - { - lazy_init(); - boost::lock_guard lock(future->mtx); - if(future->done) - { - throw promise_already_satisfied(); - } - future->mark_exceptional_finish_internal(p); - } - - template - void set_wait_callback(F f) - { - lazy_init(); - future->set_wait_callback(f,this); - } -}; - -namespace detail { - -template -struct task_base: - detail::future_object -{ - bool started; - - task_base(): - started(false) - {} - - void run() - { - { - boost::lock_guard lk(this->mtx); - if(started) - { - throw task_already_started(); - } - started=true; - } - do_run(); - } - - void owner_destroyed() - { - boost::lock_guard lk(this->mtx); - if(!started) - { - started=true; - this->mark_exceptional_finish_internal(boost::copy_exception(broken_promise())); - } - } - - virtual void do_run()=0; -}; - -template -struct task_object: - task_base -{ - F f; - task_object(F const& f_): - f(f_) - {} - task_object( BOOST_RV_REF( F) f_): - f(f_) - {} - - void do_run() - { - try - { - this->mark_finished_with_result(f()); - } - catch(...) - { - this->mark_exceptional_finish(); - } - } -}; - -template -struct task_object: - task_base -{ - F f; - task_object(F const& f_): - f(f_) - {} - task_object( BOOST_RV_REF( F) f_): - f(f_) - {} - - void do_run() - { - try - { - f(); - this->mark_finished_with_result(); - } - catch(...) - { - this->mark_exceptional_finish(); - } - } -}; - -} - - -template -class packaged_task -{ - BOOST_MOVABLE_BUT_NOT_COPYABLE( packaged_task); - - boost::shared_ptr > task; - bool future_obtained; - -public: - packaged_task(): - future_obtained(false) - {} - - // construction and destruction - template - explicit packaged_task(F const& f): - task(new detail::task_object(f)),future_obtained(false) - {} - explicit packaged_task(R(*f)()): - task(new detail::task_object(f)),future_obtained(false) - {} - - template - explicit packaged_task( BOOST_RV_REF( F) f): - task(new detail::task_object(f)),future_obtained(false) - {} - -// template -// explicit packaged_task(F const& f, Allocator a); -// template -// explicit packaged_task(F&& f, Allocator a); - - ~packaged_task() - { - if(task) - { - task->owner_destroyed(); - } - } - - packaged_task( BOOST_RV_REF( packaged_task) other): - future_obtained(other.future_obtained) - { - task.swap(other.task); - other.future_obtained=false; - } - packaged_task& operator=( BOOST_RV_REF( packaged_task) other) - { - packaged_task temp(other); - swap(temp); - return *this; - } - - void swap(packaged_task& other) - { - task.swap(other.task); - std::swap(future_obtained,other.future_obtained); - } - - // result retrieval - unique_future get_future() - { - if(!task) - { - throw task_moved(); - } - else if(!future_obtained) - { - future_obtained=true; - return unique_future(task); - } - else - { - throw future_already_retrieved(); - } - } - - // execution - void operator()() - { - if(!task) - { - throw task_moved(); - } - task->run(); - } - - template - void set_wait_callback(F f) - { - task->set_wait_callback(f,this); - } -}; - -}} - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_SUFFIX -#endif - -#endif // BOOST_TASKLETS_FUTURE_H diff --git a/boost/tasklet/interruption.hpp b/boost/tasklet/interruption.hpp deleted file mode 100644 index 12c1d290..00000000 --- a/boost/tasklet/interruption.hpp +++ /dev/null @@ -1,86 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_THIS_TASKLET_INTERRUPTION_H -#define BOOST_THIS_TASKLET_INTERRUPTION_H - -#include - -#include -#include - -#include -#include -#include - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_PREFIX -#endif - -namespace boost { -namespace this_tasklet { - -class restore_interruption; - -class disable_interruption : private noncopyable -{ -private: - friend class restore_interruption; - - bool set_; - -public: - disable_interruption() : - set_( ( tasklets::strategy::interrupt_flags_() & tasklets::detail::INTERRUPTION_BLOCKED) != 0) - { - if ( ! set_) - tasklets::strategy::interrupt_flags_() |= tasklets::detail::INTERRUPTION_BLOCKED; - } - - ~disable_interruption() - { - try - { - if ( ! set_) - tasklets::strategy::interrupt_flags_() &= ~tasklets::detail::INTERRUPTION_BLOCKED; - } - catch (...) - {} - } -}; - -class restore_interruption : private noncopyable -{ -private: - disable_interruption & disabler_; - -public: - explicit restore_interruption( disable_interruption & disabler) : - disabler_( disabler) - { - if ( ! disabler_.set_) - tasklets::strategy::interrupt_flags_() &= ~tasklets::detail::INTERRUPTION_BLOCKED; - } - - ~restore_interruption() - { - try - { - if ( ! disabler_.set_) - tasklets::strategy::interrupt_flags_() |= tasklets::detail::INTERRUPTION_BLOCKED; - } - catch (...) - {} - } -}; - -}} - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_SUFFIX -#endif - -#endif // BOOST_THIS_TASKLET_INTERRUPTION_H diff --git a/boost/tasklet/manual_reset_event.hpp b/boost/tasklet/manual_reset_event.hpp deleted file mode 100644 index 4ce4c761..00000000 --- a/boost/tasklet/manual_reset_event.hpp +++ /dev/null @@ -1,66 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_TASKLETS_MANUAL_RESET_EVENT_H -#define BOOST_TASKLETS_MANUAL_RESET_EVENT_H - -#include - -#include -#include -#include - -#include -#include - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_PREFIX -#endif - -# if defined(BOOST_MSVC) -# pragma warning(push) -# pragma warning(disable:4355 4251 4275) -# endif - -namespace boost { -namespace tasklets { - -class BOOST_TASKLET_DECL manual_reset_event : private noncopyable -{ -private: - enum state - { - SET = 0, - RESET - }; - - atomic< state > state_; - atomic< std::size_t > waiters_; - mutex enter_mtx_; - -public: - explicit manual_reset_event( bool = false); - - void set(); - - void reset(); - - void wait(); - - bool try_wait(); -}; - -}} - -# if defined(BOOST_MSVC) -# pragma warning(pop) -# endif - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_SUFFIX -#endif - -#endif // BOOST_TASKLETS_MANUAL_RESET_EVENT_H diff --git a/boost/tasklet/mutex.hpp b/boost/tasklet/mutex.hpp deleted file mode 100644 index 75a589f3..00000000 --- a/boost/tasklet/mutex.hpp +++ /dev/null @@ -1,101 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) -// -// based on boost::interprocess::sync::interprocess_spin_mutex - -#ifndef BOOST_TASKLETS_MUTEX_H -#define BOOST_TASKLETS_MUTEX_H - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_PREFIX -#endif - -# if defined(BOOST_MSVC) -# pragma warning(push) -# pragma warning(disable:4355 4251 4275) -# endif - -namespace boost { -namespace tasklets { - -class BOOST_TASKLET_DECL mutex : private noncopyable -{ -private: - enum state - { - LOCKED = 0, - UNLOCKED - }; - - struct ordered_idx_tag {}; - struct sequenced_idx_tag {}; - - typedef boost::multi_index::multi_index_container< - tasklet, - boost::multi_index::indexed_by< - boost::multi_index::ordered_unique< - boost::multi_index::tag< ordered_idx_tag >, - boost::multi_index::const_mem_fun< - tasklet, tasklet::id, & tasklet::get_id - > - >, - boost::multi_index::sequenced< - boost::multi_index::tag< sequenced_idx_tag > - > - > - > container; - - typedef container::index< ordered_idx_tag >::type ordered_idx; - typedef container::index< sequenced_idx_tag >::type sequenced_idx; - - object::id oid_; - state state_; - spin_mutex mtx_; - container waiting_tasklets_; - ordered_idx & oidx_; - sequenced_idx & sidx_; - -public: - typedef unique_lock< mutex > scoped_lock; - - mutex(); - - ~mutex(); - - void lock(); - - bool try_lock(); - - void unlock(); -}; - -typedef mutex try_mutex; - -}} - -# if defined(BOOST_MSVC) -# pragma warning(pop) -# endif - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_SUFFIX -#endif - -#endif // BOOST_TASKLETS_MUTEX_H diff --git a/boost/tasklet/object/id.hpp b/boost/tasklet/object/id.hpp deleted file mode 100644 index 68679581..00000000 --- a/boost/tasklet/object/id.hpp +++ /dev/null @@ -1,68 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_TASKLETS_DETAIL_ID_H -#define BOOST_TASKLETS_DETAIL_ID_H - -#include - -#include - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_PREFIX -#endif - -namespace boost { -namespace tasklets { -namespace object { - -class id -{ -private: - void const* vp_; - -public: - template< typename T > - id( T const& t) : - vp_( static_cast< void const* >( & t) ) - {} - - bool operator==( id const& other) const - { return vp_ == other.vp_; } - - bool operator!=( id const& other) const - { return vp_ != other.vp_; } - - bool operator<( id const& other) const - { return vp_ < other.vp_; } - - bool operator>( id const& other) const - { return other.vp_ < vp_; } - - bool operator<=( id const& other) const - { return !( other.vp_ < vp_); } - - bool operator>=( id const& other) const - { return ! ( vp_ < other.vp_); } - - template< typename charT, class traitsT > - friend std::basic_ostream< charT, traitsT > & - operator<<( std::basic_ostream< charT, traitsT > & os, id const& other) - { - if ( other.vp_) - return os << other.vp_; - else - return os << "{not-a-object}"; - } -}; - -}}} - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_SUFFIX -#endif - -#endif // BOOST_TASKLETS_DETAIL_ID_H diff --git a/boost/tasklet/round_robin.hpp b/boost/tasklet/round_robin.hpp deleted file mode 100644 index a0a8ff3d..00000000 --- a/boost/tasklet/round_robin.hpp +++ /dev/null @@ -1,138 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_TASKLETS_ROUND_ROBIN_H -#define BOOST_TASKLETS_ROUND_ROBIN_H - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_PREFIX -#endif - -# if defined(BOOST_MSVC) -# pragma warning(push) -# pragma warning(disable:4251 4275) -# endif - -namespace boost { -namespace tasklets { - -class BOOST_TASKLET_DECL round_robin : private noncopyable, - public strategy -{ -private: - struct schedulable - { - tasklet f; - std::list< tasklet::id > joining_tasklets; - optional< tasklet::id > waiting_on_tasklet; - optional< object::id > waiting_on_object; - - schedulable() : - f(), joining_tasklets(), - waiting_on_tasklet(), waiting_on_object() - {} - - schedulable( tasklet f_) : - f( f_), joining_tasklets(), - waiting_on_tasklet(), waiting_on_object() - {} - - schedulable( schedulable const& other) : - f( other.f), - joining_tasklets( other.joining_tasklets), - waiting_on_tasklet( other.waiting_on_tasklet), - waiting_on_object( other.waiting_on_object) - {} - - schedulable & - operator=( schedulable const& other) - { - if ( this == & other) return * this; - f = other.f; - joining_tasklets = other.joining_tasklets; - waiting_on_tasklet = other.waiting_on_tasklet; - waiting_on_object = other.waiting_on_object; - return * this; - } - }; - - typedef std::list< tasklet::id > tasklet_id_list; - typedef std::map< object::id, tasklet_id_list > object_map; - typedef std::map< tasklet::id, schedulable > tasklet_map; - typedef std::list< tasklet::id > runnable_queue; - typedef std::queue< tasklet::id > terminated_queue; - - mutable spin_mutex mtx_; - tasklet_map tasklets_; - object_map objects_; - runnable_queue runnable_tasklets_; - terminated_queue terminated_tasklets_; - -public: - round_robin(); - - void add( tasklet &); - - void join( tasklet &); - - void interrupt( tasklet &); - - void reschedule( tasklet &); - - void cancel( tasklet &); - - void yield(); - - void wait_for_object( object::id const&, spin_mutex::scoped_lock & lk); - - void object_notify_one( object::id const&); - - void object_notify_all( object::id const&); - - void release( tasklet &); - - void migrate( tasklet &); - - void detach_all(); - - bool run(); - - bool empty() const; - - std::size_t size() const; - - std::size_t ready() const; - - bool has_ready() const; -}; - -}} - -# if defined(BOOST_MSVC) -# pragma warning(pop) -# endif - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_SUFFIX -#endif - -#endif // BOOST_TASKLETS_ROUND_ROBIN_H diff --git a/boost/tasklet/scheduler.hpp b/boost/tasklet/scheduler.hpp deleted file mode 100644 index bd2f82c6..00000000 --- a/boost/tasklet/scheduler.hpp +++ /dev/null @@ -1,96 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_TASKLETS_SCHEDULER_H -#define BOOST_TASKLETS_SCHEDULER_H - -#include -#include - -#include -#include - -#include -#include -#include -#include - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_PREFIX -#endif - -namespace boost { -namespace tasklets { - -class auto_reset_event; -class condition; -class count_down_event; -class manual_reset_event; -class mutex; - -template< typename Strategy = round_robin > -class scheduler : private noncopyable -{ -private: - friend class auto_reset_event; - friend class condition; - friend class count_down_event; - friend class manual_reset_event; - friend class mutex; - - strategy * strategy_; - -public: - scheduler() : - strategy_( new Strategy() ) - {} - - ~scheduler() - { - strategy_->detach_all(); - delete strategy_; - } - - bool run() - { return strategy_->run(); } - - bool empty() const - { return strategy_->empty(); } - - std::size_t size() const - { return strategy_->size(); } - - std::size_t ready() const - { return strategy_->ready(); } - - bool has_ready() const - { return strategy_->has_ready(); } - - void submit_tasklet( tasklet t) - { strategy_->add( t); } - - void migrate_tasklet( tasklet & t) - { - if ( ! t) throw tasklet_moved(); - t.impl_->attached_strategy()->release( t); - strategy_->migrate( t); - } - - void swap( scheduler & other) - { std::swap( strategy_, other.strategy_); } -}; - -template< typename Strategy > -void swap( scheduler< Strategy > & l, scheduler< Strategy > & r) -{ l.swap( r); } - -}} - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_SUFFIX -#endif - -#endif // BOOST_TASKLETS_SCHEDULER_H diff --git a/boost/tasklet/spin_condition.hpp b/boost/tasklet/spin_condition.hpp deleted file mode 100644 index 98dd698c..00000000 --- a/boost/tasklet/spin_condition.hpp +++ /dev/null @@ -1,152 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) -// -// based on boost::interprocess::sync::interprocess_condition - -#ifndef BOOST_TASKLETS_SPIN_CONDITION_H -#define BOOST_TASKLETS_SPIN_CONDITION_H - -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_PREFIX -#endif - -# if defined(BOOST_MSVC) -# pragma warning(push) -# pragma warning(disable:4355 4251 4275) -# endif - -namespace boost { -namespace tasklets { - -class BOOST_TASKLET_DECL spin_condition : private noncopyable -{ -private: - enum command - { - SLEEPING = 0, - NOTIFY_ONE, - NOTIFY_ALL - }; - - atomic< command > cmd_; - atomic< std::size_t > waiters_; - spin_mutex enter_mtx_; - spin_mutex check_mtx_; - - void notify_( command); - -public: - spin_condition(); - - void notify_one(); - - void notify_all(); - - void wait( unique_lock< spin_mutex > & lk) - { - if ( ! lk) - throw lock_error(); - wait( * lk.mutex() ); - } - - template< typename Pred > - void wait( unique_lock< spin_mutex > & lk, Pred pred) - { - if ( ! lk) - throw lock_error(); - - while ( ! pred() ) - wait( * lk.mutex() ); - } - - template< typename LockType > - void wait( LockType & lt) - { - { - spin_mutex::scoped_lock lk( enter_mtx_); - BOOST_ASSERT( lk); - waiters_.fetch_add( 1); - lt.unlock(); - } - - bool unlock_enter_mtx = false; - for (;;) - { - while ( SLEEPING == cmd_.load() ) - { - if ( this_tasklet::runs_as_tasklet() ) - this_tasklet::yield(); - else - this_thread::yield(); - } - - spin_mutex::scoped_lock lk( check_mtx_); - BOOST_ASSERT( lk); - - command expected = NOTIFY_ONE; - cmd_.compare_exchange_strong( expected, SLEEPING); - if ( SLEEPING == expected) - continue; - else if ( NOTIFY_ONE == expected) - { - unlock_enter_mtx = true; - waiters_.fetch_sub( 1); - break; - } - else - { - unlock_enter_mtx = 1 == waiters_.fetch_sub( 1); - if ( unlock_enter_mtx) - { - expected = NOTIFY_ALL; - cmd_.compare_exchange_strong( expected, SLEEPING); - } - break; - } - } - - if ( unlock_enter_mtx) - enter_mtx_.unlock(); - - lt.lock(); - } - - template< - typename LockType, - typename Pred - > - void wait( LockType & lt, Pred pred) - { - while ( ! pred() ) - wait( lt); - } -}; - -}} - -# if defined(BOOST_MSVC) -# pragma warning(pop) -# endif - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_SUFFIX -#endif - -#endif // BOOST_TASKLETS_SPIN_CONDITION_H diff --git a/boost/tasklet/spin_mutex.hpp b/boost/tasklet/spin_mutex.hpp deleted file mode 100644 index 1f2166cc..00000000 --- a/boost/tasklet/spin_mutex.hpp +++ /dev/null @@ -1,66 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) -// -// based on boost::interprocess::sync::interprocess_spin_mutex - -#ifndef BOOST_TASKLETS_SPIN_MUTEX_H -#define BOOST_TASKLETS_SPIN_MUTEX_H - -#include -#include -#include -#include - -#include - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_PREFIX -#endif - -# if defined(BOOST_MSVC) -# pragma warning(push) -# pragma warning(disable:4355 4251 4275) -# endif - -namespace boost { -namespace tasklets { - -class BOOST_TASKLET_DECL spin_mutex : private noncopyable -{ -private: - enum state - { - LOCKED = 0, - UNLOCKED - }; - - atomic< state > state_; - -public: - typedef unique_lock< spin_mutex > scoped_lock; - - spin_mutex(); - - void lock(); - - bool try_lock(); - - void unlock(); -}; - -typedef spin_mutex try_spin_mutex; - -}} - -# if defined(BOOST_MSVC) -# pragma warning(pop) -# endif - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_SUFFIX -#endif - -#endif // BOOST_TASKLETS_SPIN_MUTEX_H diff --git a/boost/tasklet/strategy.hpp b/boost/tasklet/strategy.hpp deleted file mode 100644 index 8166d298..00000000 --- a/boost/tasklet/strategy.hpp +++ /dev/null @@ -1,187 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_TASKLETS_STRATEGY_H -#define BOOST_TASKLETS_STRATEGY_H - -#include - -#include -#include - -#include -#include -#include -#include - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_PREFIX -#endif - -# if defined(BOOST_MSVC) -# pragma warning(push) -# pragma warning(disable:4251) -# endif - -namespace boost { - -namespace this_tasklet { - -bool runs_as_tasklet(); -tasklet::id get_id(); -void yield(); -void cancel(); -int priority(); -void priority( int); -void interruption_point(); -bool interruption_requested(); -bool interruption_enabled(); -void submit_tasklet( tasklet); - -class disable_interruption; -class restore_interruption; - -} - -namespace tasklets { - -class auto_reset_event; -class condition; -class count_down_event; -class manual_reset_event; -class mutex; - -class BOOST_TASKLET_DECL strategy -{ -private: - friend bool this_tasklet::runs_as_tasklet(); - friend tasklet::id this_tasklet::get_id(); - friend void this_tasklet::yield(); - friend void this_tasklet::cancel(); - friend int this_tasklet::priority(); - friend void this_tasklet::priority( int); - friend void this_tasklet::interruption_point(); - friend bool this_tasklet::interruption_requested(); - friend bool this_tasklet::interruption_enabled(); - friend void this_tasklet::submit_tasklet( tasklet); - friend class this_tasklet::disable_interruption; - friend class this_tasklet::restore_interruption; - friend class auto_reset_event; - friend class condition; - friend class count_down_event; - friend class manual_reset_event; - friend class mutex; - - static bool runs_as_tasklet_(); - - static tasklet::id get_id_(); - - static void interruption_point_(); - - static bool interruption_requested_(); - - static detail::interrupt_type & interrupt_flags_(); - - static bool interruption_enabled_(); - - static int priority_(); - - static void priority_( int); - - static void yield_(); - - static void cancel_(); - - static void submit_tasklet_( tasklet); - -protected: - static BOOST_TASKLET_TSSDECL tasklet * active_tasklet; - - static void call( tasklet &); - - static void yield( tasklet &); - - static void detach( tasklet &); - - static void enable_interruption( tasklet &); - - static bool interruption_enabled( tasklet const&); - - static bool in_state_not_started( tasklet const&); - - static bool in_state_ready( tasklet const&); - - static bool in_state_running( tasklet const&); - - static bool in_state_wait_for_tasklet( tasklet const&); - - static bool in_state_wait_for_object( tasklet const&); - - static bool in_state_terminated( tasklet const&); - - static void set_state_ready( tasklet &); - - static void set_state_running( tasklet &); - - static void set_state_wait_for_tasklet( tasklet &); - - static void set_state_wait_for_object( tasklet &); - - static void set_state_terminated( tasklet &); - - void attach( tasklet &); - -public: - strategy(); - - virtual ~strategy(); - - virtual void add( tasklet &) = 0; - - virtual void join( tasklet &) = 0; - - virtual void interrupt( tasklet &) = 0; - - virtual void reschedule( tasklet &) = 0; - - virtual void cancel( tasklet &) = 0; - - virtual void yield() = 0; - - virtual void wait_for_object( object::id const&, spin_mutex::scoped_lock & lk) = 0; - - virtual void object_notify_one( object::id const&) = 0; - - virtual void object_notify_all( object::id const&) = 0; - - virtual void release( tasklet &) = 0; - - virtual void migrate( tasklet &) = 0; - - virtual void detach_all() = 0; - - virtual bool run() = 0; - - virtual bool empty() const = 0; - - virtual std::size_t size() const = 0; - - virtual std::size_t ready() const = 0; - - virtual bool has_ready() const = 0; -}; - -}} - -# if defined(BOOST_MSVC) -# pragma warning(pop) -# endif - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_SUFFIX -#endif - -#endif // BOOST_TASKLETS_STRATEGY_H diff --git a/boost/tasklet/tasklet.hpp b/boost/tasklet/tasklet.hpp deleted file mode 100644 index 0976f7a5..00000000 --- a/boost/tasklet/tasklet.hpp +++ /dev/null @@ -1,226 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_TASKLETS_TASKLET_H -#define BOOST_TASKLETS_TASKLET_H - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_PREFIX -#endif - -# if defined(BOOST_MSVC) -# pragma warning(push) -# pragma warning(disable:4251) -# endif - -namespace boost { -namespace tasklets { - -class condition; -class mutex; -class strategy; -template< typename Strategy > -class scheduler; - -class BOOST_TASKLET_DECL tasklet -{ -private: - friend class condition; - friend class mutex; - friend class strategy; - template< typename Strategy > - friend class scheduler; - - BOOST_COPYABLE_AND_MOVABLE( tasklet); - - detail::tasklet_base::ptr impl_; - - template< typename Fn, typename AllocatorT > - static detail::tasklet_base::ptr make_impl_( - Fn fn, std::size_t stacksize, AllocatorT const& alloc) - { - return detail::tasklet_base::ptr( - new detail::tasklet_object< Fn >( fn, stacksize, alloc) ); - } - - template< typename Fn, typename AllocatorT > - static detail::tasklet_base::ptr make_impl_( - BOOST_RV_REF( Fn) fn, std::size_t stacksize, AllocatorT const& alloc) - { - return detail::tasklet_base::ptr( - new detail::tasklet_object< Fn >( fn, stacksize, alloc) ); - } - -public: - static std::size_t default_stacksize; - - class id; - - tasklet(); - - template< typename Fn, typename AllocatorT > - explicit tasklet( Fn fn, std::size_t stacksize, AllocatorT const& alloc) : - impl_( make_impl_( fn, stacksize, alloc) ) - {} - -#define BOOST_TASKLET_ARG(z, n, unused) \ - BOOST_PP_CAT(A, n) BOOST_PP_CAT(a, n) -#define BOOST_ENUM_TASKLET_ARGS(n) BOOST_PP_ENUM(n, BOOST_TASKLET_ARG, ~) - -#define BOOST_TASKLET_TASKLET_CTOR(z, n, unused) \ - template< typename Fn, BOOST_PP_ENUM_PARAMS(n, typename A), typename AllocatorT > \ - tasklet( Fn fn, BOOST_ENUM_TASKLET_ARGS(n), std::size_t stacksize, AllocatorT const& alloc) : \ - impl_( \ - make_impl_( \ - boost::bind( boost::type< void >(), fn, BOOST_PP_ENUM_PARAMS(n, a) ), \ - stacksize, alloc) ) \ - {} \ - -#ifndef BOOST_TASKLET_MAX_ARITY -#define BOOST_TASKLET_MAX_ARITY 10 -#endif - -BOOST_PP_REPEAT_FROM_TO( 1, BOOST_TASKLET_MAX_ARITY, BOOST_TASKLET_TASKLET_CTOR, ~) - -#undef BOOST_TASKLET_TASKLET_CTOR - - template< typename Fn, typename AllocatorT > - explicit tasklet( BOOST_RV_REF( Fn) fn, std::size_t stacksize, AllocatorT const& alloc) : - impl_( make_impl_( fn, stacksize, alloc) ) - {} - - tasklet( tasklet const& other); - - tasklet & operator=( BOOST_COPY_ASSIGN_REF( tasklet) other); - - tasklet( BOOST_RV_REF( tasklet) other); - - tasklet & operator=( BOOST_RV_REF( tasklet) other); - - typedef detail::tasklet_base::ptr::unspecified_bool_type unspecified_bool_type; - - operator unspecified_bool_type() const; - - bool operator!() const; - - void swap( tasklet & other); - - id get_id() const; - - bool operator==( tasklet const& other) const; - bool operator!=( tasklet const& other) const; - - bool is_alive() const; - - int priority() const; - - void priority( int); - - void interrupt(); - - bool interruption_requested() const; - - void cancel(); - - void join(); -}; - -class BOOST_TASKLET_DECL tasklet::id -{ -private: - friend class tasklet; - - uint64_t id_; - - explicit id( detail::tasklet_base::ptr info) : - id_( reinterpret_cast< uint64_t >( info.get() ) ) - {} - -public: - id() : - id_( 0) - {} - - bool operator==( id const& other) const - { return id_ == other.id_; } - - bool operator!=( id const& other) const - { return id_ != other.id_; } - - bool operator<( id const& other) const - { return id_ < other.id_; } - - bool operator>( id const& other) const - { return other.id_ < id_; } - - bool operator<=( id const& other) const - { return !( other.id_ < id_); } - - bool operator>=( id const& other) const - { return ! ( id_ < other.id_); } - - template< typename charT, class traitsT > - friend std::basic_ostream< charT, traitsT > & - operator<<( std::basic_ostream< charT, traitsT > & os, id const& other) - { - if ( 0 != other.id_) - return os << other.id_; - else - return os << "{not-a-tasklet}"; - } -}; - -template< typename Fn > -tasklet make_tasklet( Fn fn, std::size_t stacksize) -{ return tasklet( fn, stacksize); } - -#define BOOST_TASKLET_MAKE_TASKLET_FUNCTION(z, n, unused) \ -template< typename Fn, BOOST_PP_ENUM_PARAMS(n, typename A) > \ -tasklet make_tasklet( Fn fn, BOOST_ENUM_TASKLET_ARGS(n), std::size_t stacksize) \ -{ return tasklet( fn, BOOST_PP_ENUM_PARAMS(n, a), stacksize); } - -BOOST_PP_REPEAT_FROM_TO( 1, BOOST_TASKLET_MAX_ARITY, BOOST_TASKLET_MAKE_TASKLET_FUNCTION, ~) - -#undef BOOST_TASKLET_MAKE_TASKLET_FUNCTION -#undef BOOST_ENUM_TASKLET_ARGS -#undef BOOST_TASKLET_ARG -#undef BOOST_TASKLET_MAX_ARITY - -} - -using tasklets::tasklet; - -inline -void swap( tasklet & l, tasklet & r) -{ return l.swap( r); } - -} - -# if defined(BOOST_MSVC) -# pragma warning(pop) -# endif - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_SUFFIX -#endif - -#endif // BOOST_TASKLETS_TASKLET_H diff --git a/boost/tasklet/unbounded_channel.hpp b/boost/tasklet/unbounded_channel.hpp deleted file mode 100644 index 59789802..00000000 --- a/boost/tasklet/unbounded_channel.hpp +++ /dev/null @@ -1,197 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_TASKLETS_UNBOUNDED_CHANNEL_H -#define BOOST_TASKLETS_UNBOUNDED_CHANNEL_H - -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_PREFIX -#endif - -namespace boost { -namespace tasklets { -namespace detail { - -template< typename T > -struct unbounded_channel_node -{ - typedef intrusive_ptr< unbounded_channel_node > ptr; - - atomic< std::size_t > use_count; - T va; - ptr next; - - unbounded_channel_node() : - use_count( 0), - va(), - next() - {} -}; - -template< typename T > -void intrusive_ptr_add_ref( unbounded_channel_node< T > * p) -{ p->use_count.fetch_add( 1, memory_order_relaxed); } - -template< typename T > -void intrusive_ptr_release( unbounded_channel_node< T > * p) -{ - if ( p->use_count.fetch_sub( 1, memory_order_release) == 1) - { - atomic_thread_fence( memory_order_acquire); - delete p; - } -} - -} - -template< typename T > -class unbounded_channel : private noncopyable -{ -public: - typedef optional< T > value_type; - -private: - typedef detail::unbounded_channel_node< value_type > node_type; - - template< typename X > - friend void intrusive_ptr_add_ref( unbounded_channel< X > * p); - template< typename X > - friend void intrusive_ptr_release( unbounded_channel< X > * p); - - enum state - { - ACTIVE = 0, - DEACTIVE - }; - - atomic< state > state_; - typename node_type::ptr head_; - mutable mutex head_mtx_; - typename node_type::ptr tail_; - mutable mutex tail_mtx_; - condition not_empty_cond_; - atomic< std::size_t > use_count_; - - bool active_() const - { return ACTIVE == state_.load(); } - - void deactivate_() - { state_.store( DEACTIVE); } - - bool empty_() const - { return head_ == get_tail_(); } - - typename node_type::ptr get_tail_() const - { - mutex::scoped_lock lk( tail_mtx_); - typename node_type::ptr tmp = tail_; - return tmp; - } - - typename node_type::ptr pop_head_() - { - typename node_type::ptr old_head = head_; - head_ = old_head->next; - return old_head; - } - -public: - unbounded_channel() : - state_( ACTIVE), - head_( new node_type() ), - head_mtx_(), - tail_( head_), - tail_mtx_(), - not_empty_cond_(), - use_count_( 0) - {} - - bool active() const - { return active_(); } - - void deactivate() - { - mutex::scoped_lock lk( head_mtx_); - deactivate_(); - not_empty_cond_.notify_all(); - } - - bool empty() const - { - mutex::scoped_lock lk( head_mtx_); - return empty_(); - } - - void put( T const& t) - { - typename node_type::ptr new_node( new node_type() ); - { - mutex::scoped_lock lk( tail_mtx_); - - if ( ! active_() ) - throw std::runtime_error("queue is not active"); - - tail_->va = t; - tail_->next = new_node; - tail_ = new_node; - } - not_empty_cond_.notify_one(); - } - - bool take( value_type & va) - { - mutex::scoped_lock lk( head_mtx_); - bool empty = empty_(); - if ( ! active_() && empty) - return false; - if ( empty) - { - try - { - while ( active_() && empty_() ) - not_empty_cond_.wait( lk); - } - catch ( tasklet_interrupted const&) - { return false; } - } - if ( ! active_() && empty_() ) - return false; - swap( va, head_->va); - pop_head_(); - return va; - } - - bool try_take( value_type & va) - { - mutex::scoped_lock lk( head_mtx_); - if ( empty_() ) - return false; - swap( va, head_->va); - pop_head_(); - return va; - } -}; - -}} - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_SUFFIX -#endif - -#endif // BOOST_TASKLETS_UNBOUNDED_CHANNEL_H diff --git a/boost/tasklet/utility.hpp b/boost/tasklet/utility.hpp deleted file mode 100644 index 1565c2cc..00000000 --- a/boost/tasklet/utility.hpp +++ /dev/null @@ -1,71 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_THIS_TASKLET_UTILITY_H -#define BOOST_THIS_TASKLET_UTILITY_H - -#include -#include -#include -#include - -#include -#include - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_PREFIX -#endif - -namespace boost { -namespace this_tasklet { - -inline -bool runs_as_tasklet() -{ return tasklets::strategy::runs_as_tasklet_(); } - -inline -tasklet::id get_id() -{ return tasklets::strategy::get_id_(); } - -inline -int priority() -{ return tasklets::strategy::priority_(); } - -inline -void priority( int prio) -{ tasklets::strategy::priority_( prio); } - -inline -void interruption_point() -{ tasklets::strategy::interruption_point_(); } - -inline -bool interruption_requested() -{ return tasklets::strategy::interruption_requested_(); } - -inline -bool interruption_enabled() -{ return tasklets::strategy::interruption_enabled_(); } - -inline -void yield() -{ tasklets::strategy::yield_(); } - -inline -void cancel() -{ tasklets::strategy::cancel_(); } - -inline -void submit_tasklet( tasklet f) -{ tasklets::strategy::submit_tasklet_( f); } - -}} - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_SUFFIX -#endif - -#endif // BOOST_THIS_TASKLET_UTILITY_H diff --git a/libs/task/build/Jamfile.v2 b/libs/task/build/Jamfile.v2 deleted file mode 100644 index 6f9cf91e..00000000 --- a/libs/task/build/Jamfile.v2 +++ /dev/null @@ -1,89 +0,0 @@ -# Boost.Task Library Build Jamfile - -# Copyright Oliver Kowalke 2009. -# Distributed under the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) - -import os ; -import feature ; -import indirect ; -import path ; - -project boost/task - : source-location - ../src - : requirements - /boost/tasklet//boost_tasklet - /boost/thread//boost_thread - /boost/system//boost_system - static:BOOST_TASKS_BUILD_LIB=1 - shared:BOOST_TASKS_BUILD_DLL=1 - multi - : default-build - multi - ; - -local rule default_taskapi ( ) -{ - local api = posix ; - if [ os.name ] = "NT" { api = win32 ; } - return $(api) ; -} - -feature.feature taskapi : posix win32 : propagated ; -feature.set-default taskapi : [ default_taskapi ] ; - -alias task_sources - : ## win32 sources ## - callable.cpp - context.cpp - fast_semaphore.cpp - poolsize.cpp - semaphore_windows.cpp - spin/auto_reset_event.cpp - spin/barrier.cpp - spin/condition.cpp - spin/count_down_event.cpp - spin/manual_reset_event.cpp - spin/mutex.cpp - stacksize.cpp - watermark.cpp - detail/worker.cpp - detail/worker_group.cpp - detail/wsq.cpp - : ## requirements ## - win32 - ; - -alias task_sources - : ## posix sources ## - callable.cpp - context.cpp - fast_semaphore.cpp - poolsize.cpp - semaphore_posix.cpp - spin/auto_reset_event.cpp - spin/barrier.cpp - spin/condition.cpp - spin/count_down_event.cpp - spin/manual_reset_event.cpp - spin/mutex.cpp - stacksize.cpp - watermark.cpp - detail/worker.cpp - detail/worker_group.cpp - detail/wsq.cpp - : ## requirements ## - posix - ; - -explicit task_sources ; - -lib boost_task - : task_sources - : shared:BOOST_TASKS_USE_DLL=1 - static:BOOST_TASKS_USE_LIB=1 - ; - -boost-install boost_task ; diff --git a/libs/task/doc/Jamfile.v2 b/libs/task/doc/Jamfile.v2 deleted file mode 100644 index 087ef08c..00000000 --- a/libs/task/doc/Jamfile.v2 +++ /dev/null @@ -1,36 +0,0 @@ -# Boost.ThreadPool Library Documentation Jamfile - -# Copyright (C) 2008 Oliver Kowalke - -# Use, modification and distribution is subject to the Boost Software License, -# Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) - -path-constant boost-images : ../../../doc/src/images ; - -xml task : task.qbk ; - -boostbook standalone - : - task - : - # HTML options first: - # Use graphics not text for navigation: - navig.graphics=1 - # How far down we chunk nested sections, basically all of them: - chunk.section.depth=3 - # Don't put the first section on the same page as the TOC: - chunk.first.sections=1 - # How far down sections get TOC's - toc.section.depth=10 - # Max depth in each TOC: - toc.max.depth=3 - # How far down we go with TOC's - generate.section.toc.level=10 - # Path for links to Boost: - boost.root=../../../.. - # Path for libraries index: - boost.libraries=../../../../libs/libraries.htm - # Use the main Boost stylesheet: - html.stylesheet=../../../../doc/html/boostbook.css - ; diff --git a/libs/task/doc/acknowledgements.qbk b/libs/task/doc/acknowledgements.qbk deleted file mode 100644 index 5f2b5a1e..00000000 --- a/libs/task/doc/acknowledgements.qbk +++ /dev/null @@ -1,13 +0,0 @@ -[/ - Copyright Oliver Kowalke 2009. - Distributed under the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt -] - - -[section:acknowledgements Acknowledgments] - -I'd like to thank Vicente J. Botet Escriba for his comments. - -[endsect] diff --git a/libs/task/doc/as_sub_task.qbk b/libs/task/doc/as_sub_task.qbk deleted file mode 100644 index 63617cee..00000000 --- a/libs/task/doc/as_sub_task.qbk +++ /dev/null @@ -1,40 +0,0 @@ -[/ - Copyright Oliver Kowalke 2009. - Distributed under the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt -] - - -[section:as_sub_task Execute as Sub-Task] - -__as_sub_task__ is a convenient way to execute a __sub_task__. If the parent task is executed inside a __thread_pool__ the __sub_task__ is put into the local-queue of the -__worker_thread__ in the other case the __sub_task__ will be executed in a new thread. __as_sub_task__ is used as default __ep__ for __fn_async__, - - boost::task::handle< long > h( - boost::task::async( - boost::task::make_task( fibonacci, 10), - boost::task::as_sub_task() ) ); - - -[section:as_sub_task Class `as_sub_task`] - - #include - - struct as_sub_task - { - template< typename R > - handle< R > operator()( task< R >); - }; - - -[section `template< typename R > handle< R > operator()( task< R > t)`] -[variablelist -[[Effects:] [moves task in a new thread or thread-pool and returns an handle associated with the task]] -[[Throws:] [`boost::thread_resource_error`]] -] -[endsect] - -[endsect] - -[endsect] diff --git a/libs/task/doc/async_completion_token.qbk b/libs/task/doc/async_completion_token.qbk deleted file mode 100644 index 3b5c5cc5..00000000 --- a/libs/task/doc/async_completion_token.qbk +++ /dev/null @@ -1,315 +0,0 @@ -[/ - Copyright Oliver Kowalke 2009. - Distributed under the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt -] - - -[section:async_completion_token Asynchronous Completion Token] - -[heading Synopsis] - -The __act__ dispatches processing tasks in response to the completion of asynchronous operations. __act__ uniquely identifies -the task and state necessary to process the result of the operation [footnote see [@http://www.cs.wustl.edu/~schmidt/PDF/ACT.pdf 'Asynchronous Completion Token'], Douglas Schmidt]. - -__handle__ represents an __act__. It will be returned by __async__ and is associated with the submitted __task__. - - long fibonacci( long n) - { - if ( n == 0) return 0; - if ( n == 1) return 1; - long k1( 1), k2( 0); - for ( int i( 2); i <= n; ++i) - { - long tmp( k1); - k1 = k1 + k2; - k2 = tmp; - } - return k1; - } - - void main() - { - // create task - boost::tasks::task< long > t( fibonacci, 10); - - // move task ownership to executor - boost::tasks::handle< long > h( - boost::tasks::async( - boost::move( t), - boost::tasks::new_thread() ) ); - - std::cout << "is ready == " << std::boolalpha << h.is_ready() << "\n"; - - // wait for task completion - h.wait(); - - std::cout << "has value == " << std::boolalpha << h.has_value() << "\n"; - std::cout << "has exception == " << std::boolalpha << h.has_exception() << "\n"; - - // return result - std::cout << "fibonacci(10) == " << h.get() << std::endl; - } - -[heading Interruption] - -Each invokation of __fn_async__ returns an __handle__ which allows to control the associated __task__ (passed to __fn_async__). This includes -the ability to interrupt an __task__ if it is cooperative. Cooperative means that the __task__ contains __interruption_points__ or checks for -interruption requests [footnote see [@http://www.ddj.com/architect/207100682 'Interrupt Politely'], Herb Sutter]. - -* __fn_interrupt__: interrupt __task__ and return immediately - -* __fn_interrupt_and_wait__: interrupt and wait until __task__ was removed from __worker_thread__ - -* __fn_interrupt_and_wait_for__: interrupt and wait until __task__ was removed from __worker_thread__ or time duration has elapsed - -* __fn_interrupt_and_wait_until__: interrupt and wait until __task__ was removed from __worker_thread__ or time point has reached - -* __fn_interruption_requested__: return bool if interruption was requested - - long cooperative( long n) - { - boost::this_thread::interruption_point(); // interruption point - - if ( n == 0) return 0; - if ( n == 1) return 1; - long k1( 1), k2( 0); - for ( int i( 2); i <= n; ++i) - { - if ( boost::this_thread::interruption_requested() ) // check if interruption was requested - return; - - long tmp( k1); - k1 = k1 + k2; - k2 = tmp; - } - - boost::this_thread::interruption_point(); // interruption point - - return k1; - } - - void main() - { - // task, to be executed asynchronously - boost::tasks::task< long > t( cooperative, 10); - - // move task to async. executor - boost::tasks::handle< long > h( - boost::tasks::async( - boost::move( t), - boost::tasks::new_thread() ) ); - - // interrupt task and wait until task is removed by worker-thread - h.interrupt_and_wait(); - - std::cout << "is ready == " << std::boolalpha << h.is_ready() << "\n"; - std::cout << "has value == " << std::boolalpha << h.has_value() << "\n"; - std::cout << "has exception == " << std::boolalpha << h.has_exception() << "\n"; - - // access result - // throws boost::tasks::task_interrupted - std::cout << h.get() << std::endl; - } - -[note If the task is still pending (not executed yet) when an interruption is requested - the task is not removed from the queue, it is marked to be interrupted instead.] - - -[heading Completion] - -__boost_task__ provides function __waitfor_all__ waits for all handles passed to this function to become ready - - void main() - { - std::vector handles< boost::tasks::handle< long > > results; - results.reserve( 10); - - for ( int i = 0; i < 10; ++i) - { - boost::tasks::task< long > t( fibonacci, i); - - results.push_back( - boost::tasks::async( - boost::move( t) ) ); - } - - // wait until all tasks are ready - boost::tasks::waitfor_all( results.begin(), results.end() ); - - int k = 0; - std::vector< boost::tasks::handle< long > >::iterator e( results.end() ); - for ( - std::vector< boost::tasks::handle< long > >::iterator i( results.begin() ); - i != e; - ++i) - std::cout << "fibonacci(" << k++ << ") == " << i->get() << std::endl; - } - -[section:handle Class template `handle`] - - #include - - template< typename R > - class handle - { - handle(); - - template< typename F > - handle( F const&, context const&); - - void interrupt(); - void interrupt_and_wait(); - void interrupt_and_wait_until( system_time const& abs_time); - template< typename TimeDuration > - void interrupt_and_wait_for( Duration const& rel_time); - bool interruption_requested(); - - R get(); - bool is_ready() const; - bool has_value() const; - bool has_exception() const; - void wait() const; - bool wait_until( system_time const& abs_time); - template< typename TimeDuration > - bool wait_for( TimeDuration const& rel_time); - - void swap( handle< R > & other); - }; - - template< typename Iterator > - friend void waitfor_all( Iterator begin, Iterator end); - - template< typename T1, typename T2 > - friend void waitfor_all( T1 & t1, T2 & t2); - ... - template< typename T1, typename T2, typename T3, typename T4, typename T5 > - friend void waitfor_all( handle< T1 > & t1, handle< T2 > & t2, handle< T3 > & t3, handle< T4 > & t4, handle< T5 > & t5); - -[section `handle()`] -[variablelist -[[Effects:] [constructs an empty (invalid) handle]] -[[Throws:] [Nothing]] -] -[endsect] - -[section `template< typename F > handle( F const&, context const&)`] -[variablelist -[[Effects:] [constructs an handle associated with an future and an context]] -[[Throws:] [Nothing]] -] -[endsect] - -[section `bool interruption_requested()`] -[variablelist -[[Effects:] [checks if interruption is already requested]] -[[Throws:] [Nothing]] -] -[endsect] - -[section `void interrupt()`] -[variablelist -[[Effects:] [requests task interruption; doesn not block (immediatly returns)]] -[[Throws:] [Nothing]] -] -[endsect] - -[section `void interrupt_and_wait()`] -[variablelist -[[Effects:] [requests task interruption and blocks until worker-thread stops task]] -[[Throws:] [`boost::thread_resource_error`]] -] -[endsect] - -[section `bool interrupt_and_wait_until( system_time const&)`] -[variablelist -[[Effects:] [requests task interruption and blocks until worker-thread stops task or time-point elapsed]] -[[Returns:] [false if the the time specified by abs_time was reached, true otherwise]] -[[Throws:] [`boost::thread_resource_error`]] -] -[endsect] - -[section `template< typename TimeDuration > interrupt_and_wait_for( TimeDuration const&)`] -[variablelist -[[Effects:] [requests task interruption and blocks until worker-thread stops task or time-duration elapsed]] -[[Returns:] [false if the the time specified by rel_time was reached, true otherwise]] -[[Throws:] [`boost::thread_resource_error`]] -] -[endsect] - -[section `R get()`] -[variablelist -[[Effects:] [requests the result]] -[[Throws:] [`boost::task::task_interrupted`, `boost::task::task_uninialized`, `boost::task::task_rejected`, `boost::task::broken_task`]] -] -[endsect] - -[section `void wait()`] -[variablelist -[[Effects:] [blocks caller until task is done]] -[[Throws:] [`boost::task::task_interrupted`, `boost::task::task_uninialized`, `boost::task::task_rejected`, `boost::task::broken_task`]] -] -[endsect] - -[section `template< typename TimeDuration > wait_for( TimeDuration const&)`] -[variablelist -[[Effects:] [blocks caller until task is done]] -[[Throws:] [`boost::task::task_interrupted`, `boost::task::task_uninialized`, `boost::task::task_rejected`, `boost::task::broken_task`]] -] -[endsect] - -[section `bool wait_until( system_time const& abs_time) const`] -[variablelist -[[Effects:] [blocks caller until task is done]] -[[Throws:] [`boost::task::task_interrupted`, `boost::task::task_uninialized`, `boost::task::task_rejected`, `boost::task::broken_task`]] -] -[endsect] - -[section `bool is_ready()`] -[variablelist -[[Effects:] [checks if task is done]] -[[Throws:] [Nothing]] -] -[endsect] - -[section `bool has_value()`] -[variablelist -[[Effects:] [checks if task is done and a result value is set]] -[[Throws:] [Nothing]] -] -[endsect] - -[section `bool has_exception()`] -[variablelist -[[Effects:] [checks if task is done and an exception is set]] -[[Throws:] [Nothing]] -] -[endsect] - -[section `void swap( handle< R > & other)`] -[variablelist -[[Effects:] [swapps handle]] -[[Throws:] [Nothing]] -] -[endsect] - -[section Non-member function `wait_for_all()`] - - template< typename Iterator > - void waitfor_all( Iterator begin, Iterator end); - - template< typename T1, typename T2 > - void waitfor_all( T1 & t1, T2 & t2); - ... - template< typename T1, typename T2, typename T3, typename T4, typename T5 > - void waitfor_all( handle< T1 > & t1, handle< T2 > & t2, handle< T3 > & t3, handle< T4 > & t4, handle< T5 > & t5); - -[variablelist -[[Effects:] [waits for all handles to become ready]] -[[Throws:] [`boost::task::task_interrupted`, `boost::task::task_rejected`]] -] -[endsect] - -[endsect] - -[endsect] diff --git a/libs/task/doc/async_execution.qbk b/libs/task/doc/async_execution.qbk deleted file mode 100644 index a812d14c..00000000 --- a/libs/task/doc/async_execution.qbk +++ /dev/null @@ -1,90 +0,0 @@ -[/ Copyright Oliver Kowalke 2009. - Distributed under the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt -] - - -[section:async_execution Asynchronous Execution] - -[heading Synopsis] - -In order to execute a task it has to be passed to function __fn_async__. The task is store inside -the __ep__ (may be given as an additional argument to __fn_async__) and will by means of __ep__. - - -[section:async Non-member function `async()`] - -Function __fn_async__ applies the moved __task__ to the __ep__ which executes the __task__ (for this purpose __ep__ is -required to provide `handle< R > operator()( task< R > && t)`). -The function returns a __handle__ which controls the submitted __task__. - - long fibonacci( long n) - { - if ( n == 0) return 0; - if ( n == 1) return 1; - long k1( 1), k2( 0); - for ( int i( 2); i <= n; ++i) - { - long tmp( k1); - k1 = k1 + k2; - k2 = tmp; - } - return k1; - } - - void main() - { - // task computing fibonacci(10) - // move the task to executor - boost::tasks::handle< long > h1( - boost::tasks::async( - boost::tasks::make_task( fibonacci, 10) ) ); - - // task computing fibonacci(5) - boost::task< long > t( fibonacci, 5); - // move the task to executor - boost::tasks::handle< long > h2( - boost::tasks::async( - boost::move( t) ) ); - - // access the results - std::cout << "fibonacci(10) == " << h1.get() << std::endl; - std::cout << "fibonacci(5) == " << h2.get() << std::endl; - } - - -[section:async Non-member function `async()`] - - #include - - template< typename R > - handle< R > async( task< R > t); - - template< typename R > - handle< R > async( task< R > t, own_thread ep); - - template< typename R > - handle< R > async( task< R > t, new_thread ep); - - template< typename R, typename Channel > - handle< R > async( task< R > t, pool< Channel > & ep); - - template< typename R, typename Channel, typename Attr > - handle< R > async( task< R > t, Attr attr, pool< Channel > & ep); - - template< typename R, typename Strategy > - handle< R > async( task< R > t, tasklets::scheduler< Strategy > & ep); - -[variablelist -[[Effects:] [moves task to an asyncrounous executer and returns a handle associated with the task]] -[[Throws:] [`boost::thread_resource_error`]] -] -[endsect] - -[endsect] - -[include async_completion_token.qbk] -[include execution_policies.qbk] - -[endsect] diff --git a/libs/task/doc/execution_policies.qbk b/libs/task/doc/execution_policies.qbk deleted file mode 100644 index 363477d6..00000000 --- a/libs/task/doc/execution_policies.qbk +++ /dev/null @@ -1,21 +0,0 @@ -[/ - Copyright Oliver Kowalke 2009. - Distributed under the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt -] - - -[section:execution_policy Execution Policies] - -In contrast to synchronous methods asynchronous methods do not block the program flow when a time consuming operation is executed. -The application continues executing the current context and when the result of the asynchronous method is required the __act__ can be used. - -A __ep__ describes how a __task__ gets asynchronously executed and provides a __act__ to manage the __task__. - -[include own_thread.qbk] -[include new_thread.qbk] -[include as_sub_task.qbk] -[include threadpool.qbk] - -[endsect] diff --git a/libs/task/doc/fork_join.qbk b/libs/task/doc/fork_join.qbk deleted file mode 100644 index 72411ace..00000000 --- a/libs/task/doc/fork_join.qbk +++ /dev/null @@ -1,78 +0,0 @@ -/ - Copyright Oliver Kowalke 2009. - Distributed under the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt -] - - -[section:forkjoin Fork/Join] - -Fork/Join algorithms are recursive divide-and-conquer algorithms which repeatedly splitt into sub-tasks until they become small -enough to solve using simple, short sequential methods, so that they run in parallel on multiple cores. - -The fork operation creates new __sub_tasks__ which can run in parallel. The current __task__ is not proceeded in the join operation -until the forked __sub_tasks__ have completed. In the meantime the __worker_thread__ executes other tasks from its local __worker_queue__. - -`` - long serial_fib( long n) - { - if( n < 2) return n; - else return serial_fib( n - 1) + serial_fib( n - 2); - } - - long parallel_fib( long n, long cutof) - { - if ( n < cutof) return serial_fib( n); - else - { - // fork sub-task by moving the task - // ownership to the thread-pool - // sub-task computes fibonacci(n-1) - h1 = boost::task::async( - boost::task::make_task( - parallel_fib, - n - 1, - cutof) ); - - // fork sub-task by moving the task - // ownership to the thread-pool - // sub-task computes fibonacci(n-2) - h2 = boost::task::async( - boost::task::make_task( - parallel_fib, - n - 2, - cutof) ); - - // join the results of both sub-tasks - // if one of the both sub-tasks is not ready - // the worker-thread does not block, it executes other - // task from its local-queue - return h1.get() + h2.get(); - } - } - - void main() - { - boost::task::static_pool< boost::task::unbounded_fifo > pool( boost::task::poolsize( 5) ); - - // compute fibonacci-number 10 - // for numbers < 5 do inline calculation - boost::task::task< long > t( - parallel_fib, - 10, - 5); - - // move task ownership to thread-pool - boost::task::handle< long > h( - boost::task::async( - boost::move( t), - pool) ); - - // access result - std::cout << "fibonacci(10) == " << h.get() << std::endl; - } -`` - - -[endsect] diff --git a/libs/task/doc/handle.qbk b/libs/task/doc/handle.qbk deleted file mode 100644 index 262191a7..00000000 --- a/libs/task/doc/handle.qbk +++ /dev/null @@ -1,333 +0,0 @@ -[/ - Copyright Oliver Kowalke 2009. - Distributed under the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt -] - - -[section:handle Class template `handle`] - -[heading Synopsis] - -__handle__ represents an __act__. It will be returned by __async__ and is associated with the submitted __task__. - - long fibonacci( long n) - { - if ( n == 0) return 0; - if ( n == 1) return 1; - long k1( 1), k2( 0); - for ( int i( 2); i <= n; ++i) - { - long tmp( k1); - k1 = k1 + k2; - k2 = tmp; - } - return k1; - } - - void main() - { - // create task - boost::tasks::task< long > t( fibonacci, 10); - - // move task ownership to executor - boost::tasks::handle< long > h( - boost::tasks::async( - boost::move( t), - boost::tasks::new_thread() ) ); - - std::cout << "is ready == " << std::boolalpha << h.is_ready() << "\n"; - - // wait for task completion - h.wait(); - - std::cout << "has value == " << std::boolalpha << h.has_value() << "\n"; - std::cout << "has exception == " << std::boolalpha << h.has_exception() << "\n"; - - // return result - std::cout << "fibonacci(10) == " << h.get() << std::endl; - } - -[heading Interruption] - -Each invokation of __fn_async__ returns an __handle__ which allows to control the associated __task__ (passed to __fn_async__). This includes -the ability to interrupt an __task__ if it is cooperative. Cooperative means that the __task__ contains __interruption_points__ or checks for -interruption requests [footnote see [@http://www.ddj.com/architect/207100682 'Interrupt Politely'], Herb Sutter]. - -* __fn_interrupt__: interrupt __task__ and return immediately - -* __fn_interrupt_and_wait__: interrupt and wait until __task__ was removed from __worker_thread__ - -* __fn_interrupt_and_wait_for__: interrupt and wait until __task__ was removed from __worker_thread__ or time duration has elapsed - -* __fn_interrupt_and_wait_until__: interrupt and wait until __task__ was removed from __worker_thread__ or time point has reached - -* __fn_interruption_requested__: return bool if interruption was requested - - long cooperative( long n) - { - boost::this_thread::interruption_point(); // interruption point - - if ( n == 0) return 0; - if ( n == 1) return 1; - long k1( 1), k2( 0); - for ( int i( 2); i <= n; ++i) - { - if ( boost::this_thread::interruption_requested() ) // check if interruption was requested - return; - - long tmp( k1); - k1 = k1 + k2; - k2 = tmp; - } - - boost::this_thread::interruption_point(); // interruption point - - return k1; - } - - void main() - { - // task, to be executed asynchronously - boost::tasks::task< long > t( cooperative, 10); - - // move task to async. executor - boost::tasks::handle< long > h( - boost::tasks::async( - boost::move( t), - boost::tasks::new_thread() ) ); - - // interrupt task and wait until task is removed by worker-thread - h.interrupt_and_wait(); - - std::cout << "is ready == " << std::boolalpha << h.is_ready() << "\n"; - std::cout << "has value == " << std::boolalpha << h.has_value() << "\n"; - std::cout << "has exception == " << std::boolalpha << h.has_exception() << "\n"; - - // access result - // throws boost::tasks::task_interrupted - std::cout << h.get() << std::endl; - } - -[note If the task is still pending (not executed yet) when an interruption is requested - the task is not removed from the queue, it is marked to be interrupted instead.] - - -[heading Completion] - -__boost_task__ provides function __waitfor_all__ waits for all handles passed to this function to become ready - - void main() - { - std::vector handles< boost::tasks::handle< long > > results; - results.reserve( 10); - - for ( int i = 0; i < 10; ++i) - { - boost::tasks::task< long > t( fibonacci, i); - - results.push_back( - boost::tasks::async( - boost::move( t) ) ); - } - - // wait until all tasks are ready - boost::tasks::waitfor_all( results.begin(), results.end() ); - - int k = 0; - std::vector< boost::tasks::handle< long > >::iterator e( results.end() ); - for ( - std::vector< boost::tasks::handle< long > >::iterator i( results.begin() ); - i != e; - ++i) - std::cout << "fibonacci(" << k++ << ") == " << i->get() << std::endl; - } - -[section:handle Class template `handle`] - - #include - - template< typename R > - class handle - { - handle(); - - template< typename F > - handle( F const&, context const&); - - void interrupt(); - void interrupt_and_wait(); - void interrupt_and_wait_until( system_time const& abs_time); - template< typename TimeDuration > - void interrupt_and_wait_for( Duration const& rel_time); - bool interruption_requested(); - - R get(); - bool is_ready() const; - bool has_value() const; - bool has_exception() const; - void wait() const; - bool wait_until( system_time const& abs_time); - template< typename TimeDuration > - bool wait_for( TimeDuration const& rel_time); - - void swap( handle< R > & other); - }; - - template< typename Iterator > - friend void waitfor_all( Iterator begin, Iterator end); - - template< typename T1, typename T2 > - friend void waitfor_all( T1 & t1, T2 & t2); - ... - template< typename T1, typename T2, typename T3, typename T4, typename T5 > - friend void waitfor_all( handle< T1 > & t1, handle< T2 > & t2, handle< T3 > & t3, handle< T4 > & t4, handle< T5 > & t5); - -[section `handle()`] -[variablelist -[[Effects:] [constructs an empty (invalid) handle]] -[[Throws:] [Nothing]] -] -[endsect] - -[section `template< typename F > handle( F const&, context const&)`] -[variablelist -[[Effects:] [constructs an handle associated with an future and an context]] -[[Throws:] [Nothing]] -] -[endsect] - -[section `bool interruption_requested()`] -[variablelist -[[Effects:] [checks if interruption is already requested]] -[[Throws:] [Nothing]] -] -[endsect] - -[section `void interrupt()`] -[variablelist -[[Effects:] [requests task interruption; doesn not block (immediatly returns)]] -[[Throws:] [Nothing]] -] -[endsect] - -[section `void interrupt_and_wait()`] -[variablelist -[[Effects:] [requests task interruption and blocks until worker-thread stops task]] -[[Throws:] [`boost::thread_resource_error`]] -] -[endsect] - -[section `bool interrupt_and_wait_until( system_time const&)`] -[variablelist -[[Effects:] [requests task interruption and blocks until worker-thread stops task or time-point elapsed]] -[[Returns:] [false if the the time specified by abs_time was reached, true otherwise]] -[[Throws:] [`boost::thread_resource_error`]] -] -[endsect] - -[section `template< typename TimeDuration > interrupt_and_wait_for( TimeDuration const&)`] -[variablelist -[[Effects:] [requests task interruption and blocks until worker-thread stops task or time-duration elapsed]] -[[Returns:] [false if the the time specified by rel_time was reached, true otherwise]] -[[Throws:] [`boost::thread_resource_error`]] -] -[endsect] - -[section `R get()`] -[variablelist -[[Effects:] [requests the result]] -[[Throws:] [`boost::task::task_interrupted`, `boost::task::task_uninialized`, `boost::task::task_rejected`, `boost::task::broken_task`]] -] -[endsect] - -[section `void wait()`] -[variablelist -[[Effects:] [blocks caller until task is done]] -[[Throws:] [`boost::task::task_interrupted`, `boost::task::task_uninialized`, `boost::task::task_rejected`, `boost::task::broken_task`]] -] -[endsect] - -[section `template< typename TimeDuration > wait_for( TimeDuration const&)`] -[variablelist -[[Effects:] [blocks caller until task is done]] -[[Throws:] [`boost::task::task_interrupted`, `boost::task::task_uninialized`, `boost::task::task_rejected`, `boost::task::broken_task`]] -] -[endsect] - -[section `bool wait_until( system_time const& abs_time) const`] -[variablelist -[[Effects:] [blocks caller until task is done]] -[[Throws:] [`boost::task::task_interrupted`, `boost::task::task_uninialized`, `boost::task::task_rejected`, `boost::task::broken_task`]] -] -[endsect] - -[section `bool is_ready()`] -[variablelist -[[Effects:] [checks if task is done]] -[[Throws:] [Nothing]] -] -[endsect] - -[heading Member function `has_value()`] - - bool has_value() - -[variablelist -[[Effects:] [checks if task is done and a result value is set]] -[[Throws:] [Nothing]] -] - - -[heading Member function `has_exception()`] - - bool has_exception() - -[variablelist -[[Effects:] [checks if task is done and an exception is set]] -[[Throws:] [Nothing]] -] - - -[heading Member function `get_future()`] - - shared_future< R > & get_future() - -[variablelist -[[Effects:] [returns a reference to the internal shared_future< R >]] -[[Throws:] [Nothing]] -] - - -[heading Member function `swap()`] - - void swap( handle< R > & other) - -[variablelist -[[Effects:] [swapps handle]] -[[Throws:] [Nothing]] -] - - -[section Non-member function `wait_for_all()`] - - template< typename Iterator > - void waitfor_all( Iterator begin, Iterator end); - - template< typename T1, typename T2 > - void waitfor_all( T1 & t1, T2 & t2); - - ... - - template< typename T1, typename T2, typename T3, typename T4, typename T5 > - void waitfor_all( handle< T1 > & t1, handle< T2 > & t2, handle< T3 > & t3, handle< T4 > & t4, handle< T5 > & t5); - -[variablelist -[[Effects:] [waits for all handles to become ready]] -[[Throws:] [`boost::task::task_interrupted`, `boost::task::task_rejected`]] -] -[endsect] - -[endsect] - -[endsect] diff --git a/libs/task/doc/meta_functions.qbk b/libs/task/doc/meta_functions.qbk deleted file mode 100644 index fc889bde..00000000 --- a/libs/task/doc/meta_functions.qbk +++ /dev/null @@ -1,60 +0,0 @@ -[/ - Copyright Oliver Kowalke 2009. - Distributed under the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt -] - - -[section:meta_functions Meta functions] - -If the __thread_pool__ supports attributes (like priorities) __has_attribute__ evaluates to `true` at compile-time (derived from -boost::mpl::bool_). The type of the attribute is determined by __attribute_type__. - - // thread-pool with priority scheduling - // type of priority is int - typdef boost::task::static_pool< boost::task::unbounded_priority< int > > pool_type; - - // test if thread-pool supports priorities at compile time - std::cout << std::boolalpha << boost::task::has_attribute< pool_type >::value << "\n"; - - // access the type used for priority - std::cout << typeid( boost::task::attribute_type< pool_type >::type).name() << std::endl; - -[section:has_attribute Meta function `has_attribute`] - - #include - - template< typename Pool > - struct has_attribute : public mpl::bool_< - is_same< - detail::has_priority, - typename Pool::scheduler_type::priority_tag_type - >::value - > - {}; - -[variablelist -[[Effects:] [returns true if Pool supports attributes (priority-scheduling)]] -[[Throws:] [nothing]] -] -[endsect] - - -[section:attribute_type Meta function `attribute_type`] - - #include - - template< typename Pool > - struct attribute_type - { - typedef typename Pool::scheduler_type::attribute_type type; - }; - -[variablelist -[[Effects:] [returns type of attribute]] -[[Throws:] [nothing]] -] -[endsect] - -[endsect] diff --git a/libs/task/doc/new_thread.qbk b/libs/task/doc/new_thread.qbk deleted file mode 100644 index d1ed3b97..00000000 --- a/libs/task/doc/new_thread.qbk +++ /dev/null @@ -1,86 +0,0 @@ -[/ - Copyright Oliver Kowalke 2009. - Distributed under the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt -] - - -[section:new_thread Execute in Separat Thread] - -[heading Synopsis] - -__new_thread__ creates a new thread and executes the task in this thread (asynchronous). The created thread gets -joined by handle. -The returned __handle__ joins the thread in its destructor (if the last reference gets out of scope). - - long fibonacci( long n) - { - if ( n == 0) return 0; - if ( n == 1) return 1; - long k1( 1), k2( 0); - for ( int i( 2); i <= n; ++i) - { - long tmp( k1); - k1 = k1 + k2; - k2 = tmp; - } - return k1; - } - - void main() - { - boost::task::task< long > t( fibonacci, 10); - - boost::task::handle< long > h( - boost::task::async( - boost::move( t), - boost::task::new_thread() ) ); - - std::cout << "fibonacci(10) == " << h.get() << std::endl; - } - - -[caution Always store the returned __act__ in a variable because __handle__ joins the thread in its destructor (if the last -reference gets out of scope). ] - - -In the example below both `a_function()` and `another_function()` are executed synchron because the returned __handle__ is not stored in -a variable. Thatswhy the __worker_thread__ is joined after return from __fn_async__! - - boost::task::task< void > t1( a_function); - boost::task::task< void > t2( another_function); - - // handles are not retrieved - // both task executed in sequence - boost::task::async( - boost::move( t1), - boost::task::new_thread() ) ); - boost::task::async( - boost::move( t2), - boost::task::new_thread() ) ); - - -[section:new_thread Class `new_thread`] - - #include - - struct new_thread - { - template< typename R > - handle< R > operator()( task< R >); - }; - - -[section `template< typename R > handle< R > operator()( task< R > t)`] -[variablelist -[[Effects:] [moves task in a new thread an returns an handle associated with the task]] -[[Throws:] [`boost::thread_resource_error`]] -] -[endsect] - -[endsect] - -[endsect] - - diff --git a/libs/task/doc/overview.qbk b/libs/task/doc/overview.qbk deleted file mode 100644 index 4eb6c41f..00000000 --- a/libs/task/doc/overview.qbk +++ /dev/null @@ -1,140 +0,0 @@ -[/ - Copyright Oliver Kowalke 2009. - Distributed under the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt -] - - -[section:overview Overview] - -__boost_task__ provides a framework for asynchronous execution of tasks (small units of code that can be executed independently and parallel). - -* __task__, a __callable__ representing a fine-grained __work_item__: - * support of task synchron. via primitives like conditions, barriers, event-variables and channels (message exchange) - without blocking worker-thread in the __thread_pool__ - -* __handle__, works as a __act__ associated with a task: - * __fn_interrupt__, __fn_interrupt_and_wait__, ... allow to cancel an cooperative task - * __fn_get__ retrieve value or exception of task execution - * __fn_is_ready__ test if task was executed - * __fn_wait__, __fn_wait_for__ and __fn_wait_until__ block until task is executed and the result is set - * functions __waitfor_all__ to wait for all handles - -* __async__, executes a task by means of __eps__ - * executes task in current thread - * executes task in a newly created thread (thread will be destroyed after completion) - * task gets executed by a __worker_thread__ of a custom __thread_pool__ (for instance with priority or smart scheduling) - * executes task in newly created thread or in a pool of __worker_threads__ depending on whether the parent-task is already executed in a __thread_pool__ - -* __thread_pools__ with __work_stealing__ algorithm and __fork_join__ semantics - - -In order to use the classes and functions described here, you can either include the specific headers specified by the descriptions of each class or function, -or include the master library header: - - #include - -which includes all the other headers in turn. - -Used namespaces are: - - namespace boost::tasks - namespace boost::this_task - - -[heading Example] - - - long fibonacci( long n) - { - if ( n == 0) return 0; - if ( n == 1) return 1; - long k1( 1), k2( 0); - for ( int i( 2); i <= n; ++i) - { - long tmp( k1); - k1 = k1 + k2; - k2 = tmp; - } - return k1; - } - - void main() - { - // create a thread-pool - boost::tasks::static_pool< boost::tasks::unbounded_fifo > > pool( boost::tasks::poolsize( 5) ); - - // execute tasks in thread-pool - // move tasks ownership to executor - boost::tasks::handle< long > h1( - boost::tasks::async( - boost::tasks::make_task( fibonacci, 10), - pool); - boost::tasks::handle< long > h2( - boost::tasks::async( - boost::tasks::make_task( fibonacci, 5), - boost::move( t2), - pool); - - std::cout << "h1: is ready == " << std::boolalpha << h1.is_ready() << "\n"; - std::cout << "h2: is ready == " << std::boolalpha << h2.is_ready() << "\n"; - - // wait for completion of both tasks - boost::tasks::waitfor_all( h1, h2); - - std::cout << "h1: is ready == " << std::boolalpha << h1.is_ready() << "\n"; - std::cout << "h2: is ready == " << std::boolalpha << h2.is_ready() << "\n"; - std::cout << "h1: has value == " << std::boolalpha << h1.has_value() << "\n"; - std::cout << "h2: has value == " << std::boolalpha << h2.has_value() << "\n"; - std::cout << "h1: has exception == " << std::boolalpha << h1.has_exception() << "\n"; - std::cout << "h2: has exception == " << std::boolalpha << h2.has_exception() << "\n"; - - // get results - std::cout << "fibonacci(10) == " << h1.get() << std::endl; - std::cout << "fibonacci(5) == " << h2.get() << std::endl; - } - - -[heading References] - -* [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2185.html N2185]: Proposed Text for Parallel Task Execution, written by Peter Dimov. - -* [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2276.html N2276]: Thread Pools and Futures, written by Anthony Williams. - -* [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2802.html N2802]: A plea to reconsider detach-on-destruction for thread objects, written by Hans-J. Boehm. - -* [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2880.html N2880]: C++ object lifetime interactions with the threads API, written by Hans-J. Boehm and Lawrence Crowl. - -* [@http://herbsutter.wordpress.com 'Sutter’s Mill'] by Herb Sutter - -* mailing list of C++ standard committee's Library Working Group - -[warning This library is NOT an official Boost library] - -[note Please note that __boost_task__ is not optimized yet.] - -[note __boost_tasklet__ requires [*Boost Library 1.41.0] .] - -__boost_task__ depends uppon __boost_atomic__, __boost_move__ and __boost_tasklet__. - - -[heading Tested Platforms] - -__boost_task__ has been tested on the following platforms and compilers: - -* Debian GNU/Linux 2.6.31.6 (x86_64), GCC 4.3.4 -* Ubuntu GNU/Linux 2.6.28.11 (x86), ICC 11.1 -* FreeBSD 8.0 (x86), GCC 4.2.1 -* OpenSolaris 2009.06 (x86_64), GCC 4.3.2 -* Windows XP Professional (x86), MSVC 9.0 - - -[heading How to build and install] - -* download the sources from -[@http://www.boost-consulting.com/vault/index.php?directory=Concurrent%20Programming Boost Vault] -* extract the archive into the boost-source directory -* call [''bjam toolset= --with-task install'] in order to build and install the library - -[endsect] diff --git a/libs/task/doc/own_thread.qbk b/libs/task/doc/own_thread.qbk deleted file mode 100644 index bef3e24f..00000000 --- a/libs/task/doc/own_thread.qbk +++ /dev/null @@ -1,62 +0,0 @@ -[/ - Copyright Oliver Kowalke 2009. - Distributed under the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt -] - - -[section:own_thread Execute in Current Thread] - -[heading Synopsis] - -__own_thread__ executes the task in the current thread (synchronous execution). - - long fibonacci( long n) - { - if ( n == 0) return 0; - if ( n == 1) return 1; - long k1( 1), k2( 0); - for ( int i( 2); i <= n; ++i) - { - long tmp( k1); - k1 = k1 + k2; - k2 = tmp; - } - return k1; - } - - void main() - { - boost::task::task< long > t( fibonacci, 10); - - boost::task::handle< long > h( - boost::task::async( - boost::move( t), - boost::task::own_thread() ) ); - - std::cout << "fibonacci(10) == " << h.get() << std::endl; - } - - -[section:own_thread Class `own_thread`] - - #include - - struct own_thread - { - template< typename R > - handle< R > operator()( task< R > t); - }; - -[section `template< typename R > handle< R > operator()( task< R > t)`] -[variablelist -[[Effects:] [moves task in the current thread an returns an handle associated with the task]] -[[Throws:] [Nothing]] -] -[endsect] - -[endsect] - -[endsect] - diff --git a/libs/task/doc/processor_binding.qbk b/libs/task/doc/processor_binding.qbk deleted file mode 100644 index 49055859..00000000 --- a/libs/task/doc/processor_binding.qbk +++ /dev/null @@ -1,30 +0,0 @@ -[/ - Copyright Oliver Kowalke 2009. - Distributed under the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt -] - - -[section:processor_binding Processor binding] - -For some applications it is convenient to bind the __worker_threads__ to processors/cores of the system. For this purpose __fn_bind_to_processors__ must -be given to constructor instead __pool_size__ so that a __worker_thread__ is created an bound the the core. - -`` - typedef boost::task::static_pool< - boost::task::unbounded_queue< boost::tp::fifo > - > pool_type; - - // constructs thread-pool with worker-threads as - // CPUs/Cores are available on the system - pool_type pool( pool_type::bind_to_processors() ); -`` - -The constructor takes additional arguments for the [link_work_stealing work-stealing algorithm] and [link_queue high-] and [link_queue low-watermark] too. - -[note __boost_task__ does provide this feature only for Windows, Linux, AIX, HP-UX, Solaris and FreeBSD.] - - -[endsect] - diff --git a/libs/task/doc/queue.qbk b/libs/task/doc/queue.qbk deleted file mode 100644 index eb180391..00000000 --- a/libs/task/doc/queue.qbk +++ /dev/null @@ -1,118 +0,0 @@ -[/ - Copyright Oliver Kowalke 2009. - Distributed under the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt -] - - -[section:queue Global Queue] - -A __queue__ synchronizes the access between application threads and __worker_threads__ and implements policies for limitating the amount of queued tasks and how those tasks are scheduled ( first-in-first-out, priority ordering etc.) - - -[heading Bounded Queues] - -__bounded_queue__ limits the number of queued (pending) tasks in order to prevent resource exhaustion. -For this purpose a high- and low-watermark has to be passed at construction. -__hwm__ sets the maximum of pending tasks. If this limited is reached all threads which submit a task will be set to sleep (blocked). If it is equal to __lwm__ everytime a -sleeping producer thread will be woken up and puts its task if one worker thread has taken a task from the queue. -__lwm__ sets the threshold when blocked threads get woken up. If it is less than __hwm__ all sleeping producer threads will be woken up if -the amount of pending tasks reaches __lwm__. - - -[heading Unbounded Queues] - -__unbounded_queue__ allows ann unlimited number of tasks to be queued. -The insertion of an __task__ will never block. If the queue becomes empty __worker_threads__ will be set to sleep until new tasks are enqueued. - - -[heading Task Scheduling] - -For scheduling of tasks inside the queue following strategies are available: - -* fifo: first enqueued task is dequeued first - -* priority: the next item dequeued from the queue depends on its associated priority attribute and sorting criterion applied to the queue (template arguments) - - // thread-pool with priority scheduling - // tasks with higher priority are - // scheduled first - boost::task::static_pool< boost::task::unbounded_priority_queue< int > > pool( boost::task::poolsize( 5) ); - - boost::task::task< void > t1( some_fn); - boost::task::task< void > t2( another_fn); - - // move task t1 with priority 5 to thread-pool - boost::task::async( - boost::move( t1), - 5, - pool); - - // move task t2 with priority 3 to thread-pool - boost::task::async( - boost::move( t2), - 3, - pool); - - -* smart: enqueue- and dequeue-operations are determined by the template arguments und the task-attribute. The library provides an default let only one kind of task stored inside the queue (gets replaced by new one) - - long fibonacci_fn( long n) - { - if ( n == 0) return 0; - if ( n == 1) return 1; - long k1( 1), k2( 0); - for ( int i( 2); i <= n; ++i) - { - long tmp( k1); - k1 = k1 + k2; - k2 = tmp; - } - return k1; - } - - typedef boost::task::static_pool< boost::task::unbounded_smart_queue< int > > pool_type; - - void main() - { - pool_type pool( boost::task::poolsize( 1) ); - - ... - - boost::task::task< long > t1( - boost::bind( fibonacci_fn, 10) ); - boost::task::task< long > t2( - boost::bind( fibonacci_fn, 5) ); - - // replaced by later task with same attribute == 2 - // if still pending in pool - boost::task::async( - boost::move( t1), - 2, - pool); - - // will replace previous pending task with attribute == 2 - boost::task::async( - boost::move( t2), - 2, - pool); - } - - -__boost_task__ provides following queues: - -* bounded_fifo - -* bounded_priority_queue< Attr, Comp = std::less< Attr > > - -* bounded_smart_queue< Attr, Comp, Enq = detail::replace_oldest, Deq = detail::take_oldest > - - -* unbounded_fifo - -* unbounded_priority_queue< Attr, Comp = std::less< Attr > > - -* unbounded_smart_queue< Attr, Comp, Enq = detail::replace_oldest, Deq = detail::take_oldest > - -[endsect] diff --git a/libs/task/doc/scheduler.qbk b/libs/task/doc/scheduler.qbk deleted file mode 100644 index d68eb7f8..00000000 --- a/libs/task/doc/scheduler.qbk +++ /dev/null @@ -1,125 +0,0 @@ -[/ - Copyright Oliver Kowalke 2009. - Distributed under the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt -] - - -[section:scheduling Scheduling] - -The scheduling policy determines how tasks are scheduled inside the __queue__. - - -[heading fifo] - -First inserted pending __task__ gets taken first. - - -[heading priority] - -Each __task__ is submitted to the pool with a priority attribute. The type and ordering of the priority is user-defined. - -`` - // thread-pool with priority scheduling - // tasks with higher priority are - // scheduled first - boost::task::static_pool< - boost::task::unbounded_queue< - boost::task::priority< int > > - > pool( boost::task::poolsize( 5) ); - - boost::task::task< void > t1( some_fn); - boost::task::task< void > t2( another_fn); - - // move task t1 with priority 5 to thread-pool - boost::task::async( - boost::move( t1), - 5, - pool); - - // move task t2 with priority 3 to thread-pool - boost::task::async( - boost::move( t2), - 3, - pool); -`` - -In this example the tasks get scheduled by the assigned integer (third argument of __fn_async__). The __task__ with the -lowest priority gets scheduled first (taken by a __worker_thread__). The ordering can be changed by the second argument -of __priority__ (the default is `std::greater< Attr >`). - -`` - // thread-pool with priority scheduling - // tasks with lower priority are - // scheduled first - boost::task::static_pool< - boost::task::unbounded_queue< - boost::task::priority< int, std::less< int > > - > - > pool( boost::task::poolsize( 5) ); -`` - - -[heading smart] - -Each inserted __task__ is associated with an attribute. The scheduler gets an put- and take-policy as template arguments. -The corresponding policy gets applied for each insertion and removal. - -__boost_task__ provides __replace_oldest__ as put- policy and __take_oldest__ as take-policy. Both policies allow the -replacement of older (pending) tasks in the scheduler by new ones. - -`` - long fibonacci_fn( long n) - { - if ( n == 0) return 0; - if ( n == 1) return 1; - long k1( 1), k2( 0); - for ( int i( 2); i <= n; ++i) - { - long tmp( k1); - k1 = k1 + k2; - k2 = tmp; - } - return k1; - } - - typedef boost::task::static_pool< - boost::task::unbounded_queue< - boost::task::smart< - int, - std::less< int >, - boost::task::replace_oldest, - boost::task::take_oldest - > - > - > pool_type; - - void main() - { - pool_type pool( boost::task::poolsize( 1) ); - - ... - - boost::task::task< long > t1( - boost::bind( fibonacci_fn, 10) ); - boost::task::task< long > t2( - boost::bind( fibonacci_fn, 5) ); - - // replaced by later task with same attribute == 2 - // if still pending in pool - boost::task::async( - boost::move( t1), - 2, - pool); - - // will replace previous pending task with attribute == 2 - boost::task::async( - boost::move( t2), - 2, - pool); - } -`` - - -[endsect] diff --git a/libs/task/doc/shutdown.qbk b/libs/task/doc/shutdown.qbk deleted file mode 100644 index b0d2326f..00000000 --- a/libs/task/doc/shutdown.qbk +++ /dev/null @@ -1,106 +0,0 @@ -[/ - Copyright Oliver Kowalke 2009. - Distributed under the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt -] - - -[section:pool_shutdown Shutdown] - -__boost_task__ allows to shutdown a __thread_pool__ explicitly via functions __fn_shutdown__ and __fn_shutdown_now__. The -destructor of the pool calls __fn_shutdown__ if not already done so that all __worker_threads__ are joined. - -If __fn_shutdown__ is called - the the pool is set the closed state and all __worker_threads__ are joined until all pending tasks are processed. -No futher tasks can be submitted. - - long fibonacci_fn( long n) - { - if ( n == 0) return 0; - if ( n == 1) return 1; - long k1( 1), k2( 0); - for ( int i( 2); i <= n; ++i) - { - long tmp( k1); - k1 = k1 + k2; - k2 = tmp; - } - return k1; - } - - typedef boost::task::static_pool< boost::task::unbounded_fifo > pool_type; - - void main() - { - pool_type pool( boost::task::poolsize( 1) ); - - ... - - boost::task::task< long > t1( fibonacci_fn, 10); - boost::task::task< long > t2( fibonacci_fn, 5); - - boost::task::handle< long > h1( - boost::task::async( - boost::move( t1), - pool) ); - boost::task::handle< long > h2( - boost::task::async( - boost::move( t2), - pool) ); - - // waits until all pending tasks are finished - pool.shutdown(); - - std::cout << "fibonacci(10) == " << h1.get() << "\n"; - std::cout << "fibonacci(5) == " << h2.get() << std::endl; - } - -[note The deconstructor calls __fn_shutdown__ if the pool was not shutdown yet.] - - -The function __fn_shutdown_now__ closes the pool, interrupts and then joins all __worker_threads__. Pending tasks are unprocessed. - - long fibonacci_fn( long n) - { - if ( n == 0) return 0; - if ( n == 1) return 1; - long k1( 1), k2( 0); - for ( int i( 2); i <= n; ++i) - { - long tmp( k1); - k1 = k1 + k2; - k2 = tmp; - } - return k1; - } - - typedef boost::task::static_pool< boost::task::unbounded_fifo > pool_type; - - void main() - { - pool_type pool( boost::task::poolsize( 1) ); - - ... - - boost::task::task< long > t1( fibonacci_fn, 10); - boost::task::task< long > t2( fibonacci_fn, 5); - - boost::task::handle< long > h1( - boost::task::async( - boost::move( t1), - pool) ); - boost::task::handle< long > h2( - boost::task::async( - boost::move( t2), - pool) ); - - // requests task interruption and - // joins all worker-threads - pool.shutdown_now(); - - // accessing the result may throw task_interrupted - std::cout << "fibonacci(10) == " << h1.get() << "\n"; - std::cout << "fibonacci(5) == " << h2.get() << std::endl; - } - -[endsect] diff --git a/libs/task/doc/spin_barrier.qbk b/libs/task/doc/spin_barrier.qbk deleted file mode 100644 index 3257f653..00000000 --- a/libs/task/doc/spin_barrier.qbk +++ /dev/null @@ -1,47 +0,0 @@ -[/ - (C) Copyright 2007-8 Anthony Williams. - Distributed under the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt). -] - -[section:barriers Barriers] - -A barrier is a simple concept. Also known as a __rendezvous__, it is a synchronization point between multiple -contexts of execution. The barrier is configured for a particular number of tasks (`n`), and as -tasks reach the barrier they must wait until all `n` tasks have arrived. Once the `n`-th task has reached the -barrier, all the waiting tasks can proceed, and the barrier is reset. - -[section:barrier Class `barrier`] - - #include - - class barrier - { - public: - barrier( unsigned int initial); - - bool wait(); - }; - -Instances of __spin_barrier__ are not copyable or movable. - -[section:constructor `barrier( unsigned int initial)`] -[variablelist -[[Effects:] [Construct a barrier for `initial` tasks.]] -[[Throws:] [__invalid_argument__ if an error occurs.]] -] -[endsect] - -[section:wait `bool wait()`] -[variablelist -[[Effects:] [Block until `initial` tasks have called `wait` on `*this`. When the `initial`-th task calls `wait`, -all waiting tasks are unblocked, and the barrier is reset. ]] -[[Returns:] [`true` for exactly one task from each batch of waiting tasks, `false` otherwise.]] -[[Throws:] [__task_error__ if an error occurs.]] -] -[endsect] - -[endsect] - -[endsect] diff --git a/libs/task/doc/spin_condition_variables.qbk b/libs/task/doc/spin_condition_variables.qbk deleted file mode 100644 index 6ab25e11..00000000 --- a/libs/task/doc/spin_condition_variables.qbk +++ /dev/null @@ -1,199 +0,0 @@ -[/ - (C) Copyright 2007-8 Anthony Williams. - Distributed under the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt). -] - -[section:conditions Condition Variables] - -[heading Synopsis] - -The class `condition` provides a mechanism for one task to wait for notification `condition`. When the task is -woken from the wait, then it checks to see if the appropriate condition is now true, and continues if so. If the -condition is not true, then the task then calls `wait` again to resume waiting. In the simplest case, this -condition is just a boolean variable: - - boost::tasks::spin::condition cond; - boost::tasks::spin::mutex mtx; - bool data_ready; - - void process_data(); - - void wait_for_data_to_process() - { - boost::unique_lock< boost::tasks::spin::mutex > lk( mtx); - while ( ! data_ready) - { - cond.wait( lk); - } - process_data(); - } - -Notice that the `lk` is passed to `wait`: `wait` will atomically add the task to the set of tasks waiting on the -condition variable, and unlock the mutex. When the task is woken, the mutex will be locked again before the call -to `wait` returns. This allows other tasks to acquire the mutex in order to update the shared data, and ensures -that the data associated with the condition is correctly synchronized. - -In the mean time, another task sets the condition to `true`, and then calls either `notify_one` or `notify_all` on -the condition variable to wake one waiting task or all the waiting tasks respectively. - - void retrieve_data(); - void prepare_data(); - - void prepare_data_for_processing() - { - retrieve_data(); - prepare_data(); - { - boost::lock_guard< boost::tasks::spin::mutex > lk( mtx); - data_ready = true; - } - cond.notify_one(); - } - -Note that the same mutex is locked before the shared data is updated, but that the mutex does not have to be locked -across the call to `notify_one`. - -[section:condition Class `condition`] - - #include - - class condition - { - public: - condition(); - ~condition(); - - void notify_one(); - void notify_all(); - - void wait( boost::unique_lock< boost::tasks::spin::mutex > & lk); - - template< typename Pred > - void wait( boost::unique_lock< boost::tasks::spin::mutex > & lk, Pred pred); - - template< typename LockType > - void wait( LockType & lk); - - template< typename LockType, typename Pred > - void wait( LockType & lk, Pred predicate); - - void timed_wait( boost::unique_lock< boost::tasks::spin::mutex > & lk, system_time const& abs_time); - - template< typename TimeDuration > - void timed_wait( boost::unique_lock< boost::tasks::spin::mutex > & lk, TimeDuration const& rel_time); - - template< typename Pred > - void timed_wait( boost::unique_lock< boost::tasks::spin::mutex > & lk, system_time const& abs_time, Pred pred); - - template< typename TimeDuration, typename Pred > - void timed_wait( boost::unique_lock< boost::tasks::spin::mutex > & lk, TimeDuration const& rel_time, Pred pred); - - template< typename LockType > - void timed_wait( LockType & lk, system_time const& abs_time); - - template< typename TimeDuration, typename LockType > - void timed_wait( LockType & lk, TimeDuration const& rel_time); - - template< typename LockType, typename Pred > - void timed_wait( LockType & lk, system_time const& abs_time, Pred predicate); - - template< typename LockType, typename TimeDuration, typename Pred > - void timed_wait( LockType & lk, TimeDuration const& rel_time, Pred predicate); - }; - -[section:constructor `condition()`] -[variablelist -[[Effects:] [Constructs an object of class `condition`.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:destructor `~condition()`] -[variablelist -[[Precondition:] [All tasks waiting on `*this` have been notified by a call to `notify_one` or `notify_all` -(though the respective calls to `wait` need not have returned).]] -[[Effects:] [Destroys the object.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:notify_one `void notify_one()`] -[variablelist -[[Effects:] [If any tasks are currently __blocked__ waiting on `*this` in a call to `wait`, unblocks one of -those tasks.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:notify_all `void notify_all()`] -[variablelist -[[Effects:] [If any tasks are currently __blocked__ waiting on `*this` in a call to `wait`, unblocks all of -those tasks.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:wait `void wait( boost::unique_lock< boost::tasks::spin::mutex > & lk)`] -[variablelist -[[Precondition:] [`lk` is locked by the current task, and either no other -task is currently waiting on `*this`, or the execution of the `mutex()` member -function on the `lk` objects supplied in the calls to `wait` in all the tasks -currently waiting on `*this` would return the same value as `lk->mutex()` for -this call to `wait`.]] -[[Effects:] [Atomically call `lk.unlock()` and blocks the current task. The -task will unblock when notified by a call to `this->notify_one()` or -`this->notify_all()`, or spuriously. When the task is unblocked (for whatever -reason), the lock is reacquired by invoking `lk.lock()` before the call to -`wait` returns. The lock is also reacquired by invoking `lk.lock()` if the -function exits with an exception.]] -[[Postcondition:] [`lk` is locked by the current task.]] -[[Throws:] [__task_error__ if an error -occurs. __task_interrupted__ if the wait was interrupted by a call to -__interrupt__ on the __task__ object associated with the current task of execution.]] -] -[endsect] - -[section:wait_predicate `template< typename Pred > void wait( boost::unique_lock< boost::tasks::spin::mutex > & lk, Pred pred)`] -[variablelist -[[Effects:] [As-if `` -while ( ! pred()) -{ - wait( lk); -} -``]] - -] -[endsect] - -[section:wait_t `template< typename LockType > void wait( LockType & lk)`] -[variablelist -[[Effects:] [Atomically call `lk.unlock()` and blocks the current task. The -task will unblock when notified by a call to `this->notify_one()` or -`this->notify_all()`, or spuriously. When the task is unblocked (for whatever -reason), the lock is reacquired by invoking `lk.lock()` before the call to -`wait` returns. The lock is also reacquired by invoking `lk.lock()` if the -function exits with an exception.]] -[[Postcondition:] [`lk` is locked by the current task.]] -[[Throws:] [__task_error__ if an error -occurs. __task_interrupted__ if the wait was interrupted by a call to -__interrupt__ on the __task__ object associated with the current task of execution.]] -] -[endsect] - -[section:wait_predicate_t `template< typename LockType, typename Pred > void wait( LockType & lk, Pred pred)`] -[variablelist -[[Effects:] [As-if `` -while ( ! pred()) -{ - wait( lock); -} -``]] - -] -[endsect] - -[endsect] - -[endsect] diff --git a/libs/task/doc/spin_event_variables.qbk b/libs/task/doc/spin_event_variables.qbk deleted file mode 100644 index 415938fe..00000000 --- a/libs/task/doc/spin_event_variables.qbk +++ /dev/null @@ -1,289 +0,0 @@ -[/ - (C) Copyright 2009 Oliver Kowalke - Distributed under the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt). -] - -[section:eventvar_ref Event Variables] - -[heading Synopsis] - -__boost_task__ provides event variables to facilitate coordination between tasks. -A event-variable has two states `set` (`signaled`) or `reset` (`nonsignaled`). - - boost::tasks::spin::auto_reset_event ev; - - void process_data(); - - void wait_for_data_to_process() - { - ev.wait(); - process_data(); - } - -`wait` will atomically add the task to the set of tasks waiting on the event -variable. When the task is woken, the event variable will be reset again. - -In the mean time, another task signals the event variable by calling -`set` on the event variable to wake one waiting task. - - void retrieve_data(); - void prepare_data(); - - void prepare_data_for_processing() - { - retrieve_data(); - prepare_data(); - ev.set(); - } - - -[section:auto_reset_event Class `auto_reset_event`] - -[heading Synopsis] - -When the ['auto_reset_event] gets signaled, any one task will see this particular signal. When a task observes -the signal by waiting on the event, it is automatically transitioned back to non-signaled state. Any tasks can -subsequently set the event. - - #include - - class auto_reset_event : private boost::noncopyable - { - public: - explicit auto_reset_event( bool isset = false); - - ~auto_reset_event(); - - void set(); - - void wait(); - - bool try_wait(); - - bool timed_wait( system_time const& abs_time); - - templatey typename TimeDuration > - bool timed_wait( TimeDuration const& rel_time); - }; - -[section:constructor `explicit auto_reset_event( bool isset = false)`] -[variablelist -[[Effects:] [Constructs an object of class `auto_reset_event`. If isset is `true` -the variable is set.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:destructor `~auto_reset_event()`] -[variablelist -[[Precondition:] [All tasks waiting on `*this` have been notified by a call to -`set` (though the respective calls to `wait` need not have returned).]] -[[Effects:] [Destroys the object.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:set `void set()`] -[variablelist -[[Effects:] [If any tasks are currently __blocked__ waiting on `*this` in a call -to `wait`, unblocks one of those tasks.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:wait `void wait()`] -[variablelist -[[Effects:] [Blocks the current task. The task will unblock when notified by a call -to `this->set()`. When the task is unblocked, the variable is reset before `wait` -returns.]] -[[Throws:] [__task_interrupted__ if the wait was interrupted by a call to -__interrupt__ on the __task__ object associated with the current task of execution.]] -] -[endsect] - -[section:try_wait `bool try_wait()`] -[variablelist -[[Effects:] [Returns `true` if the event variable is set otherwise `false`.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[endsect] - - -[section:manual_reset_event Class `manual_reset_event`] - -[heading Synopsis] - -The ['manual_reset_event] remains signaled until it is manually reset. Multiple tasks -wait on the same event and observe the same signal. - - #include - - class manual_reset_event : private boost::noncopyable - { - public: - explicit manual_reset_event( bool isset = false); - - ~manual_reset_event(); - - void set(); - - void reset(); - - void wait(); - - bool try_wait(); - - bool timed_wait( system_time const& abs_time); - - templatey typename TimeDuration > - bool timed_wait( TimeDuration const& rel_time); - }; - -[section:constructor `explicit manual_reset_event( bool isset = false)`] -[variablelist -[[Effects:] [Constructs an object of class `manual_reset_event`. If isset is `true` -the variable is set.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:destructor `~manual_reset_event()`] -[variablelist -[[Precondition:] [All tasks waiting on `*this` have been notified by a call to -`set` (though the respective calls to `wait` need not have returned).]] -[[Effects:] [Destroys the object.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:set `void set()`] -[variablelist -[[Effects:] [If any tasks are currently __blocked__ waiting on `*this` in a call -to `wait`, unblocks those tasks. The variable remains signaled until `this->reset()` -gets called.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:reset `void reset()`] -[variablelist -[[Effects:] [The event variable gets nonsignaled and tasks calling `this->wait()` -will block.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:wait `void wait()`] -[variablelist -[[Effects:] [Blocks the current task. The task will unblock when notified by a call -to `this->set()`. When the task is unblocked, the variable remains set.]] -[[Throws:] [__task_interrupted__ if the wait was interrupted by a call to -__interrupt__ on the __task__ object associated with the current task of execution.]] -] -[endsect] - -[section:trywait `boo try_wait()`] -[variablelist -[[Effects:] [Returns `true` if the event variable is set otherwise `false`.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[endsect] - - -[section:count_down_event Class `count_down_event`] - -[heading Synopsis] - -The ['count_down_event] decrements an internal counter (set in the constructor) and all -waiting tasks are blocked until the count reaches zero. - - #include - - class count_down_event : private boost::noncopyable - { - public: - explicit count_down_event( unsigned int initial); - - ~count_down_event(); - - unsigned int initial() const; - - unsigned int current() const; - - bool is_set() const; - - void set(); - - void wait(); - - bool timed_wait( system_time const& abs_time); - - template< typename TimeDuration > - bool timed_wait( TimeDuration const& rel_time); - }; - -[section:constructor `explicit count_down_event( unsigned int initial)`] -[variablelist -[[Effects:] [Constructs an object of class `count_down_event` with initial value.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:destructor `~count_down_event()`] -[variablelist -[[Precondition:] [All tasks waiting on `*this` have been notified by a call to -`set` (though the respective calls to `wait` need not have returned).]] -[[Effects:] [Destroys the object.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:initial `unsigned int initial()`] -[variablelist -[[Effects:] [Returns the initial value the event variable was initialized with.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:current `unsigned int current()`] -[variablelist -[[Effects:] [Returns the value the variable currently holds.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:is_set `bool is_set()`] -[variablelist -[[Effects:] [Returns `true` if the varaible has reached zero.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:set `void set()`] -[variablelist -[[Effects:] [Decrements the current count. If the count reaches zero and any tasks are -currently __blocked__ waiting on `*this` in a call to `wait`, unblocks those tasks. -The variable remains signaled.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:wait `void wait()`] -[variablelist -[[Effects:] [Blocks the current task. The task will unblock when notified by a call -to `this->set()` and the count of the event variable reaches zero. When the task is -unblocked, the variable remains set.]] -[[Throws:] [__task_interrupted__ if the wait was interrupted by a call to -__interrupt__ on the __task__ object associated with the current task of execution.]] -] -[endsect] - -[endsect] - -[endsect] diff --git a/libs/task/doc/spin_fifos.qbk b/libs/task/doc/spin_fifos.qbk deleted file mode 100644 index adcdafaf..00000000 --- a/libs/task/doc/spin_fifos.qbk +++ /dev/null @@ -1,206 +0,0 @@ -[/ - Copyright Oliver Kowalke 2009. - Distributed under the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt -] - -[section:fifos (Un)Bounded fifos] - -__boost_task__ provides a bounded and a unbounded fifo suitable to synchonize tasks via message passing. - - typedef boost::tasks::spin::unbounded_channel< int > fifo_t; - - void send( fifo_t fifo) - { - for ( int i = 0; i < 5; ++i) - fifo.put( i); - fifo.deactivate(); - } - - void recv( fifo_t fifo) - { - boost::optional< int > value; - while ( fifo.take( value) ) - { std::cout << "received " << * value << std::endl; } - } - - boost::tasks::scheduler<> sched; - fifo_t fifo; - sched.make_task( send, fifo); - sched.make_task( recv, fifo); - - for (;;) - { - while ( sched.run() ); - if ( sched.empty() ) break; - } - - -[section:unbounded_channel Class template `unbounded_channel`] - - #include - - template< typename T > - class unbounded_channel : private noncopyable - { - public: - unbounded_channel(); - - void deactivate(); - - bool empty(); - - void put( T const& t); - - bool take( boost::optional< T > & va); - - bool take( boost::optional< T > & va, system_time const& abs_time); - - template< typename TimeDuration > - bool take( boost::optional< T > & va, TimeDuration const& rel_time); - - bool try_take( boost::optional< T > & va); - }; - -[section:constructor `unbounded_channel()`] -[variablelist -[[Effects:] [Constructs an object of class `unbounded_channel`.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:deactivate `void deactivate()`] -[variablelist -[[Effects:] [Deactivates the fifo. No values can be put after calling `this->deactivate`. tasks blocked in -`this->take()` will be return.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:empty `bool empty()`] -[variablelist -[[Effects:] [Returns `true` if the fifo currently contains no data.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:put `void put( T const& t)`] -[variablelist -[[Effects:] [Enqueues the value in the fifo and wakes up a task waiting for new data available from the -fifo.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:take `bool take( boost::optional< T > & va)`] -[variablelist -[[Effects:] [Dequeues a value from the fifo. If no data is available from the fifo the task gets suspended until -new data are enqueued (return value `true` and va contains dequeued value) or the fifo gets deactiveted and -the function returns `false`.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:try_take `bool try_take( boost::optional< T > & va)`] -[variablelist -[[Effects:] [Dequeues a value from the fifo. If no data is available from the fifo the function returns `false`. -Otherwise it returns `true` and `va` contains the dequed value.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[endsect] - - -[section:bounded_channel Class template `bounded_channel`] - - #include - - template< typename T > - class bounded_channel : private noncopyable - { - public: - bounded_channel( std::size_t wm); - - bounded_channel( std::size_t hwm, std::size_t lwm); - - void deactivate(); - - bool empty(); - - void put( T const& t); - - void put( T const& t, system_time const& abs_time); - - template< typename TimeDuration > - void put( T const& t, TimeDuration const& rel_time); - - bool take( boost::optional< T > & va); - - bool take( boost::optional< T > & va, system_time const& abs_time); - - template< typename TimeDuration > - bool take( boost::optional< T > & va, TimeDuration const& rel_time); - - bool try_take( boost::optional< T > & va); - }; - -[section:constructor `bounded_channel( std::size_t wm)`] -[variablelist -[[Effects:] [Constructs an object of class `bounded_channel` which will contain a maximum of `wm` items.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:constructor2 `bounded_channel( std::size_t hwm, std::size_t lwm)`] -[variablelist -[[Effects:] [Constructs an object of class `bounded_channel` which will contain a maximum of `hwm` items.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:deactivate `void deactivate()`] -[variablelist -[[Effects:] [Deactivates the fifo. No values can be put after calling `this->deactivate`. tasks blocked in -`this->take()` will be return.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:empty `bool empty()`] -[variablelist -[[Effects:] [Returns `true` if the fifo currently contains no data.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:put `void put( T const& t)`] -[variablelist -[[Effects:] [Enqueues the value in the fifo and wakes up a task waiting for new data available from the -fifo. If the watermark has reached the task putting the value will be supended until at least one item -was dequeued.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:take `bool take( boost::optional< T > & va)`] -[variablelist -[[Effects:] [Dequeues a value from the fifo. If no data is available from the fifo the task gets suspended until -new data are enqueued (return value `true` and va contains dequeued value) or the fifo gets deactiveted and -the function returns `false`.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:try_take `bool try_take( boost::optional< T > & va)`] -[variablelist -[[Effects:] [Dequeues a value from the fifo. If no data is available from the fifo the function returns `false`. -Otherwise it returns `true` and `va` contains the dequed value.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[endsect] - -[endsect] diff --git a/libs/task/doc/spin_future_ref.qbk b/libs/task/doc/spin_future_ref.qbk deleted file mode 100644 index c79451ab..00000000 --- a/libs/task/doc/spin_future_ref.qbk +++ /dev/null @@ -1,928 +0,0 @@ -[/ - (C) Copyright 2008-9 Anthony Williams. - Distributed under the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt). -] - -[section:reference Futures Reference] - -[section:future_state `state` enum] - - namespace future_state - { - enum state {uninitialized, waiting, ready}; - } - -[endsect] - -[section:unique_future `unique_future` class template] - - template - class unique_future - { - unique_future(unique_future & rhs);// = delete; - unique_future& operator=(unique_future& rhs);// = delete; - - public: - typedef future_state::state state; - - unique_future(); - ~unique_future(); - - // move support - unique_future(unique_future && other); - unique_future& operator=(unique_future && other); - - void swap(unique_future& other); - - // retrieving the value - R&& get(); - - // functions to check state - state get_state() const; - bool is_ready() const; - bool has_exception() const; - bool has_value() const; - - // waiting for the result to be ready - void wait() const; - template - bool timed_wait(Duration const& rel_time) const; - bool timed_wait_until(boost::system_time const& abs_time) const; - }; - -[section:default_constructor Default Constructor] - - unique_future(); - -[variablelist - -[[Effects:] [Constructs an uninitialized future.]] - -[[Postconditions:] [[unique_future_is_ready_link `this->is_ready`] returns `false`. [unique_future_get_state_link -`this->get_state()`] returns __uninitialized__.]] - -[[Throws:] [Nothing.]] - -] - -[endsect] - -[section:destructor Destructor] - - ~unique_future(); - -[variablelist - -[[Effects:] [Destroys `*this`.]] - -[[Throws:] [Nothing.]] - -] - -[endsect] - -[section:move_constructor Move Constructor] - - unique_future(unique_future && other); - -[variablelist - -[[Effects:] [Constructs a new future, and transfers ownership of the asynchronous result associated with `other` to `*this`.]] - -[[Postconditions:] [[unique_future_get_state_link `this->get_state()`] returns the value of `other->get_state()` prior to the -call. `other->get_state()` returns __uninitialized__. If `other` was associated with an asynchronous result, that result is now -associated with `*this`. `other` is not associated with any asynchronous result.]] - -[[Throws:] [Nothing.]] - -[[Notes:] [If the compiler does not support rvalue-references, this is implemented using the boost.thread move emulation.]] - -] - -[endsect] - -[section:move_assignment Move Assignment Operator] - - unique_future& operator=(unique_future && other); - -[variablelist - -[[Effects:] [Transfers ownership of the asynchronous result associated with `other` to `*this`.]] - -[[Postconditions:] [[unique_future_get_state_link `this->get_state()`] returns the value of `other->get_state()` prior to the -call. `other->get_state()` returns __uninitialized__. If `other` was associated with an asynchronous result, that result is now -associated with `*this`. `other` is not associated with any asynchronous result. If `*this` was associated with an asynchronous -result prior to the call, that result no longer has an associated __unique_future__ instance.]] - -[[Throws:] [Nothing.]] - -[[Notes:] [If the compiler does not support rvalue-references, this is implemented using the boost.thread move emulation.]] - -] - -[endsect] - -[section:swap Member function `swap()`] - - void swap(unique_future & other); - -[variablelist - -[[Effects:] [Swaps ownership of the asynchronous results associated with `other` and `*this`.]] - -[[Postconditions:] [[unique_future_get_state_link `this->get_state()`] returns the value of `other->get_state()` prior to the -call. `other->get_state()` returns the value of `this->get_state()` prior to the call. If `other` was associated with an -asynchronous result, that result is now associated with `*this`, otherwise `*this` has no associated result. If `*this` was -associated with an asynchronous result, that result is now associated with `other`, otherwise `other` has no associated result.]] - -[[Throws:] [Nothing.]] - -] - -[endsect] - - -[section:get Member function `get()`] - - R&& get(); - R& unique_future::get(); - void unique_future::get(); - -[variablelist - -[[Effects:] [If `*this` is associated with an asynchronous result, waits until the result is ready as-if by a call to -__unique_future_wait__, and retrieves the result (whether that is a value or an exception).]] - -[[Returns:] [If the result type `R` is a reference, returns the stored reference. If `R` is `void`, there is no return -value. Otherwise, returns an rvalue-reference to the value stored in the asynchronous result.]] - -[[Postconditions:] [[unique_future_is_ready_link `this->is_ready()`] returns `true`. [unique_future_get_state_link -`this->get_state()`] returns __ready__.]] - -[[Throws:] [__future_uninitialized__ if `*this` is not associated with an asynchronous result. __thread_interrupted__ if the result -associated with `*this` is not ready at the point of the call, and the current thread is interrupted. Any exception stored in the -asynchronous result in place of a value.]] - -[[Notes:] [`get()` is an ['interruption point].]] - -] - -[endsect] - -[section:wait Member function `wait()`] - - void wait(); - -[variablelist - -[[Effects:] [If `*this` is associated with an asynchronous result, waits until the result is ready. If the result is not ready on -entry, and the result has a ['wait callback] set, that callback is invoked prior to waiting.]] - -[[Throws:] [__future_uninitialized__ if `*this` is not associated with an asynchronous result. __thread_interrupted__ if the result -associated with `*this` is not ready at the point of the call, and the current thread is interrupted. Any exception thrown by the -['wait callback] if such a callback is called.]] - -[[Postconditions:] [[unique_future_is_ready_link `this->is_ready()`] returns `true`. [unique_future_get_state_link -`this->get_state()`] returns __ready__.]] - -[[Notes:] [`wait()` is an ['interruption point].]] - -] - -[endsect] - -[section:timed_wait_duration Member function `timed_wait()`] - - template - bool timed_wait(Duration const& wait_duration); - -[variablelist - -[[Effects:] [If `*this` is associated with an asynchronous result, waits until the result is ready, or the time specified by -`wait_duration` has elapsed. If the result is not ready on entry, and the result has a ['wait callback] set, that callback is -invoked prior to waiting.]] - -[[Returns:] [`true` if `*this` is associated with an asynchronous result, and that result is ready before the specified time has -elapsed, `false` otherwise.]] - -[[Throws:] [__future_uninitialized__ if `*this` is not associated with an asynchronous result. __thread_interrupted__ if the result -associated with `*this` is not ready at the point of the call, and the current thread is interrupted. Any exception thrown by the -['wait callback] if such a callback is called.]] - -[[Postconditions:] [If this call returned `true`, then [unique_future_is_ready_link `this->is_ready()`] returns `true` and -[unique_future_get_state_link `this->get_state()`] returns __ready__.]] - -[[Notes:] [`timed_wait()` is an ['interruption point]. `Duration` must be a type that meets the Boost.DateTime time duration requirements.]] - -] - -[endsect] - -[section:timed_wait_absolute Member function `timed_wait()`] - - bool timed_wait(boost::system_time const& wait_timeout); - -[variablelist - -[[Effects:] [If `*this` is associated with an asynchronous result, waits until the result is ready, or the time point specified by -`wait_timeout` has passed. If the result is not ready on entry, and the result has a ['wait callback] set, that callback is invoked -prior to waiting.]] - -[[Returns:] [`true` if `*this` is associated with an asynchronous result, and that result is ready before the specified time has -passed, `false` otherwise.]] - -[[Throws:] [__future_uninitialized__ if `*this` is not associated with an asynchronous result. __thread_interrupted__ if the result -associated with `*this` is not ready at the point of the call, and the current thread is interrupted. Any exception thrown by the -['wait callback] if such a callback is called.]] - -[[Postconditions:] [If this call returned `true`, then [unique_future_is_ready_link `this->is_ready()`] returns `true` and -[unique_future_get_state_link `this->get_state()`] returns __ready__.]] - -[[Notes:] [`timed_wait()` is an ['interruption point].]] - -] - -[endsect] - - -[section:is_ready Member function `is_ready()`] - - bool is_ready(); - -[variablelist - -[[Effects:] [Checks to see if the asynchronous result associated with `*this` is set.]] - -[[Returns:] [`true` if `*this` is associated with an asynchronous result, and that result is ready for retrieval, `false` -otherwise.]] - -[[Throws:] [Nothing.]] - -] - -[endsect] - -[section:has_value Member function `has_value()`] - - bool has_value(); - -[variablelist - -[[Effects:] [Checks to see if the asynchronous result associated with `*this` is set with a value rather than an exception.]] - -[[Returns:] [`true` if `*this` is associated with an asynchronous result, that result is ready for retrieval, and the result is a -stored value, `false` otherwise.]] - -[[Throws:] [Nothing.]] - -] - -[endsect] - -[section:has_exception Member function `has_exception()`] - - bool has_exception(); - -[variablelist - -[[Effects:] [Checks to see if the asynchronous result associated with `*this` is set with an exception rather than a value.]] - -[[Returns:] [`true` if `*this` is associated with an asynchronous result, that result is ready for retrieval, and the result is a -stored exception, `false` otherwise.]] - -[[Throws:] [Nothing.]] - -] - -[endsect] - -[section:get_state Member function `get_state()`] - - future_state::state get_state(); - -[variablelist - -[[Effects:] [Determine the state of the asynchronous result associated with `*this`, if any.]] - -[[Returns:] [__uninitialized__ if `*this` is not associated with an asynchronous result. __ready__ if the asynchronous result -associated with `*this` is ready for retrieval, __waiting__ otherwise.]] - -[[Throws:] [Nothing.]] - -] - -[endsect] - - -[endsect] - -[section:shared_future `shared_future` class template] - - template - class shared_future - { - public: - typedef future_state::state state; - - shared_future(); - ~shared_future(); - - // copy support - shared_future(shared_future const& other); - shared_future& operator=(shared_future const& other); - - // move support - shared_future(shared_future && other); - shared_future(unique_future && other); - shared_future& operator=(shared_future && other); - shared_future& operator=(unique_future && other); - - void swap(shared_future& other); - - // retrieving the value - R get(); - - // functions to check state, and wait for ready - state get_state() const; - bool is_ready() const; - bool has_exception() const; - bool has_value() const; - - // waiting for the result to be ready - void wait() const; - template - bool timed_wait(Duration const& rel_time) const; - bool timed_wait_until(boost::system_time const& abs_time) const; - }; - -[section:default_constructor Default Constructor] - - shared_future(); - -[variablelist - -[[Effects:] [Constructs an uninitialized future.]] - -[[Postconditions:] [[shared_future_is_ready_link `this->is_ready`] returns `false`. [shared_future_get_state_link -`this->get_state()`] returns __uninitialized__.]] - -[[Throws:] [Nothing.]] - -] - -[endsect] - -[section:get Member function `get()`] - - const R& get(); - -[variablelist - -[[Effects:] [If `*this` is associated with an asynchronous result, waits until the result is ready as-if by a call to -__shared_future_wait__, and returns a `const` reference to the result.]] - -[[Returns:] [If the result type `R` is a reference, returns the stored reference. If `R` is `void`, there is no return -value. Otherwise, returns a `const` reference to the value stored in the asynchronous result.]] - -[[Throws:] [__future_uninitialized__ if `*this` is not associated with an asynchronous result. __thread_interrupted__ if the -result associated with `*this` is not ready at the point of the call, and the current thread is interrupted.]] - -[[Notes:] [`get()` is an ['interruption point].]] - -] - -[endsect] - -[section:wait Member function `wait()`] - - void wait(); - -[variablelist - -[[Effects:] [If `*this` is associated with an asynchronous result, waits until the result is ready. If the result is not ready on -entry, and the result has a ['wait callback] set, that callback is invoked prior to waiting.]] - -[[Throws:] [__future_uninitialized__ if `*this` is not associated with an asynchronous result. __thread_interrupted__ if the result -associated with `*this` is not ready at the point of the call, and the current thread is interrupted. Any exception thrown by the -['wait callback] if such a callback is called.]] - -[[Postconditions:] [[shared_future_is_ready_link `this->is_ready()`] returns `true`. [shared_future_get_state_link -`this->get_state()`] returns __ready__.]] - -[[Notes:] [`wait()` is an ['interruption point].]] - -] - -[endsect] - -[section:timed_wait_duration Member function `timed_wait()`] - - template - bool timed_wait(Duration const& wait_duration); - -[variablelist - -[[Effects:] [If `*this` is associated with an asynchronous result, waits until the result is ready, or the time specified by -`wait_duration` has elapsed. If the result is not ready on entry, and the result has a ['wait callback] set, that callback is -invoked prior to waiting.]] - -[[Returns:] [`true` if `*this` is associated with an asynchronous result, and that result is ready before the specified time has -elapsed, `false` otherwise.]] - -[[Throws:] [__future_uninitialized__ if `*this` is not associated with an asynchronous result. __thread_interrupted__ if the result -associated with `*this` is not ready at the point of the call, and the current thread is interrupted. Any exception thrown by the -['wait callback] if such a callback is called.]] - -[[Postconditions:] [If this call returned `true`, then [shared_future_is_ready_link `this->is_ready()`] returns `true` and -[shared_future_get_state_link `this->get_state()`] returns __ready__.]] - -[[Notes:] [`timed_wait()` is an ['interruption point]. `Duration` must be a type that meets the Boost.DateTime time duration requirements.]] - -] - -[endsect] - -[section:timed_wait_absolute Member function `timed_wait()`] - - bool timed_wait(boost::system_time const& wait_timeout); - -[variablelist - -[[Effects:] [If `*this` is associated with an asynchronous result, waits until the result is ready, or the time point specified by -`wait_timeout` has passed. If the result is not ready on entry, and the result has a ['wait callback] set, that callback is invoked -prior to waiting.]] - -[[Returns:] [`true` if `*this` is associated with an asynchronous result, and that result is ready before the specified time has -passed, `false` otherwise.]] - -[[Throws:] [__future_uninitialized__ if `*this` is not associated with an asynchronous result. __thread_interrupted__ if the result -associated with `*this` is not ready at the point of the call, and the current thread is interrupted. Any exception thrown by the -['wait callback] if such a callback is called.]] - -[[Postconditions:] [If this call returned `true`, then [shared_future_is_ready_link `this->is_ready()`] returns `true` and -[shared_future_get_state_link `this->get_state()`] returns __ready__.]] - -[[Notes:] [`timed_wait()` is an ['interruption point].]] - -] - -[endsect] - -[section:is_ready Member function `is_ready()`] - - bool is_ready(); - -[variablelist - -[[Effects:] [Checks to see if the asynchronous result associated with `*this` is set.]] - -[[Returns:] [`true` if `*this` is associated with an asynchronous result, and that result is ready for retrieval, `false` -otherwise.]] - -[[Throws:] [Nothing.]] - -] - -[endsect] - -[section:has_value Member function `has_value()`] - - bool has_value(); - -[variablelist - -[[Effects:] [Checks to see if the asynchronous result associated with `*this` is set with a value rather than an exception.]] - -[[Returns:] [`true` if `*this` is associated with an asynchronous result, that result is ready for retrieval, and the result is a -stored value, `false` otherwise.]] - -[[Throws:] [Nothing.]] - -] - -[endsect] - -[section:has_exception Member function `has_exception()`] - - bool has_exception(); - -[variablelist - -[[Effects:] [Checks to see if the asynchronous result associated with `*this` is set with an exception rather than a value.]] - -[[Returns:] [`true` if `*this` is associated with an asynchronous result, that result is ready for retrieval, and the result is a -stored exception, `false` otherwise.]] - -[[Throws:] [Nothing.]] - -] - -[endsect] - -[section:get_state Member function `get_state()`] - - future_state::state get_state(); - -[variablelist - -[[Effects:] [Determine the state of the asynchronous result associated with `*this`, if any.]] - -[[Returns:] [__uninitialized__ if `*this` is not associated with an asynchronous result. __ready__ if the asynchronous result -associated with `*this` is ready for retrieval, __waiting__ otherwise.]] - -[[Throws:] [Nothing.]] - -] - -[endsect] - - -[endsect] - -[section:promise `promise` class template] - - template - class promise - { - promise(promise & rhs);// = delete; - promise & operator=(promise & rhs);// = delete; - public: - // template explicit promise(Allocator a); - - promise(); - ~promise(); - - // Move support - promise(promise && rhs); - promise & operator=(promise&& rhs); - - void swap(promise& other); - // Result retrieval - unique_future get_future(); - - // Set the value - void set_value(R& r); - void set_value(R&& r); - void set_exception(boost::exception_ptr e); - - template - void set_wait_callback(F f); - }; - -[section:default_constructor Default Constructor] - - promise(); - -[variablelist - -[[Effects:] [Constructs a new __promise__ with no associated result.]] - -[[Throws:] [Nothing.]] - -] - -[endsect] - -[section:move_constructor Move Constructor] - - promise(promise && other); - -[variablelist - -[[Effects:] [Constructs a new __promise__, and transfers ownership of the result associated with `other` to `*this`, leaving `other` -with no associated result.]] - -[[Throws:] [Nothing.]] - -[[Notes:] [If the compiler does not support rvalue-references, this is implemented using the boost.thread move emulation.]] - -] - -[endsect] - -[section:move_assignment Move Assignment Operator] - - promise& operator=(promise && other); - -[variablelist - -[[Effects:] [Transfers ownership of the result associated with `other` to `*this`, leaving `other` with no associated result. If there -was already a result associated with `*this`, and that result was not ['ready], sets any futures associated with that result to -['ready] with a __broken_promise__ exception as the result. ]] - -[[Throws:] [Nothing.]] - -[[Notes:] [If the compiler does not support rvalue-references, this is implemented using the boost.thread move emulation.]] - -] - -[endsect] - -[section:destructor Destructor] - - ~promise(); - -[variablelist - -[[Effects:] [Destroys `*this`. If there was a result associated with `*this`, and that result is not ['ready], sets any futures -associated with that task to ['ready] with a __broken_promise__ exception as the result.]] - -[[Throws:] [Nothing.]] - -] - -[endsect] - -[section:get_future Member Function `get_future()`] - - unique_future get_future(); - -[variablelist - -[[Effects:] [If `*this` was not associated with a result, allocate storage for a new asynchronous result and associate it with -`*this`. Returns a __unique_future__ associated with the result associated with `*this`. ]] - -[[Throws:] [__future_already_retrieved__ if the future associated with the task has already been retrieved. `std::bad_alloc` if any -memory necessary could not be allocated.]] - -] - -[endsect] - -[section:set_value Member Function `set_value()`] - - void set_value(R&& r); - void set_value(const R& r); - void promise::set_value(R& r); - void promise::set_value(); - -[variablelist - -[[Effects:] [If `*this` was not associated with a result, allocate storage for a new asynchronous result and associate it with -`*this`. Store the value `r` in the asynchronous result associated with `*this`. Any threads blocked waiting for the asynchronous -result are woken.]] - -[[Postconditions:] [All futures waiting on the asynchronous result are ['ready] and __unique_future_has_value__ or -__shared_future_has_value__ for those futures shall return `true`.]] - -[[Throws:] [__promise_already_satisfied__ if the result associated with `*this` is already ['ready]. `std::bad_alloc` if the memory -required for storage of the result cannot be allocated. Any exception thrown by the copy or move-constructor of `R`.]] - -] - -[endsect] - -[section:set_exception Member Function `set_exception()`] - - void set_exception(boost::exception_ptr e); - -[variablelist - -[[Effects:] [If `*this` was not associated with a result, allocate storage for a new asynchronous result and associate it with -`*this`. Store the exception `e` in the asynchronous result associated with `*this`. Any threads blocked waiting for the asynchronous -result are woken.]] - -[[Postconditions:] [All futures waiting on the asynchronous result are ['ready] and __unique_future_has_exception__ or -__shared_future_has_exception__ for those futures shall return `true`.]] - -[[Throws:] [__promise_already_satisfied__ if the result associated with `*this` is already ['ready]. `std::bad_alloc` if the memory -required for storage of the result cannot be allocated.]] - -] - -[endsect] - -[section:set_wait_callback Member Function `set_wait_callback()`] - - template - void set_wait_callback(F f); - -[variablelist - -[[Preconditions:] [The expression `f(t)` where `t` is a lvalue of type __packaged_task__ shall be well-formed. Invoking a copy of -`f` shall have the same effect as invoking `f`]] - -[[Effects:] [Store a copy of `f` with the asynchronous result associated with `*this` as a ['wait callback]. This will replace any -existing wait callback store alongside that result. If a thread subsequently calls one of the wait functions on a __unique_future__ -or __shared_future__ associated with this result, and the result is not ['ready], `f(*this)` shall be invoked.]] - -[[Throws:] [`std::bad_alloc` if memory cannot be allocated for the required storage.]] - -] - -[endsect] - -[endsect] - -[section:packaged_task `packaged_task` class template] - - template - class packaged_task - { - packaged_task(packaged_task&);// = delete; - packaged_task& operator=(packaged_task&);// = delete; - - public: - // construction and destruction - template - explicit packaged_task(F const& f); - - explicit packaged_task(R(*f)()); - - template - explicit packaged_task(F&& f); - - // template - // explicit packaged_task(F const& f, Allocator a); - // template - // explicit packaged_task(F&& f, Allocator a); - - ~packaged_task() - {} - - // move support - packaged_task(packaged_task&& other); - packaged_task& operator=(packaged_task&& other); - - void swap(packaged_task& other); - // result retrieval - unique_future get_future(); - - // execution - void operator()(); - - template - void set_wait_callback(F f); - }; - -[section:task_constructor Task Constructor] - - template - packaged_task(F const &f); - - packaged_task(R(*f)()); - - template - packaged_task(F&&f); - -[variablelist - -[[Preconditions:] [`f()` is a valid expression with a return type convertible to `R`. Invoking a copy of `f` shall behave the same -as invoking `f`.]] - -[[Effects:] [Constructs a new __packaged_task__ with a copy of `f` stored as the associated task.]] - -[[Throws:] [Any exceptions thrown by the copy (or move) constructor of `f`. `std::bad_alloc` if memory for the internal data -structures could not be allocated.]] - -] - -[endsect] - -[section:move_constructor Move Constructor] - - packaged_task(packaged_task && other); - -[variablelist - -[[Effects:] [Constructs a new __packaged_task__, and transfers ownership of the task associated with `other` to `*this`, leaving `other` -with no associated task.]] - -[[Throws:] [Nothing.]] - -[[Notes:] [If the compiler does not support rvalue-references, this is implemented using the boost.thread move emulation.]] - -] - -[endsect] - -[section:move_assignment Move Assignment Operator] - - packaged_task& operator=(packaged_task && other); - -[variablelist - -[[Effects:] [Transfers ownership of the task associated with `other` to `*this`, leaving `other` with no associated task. If there -was already a task associated with `*this`, and that task has not been invoked, sets any futures associated with that task to -['ready] with a __broken_promise__ exception as the result. ]] - -[[Throws:] [Nothing.]] - -[[Notes:] [If the compiler does not support rvalue-references, this is implemented using the boost.thread move emulation.]] - -] - -[endsect] - -[section:destructor Destructor] - - ~packaged_task(); - -[variablelist - -[[Effects:] [Destroys `*this`. If there was a task associated with `*this`, and that task has not been invoked, sets any futures -associated with that task to ['ready] with a __broken_promise__ exception as the result.]] - -[[Throws:] [Nothing.]] - -] - -[endsect] - -[section:get_future Member Function `get_future()`] - - unique_future get_future(); - -[variablelist - -[[Effects:] [Returns a __unique_future__ associated with the result of the task associated with `*this`. ]] - -[[Throws:] [__task_moved__ if ownership of the task associated with `*this` has been moved to another instance of -__packaged_task__. __future_already_retrieved__ if the future associated with the task has already been retrieved.]] - -] - -[endsect] - -[section:call_operator Member Function `operator()()`] - - void operator()(); - -[variablelist - -[[Effects:] [Invoke the task associated with `*this` and store the result in the corresponding future. If the task returns normally, -the return value is stored as the asynchronous result, otherwise the exception thrown is stored. Any threads blocked waiting for the -asynchronous result associated with this task are woken.]] - -[[Postconditions:] [All futures waiting on the asynchronous result are ['ready]]] - -[[Throws:] [__task_moved__ if ownership of the task associated with `*this` has been moved to another instance of -__packaged_task__. __task_already_started__ if the task has already been invoked.]] - -] - -[endsect] - -[section:set_wait_callback Member Function `set_wait_callback()`] - - template - void set_wait_callback(F f); - -[variablelist - -[[Preconditions:] [The expression `f(t)` where `t` is a lvalue of type __packaged_task__ shall be well-formed. Invoking a copy of -`f` shall have the same effect as invoking `f`]] - -[[Effects:] [Store a copy of `f` with the task associated with `*this` as a ['wait callback]. This will replace any existing wait -callback store alongside that task. If a thread subsequently calls one of the wait functions on a __unique_future__ or -__shared_future__ associated with this task, and the result of the task is not ['ready], `f(*this)` shall be invoked.]] - -[[Throws:] [__task_moved__ if ownership of the task associated with `*this` has been moved to another instance of -__packaged_task__.]] - -] - -[endsect] - - -[endsect] - -[section:wait_for_all Non-member function `wait_for_all()`] - - template - void wait_for_all(Iterator begin,Iterator end); - - template - void wait_for_all(F1& f1,F2& f2); - - template - void wait_for_all(F1& f1,F2& f2,F3& f3); - - template - void wait_for_all(F1& f1,F2& f2,F3& f3,F4& f4); - - template - void wait_for_all(F1& f1,F2& f2,F3& f3,F4& f4,F5& f5); - -[variablelist - -[[Preconditions:] [The types `Fn` shall be specializations of -__unique_future__ or __shared_future__, and `Iterator` shall be a -forward iterator with a `value_type` which is a specialization of -__unique_future__ or __shared_future__.]] - -[[Effects:] [Waits until all of the specified futures are ['ready].]] - -[[Throws:] [Any exceptions thrown by a call to `wait()` on the specified futures.]] - -[[Notes:] [`wait_for_all()` is an ['interruption point].]] - -] - - -[endsect] - - -[endsect] diff --git a/libs/task/doc/spin_futures.qbk b/libs/task/doc/spin_futures.qbk deleted file mode 100644 index ec1d016b..00000000 --- a/libs/task/doc/spin_futures.qbk +++ /dev/null @@ -1,181 +0,0 @@ -[/ - (C) Copyright 2008-9 Anthony Williams. - Distributed under the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt). -] - -[section:futures Futures] - -[template future_state_link[link_text] [link task.spin_synchronization.futures.reference.future_state [link_text]]] -[def __uninitialized__ [future_state_link `boost::future_state::uninitialized`]] -[def __ready__ [future_state_link `boost::future_state::ready`]] -[def __waiting__ [future_state_link `boost::future_state::waiting`]] - -[def __future_uninitialized__ `boost::future_uninitialized`] -[def __broken_promise__ `boost::broken_promise`] -[def __future_already_retrieved__ `boost::future_already_retrieved`] -[def __task_moved__ `boost::task_moved`] -[def __task_already_started__ `boost::task_already_started`] -[def __promise_already_satisfied__ `boost::promise_already_satisfied`] - -[def __task_interrupted__ `boost::task_interrupted`] - - -[template unique_future_link[link_text] [link task.spin_synchronization.futures.reference.unique_future [link_text]]] -[def __unique_future__ [unique_future_link `boost::unique_future`]] - -[template unique_future_get_link[link_text] [link task.spin_synchronization.futures.reference.unique_future.get [link_text]]] -[def __unique_future_get__ [unique_future_get_link `boost::unique_future::get()`]] - -[template unique_future_wait_link[link_text] [link task.spin_synchronization.futures.reference.unique_future.wait [link_text]]] -[def __unique_future_wait__ [unique_future_wait_link `boost::unique_future::wait()`]] - -[template unique_future_is_ready_link[link_text] [link task.spin_synchronization.futures.reference.unique_future.is_ready [link_text]]] -[def __unique_future_is_ready__ [unique_future_is_ready_link `boost::unique_future::is_ready()`]] - -[template unique_future_has_value_link[link_text] [link task.spin_synchronization.futures.reference.unique_future.has_value [link_text]]] -[def __unique_future_has_value__ [unique_future_has_value_link `boost::unique_future::has_value()`]] - -[template unique_future_has_exception_link[link_text] [link task.spin_synchronization.futures.reference.unique_future.has_exception [link_text]]] -[def __unique_future_has_exception__ [unique_future_has_exception_link `boost::unique_future::has_exception()`]] - -[template unique_future_get_state_link[link_text] [link task.spin_synchronization.futures.reference.unique_future.get_state [link_text]]] -[def __unique_future_get_state__ [unique_future_get_state_link `boost::unique_future::get_state()`]] - -[template shared_future_link[link_text] [link task.spin_synchronization.futures.reference.shared_future [link_text]]] -[def __shared_future__ [shared_future_link `boost::shared_future`]] - -[template shared_future_get_link[link_text] [link task.spin_synchronization.futures.reference.shared_future.get [link_text]]] -[def __shared_future_get__ [shared_future_get_link `boost::shared_future::get()`]] - -[template shared_future_wait_link[link_text] [link task.spin_synchronization.futures.reference.shared_future.wait [link_text]]] -[def __shared_future_wait__ [shared_future_wait_link `boost::shared_future::wait()`]] - -[template shared_future_is_ready_link[link_text] [link task.spin_synchronization.futures.reference.shared_future.is_ready [link_text]]] -[def __shared_future_is_ready__ [shared_future_is_ready_link `boost::shared_future::is_ready()`]] - -[template shared_future_has_value_link[link_text] [link task.spin_synchronization.futures.reference.shared_future.has_value [link_text]]] -[def __shared_future_has_value__ [shared_future_has_value_link `boost::shared_future::has_value()`]] - -[template shared_future_has_exception_link[link_text] [link task.spin_synchronization.futures.reference.shared_future.has_exception [link_text]]] -[def __shared_future_has_exception__ [shared_future_has_exception_link `boost::shared_future::has_exception()`]] - -[template shared_future_get_state_link[link_text] [link task.spin_synchronization.futures.reference.shared_future.get_state [link_text]]] -[def __shared_future_get_state__ [shared_future_get_state_link `boost::shared_future::get_state()`]] - -[template promise_link[link_text] [link task.spin_synchronization.futures.reference.promise [link_text]]] -[def __promise__ [promise_link `boost::promise`]] - -[template packaged_task_link[link_text] [link task.spin_synchronization.futures.reference.packaged_task [link_text]]] -[def __packaged_task__ [packaged_task_link `boost::packaged_task`]] -[/ -[template wait_for_any_link[link_text] [link task.spin_synchronization.futures.reference.wait_for_any [link_text]]] -[def __wait_for_any__ [wait_for_any_link `boost::wait_for_any()`]] -] -[template wait_for_all_link[link_text] [link task.spin_synchronization.futures.reference.wait_for_all [link_text]]] -[def __wait_for_all__ [wait_for_all_link `boost::wait_for_all()`]] - - -[section:overview Overview] - -The futures library provides a means of handling synchronous future values, whether those values are generated by another task, or -on a single task in response to external stimuli, or on-demand. - -This is done through the provision of four class templates: __unique_future__ and __shared_future__ which are used to retrieve the -asynchronous results, and __promise__ and __packaged_task__ which are used to generate the asynchronous results. - -An instance of __unique_future__ holds the one and only reference to a result. Ownership can be transferred between instances using -the move constructor or move-assignment operator, but at most one instance holds a reference to a given asynchronous result. When -the result is ready, it is returned from __unique_future_get__ by rvalue-reference to allow the result to be moved or copied as -appropriate for the type. - -On the other hand, many instances of __shared_future__ may reference the same result. Instances can be freely copied and assigned, -and __shared_future_get__ returns a `const` reference so that multiple calls to __shared_future_get__ are safe. You can move an -instance of __unique_future__ into an instance of __shared_future__, thus transferring ownership of the associated asynchronous -result, but not vice-versa. - -You can wait for futures either individually or with one of the __wait_for_any__ and __wait_for_all__ functions. - -[endsect] - -[section:creating Creating asynchronous values] - -You can set the value in a future with either a __promise__ or a __packaged_task__. A __packaged_task__ is a callable object that -wraps a function or callable object. When the packaged task is invoked, it invokes the contained function in turn, and populates a -future with the return value. This is an answer to the perennial question: "how do I return a value from a task?": package the -function you wish to run as a __packaged_task__ and pass the packaged task to the task constructor. The future retrieved from the -packaged task can then be used to obtain the return value. If the function throws an exception, that is stored in the future in -place of the return value. - - int calculate_the_answer_to_life_the_universe_and_everything() - { return 42; } - - boost::tasks::spin::packaged_task< int > pt( calculate_the_answer_to_life_the_universe_and_everything); - boost::tasks::spin::unique_future< int > fi( pt.get_future() ); - - boost::task task( boost::move( pt) ); // launch task on a task - - fi.wait(); // wait for it to finish - - assert( fi.is_ready() ); - assert( fi.has_value() ); - assert( ! fi.has_exception() ); - assert( fi.get_state() == boost::future_state::ready); - assert( fi.get() == 42); - - -A __promise__ is a bit more low level: it just provides explicit functions to store a value or an exception in the associated -future. A promise can therefore be used where the value may come from more than one possible source, or where a single operation may -produce multiple values. - - boost::tasks::spin::promise< int > pi; - boost::tasks::spin::unique_future< int > fi; - fi = pi.get_future(); - - pi.set_value( 42); - - assert( fi.is_ready() ); - assert( fi.has_value() ); - assert( ! fi.has_exception() ); - assert( fi.get_state() == boost::future_state::ready); - assert( fi.get() == 42); - -[endsect] - -[section:lazy_futures Wait Callbacks and Lazy Futures] - -Both __promise__ and __packaged_task__ support ['wait callbacks] that are invoked when a task blocks in a call to `wait()` or -`timed_wait()` on a future that is waiting for the result from the __promise__ or __packaged_task__, in the task that is doing the -waiting. These can be set using the `set_wait_callback()` member function on the __promise__ or __packaged_task__ in question. - -This allows ['lazy futures] where the result is not actually computed until it is needed by some task. In the example below, the -call to `f.get()` invokes the callback `invoke_lazy_task`, which runs the task to set the value. If you remove the call to -`f.get()`, the task is not ever run. - - int calculate_the_answer_to_life_the_universe_and_everything() - { return 42; } - - void invoke_lazy_task( boost::tasks::spin::packaged_task< int > & task) - { - try - { task(); } - catch( boost::task_already_started const&) - {} - } - - int main() - { - boost::tasks::spin::packaged_task< int > task( calculate_the_answer_to_life_the_universe_and_everything); - task.set_wait_callback( invoke_lazy_task); - boost::tasks::spin::unique_future< int > f( task.get_future() ); - - assert( f.get() == 42); - } - - -[endsect] - -[include spin_future_ref.qbk] - -[endsect] diff --git a/libs/task/doc/spin_mutexes.qbk b/libs/task/doc/spin_mutexes.qbk deleted file mode 100644 index 192b6342..00000000 --- a/libs/task/doc/spin_mutexes.qbk +++ /dev/null @@ -1,43 +0,0 @@ -[/ - (C) Copyright 2007-8 Anthony Williams. - Distributed under the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt). -] - -[section:mutex_types Mutex Types] - -[section:mutex Class `mutex`] - - #include - - class mutex : private boost::noncopyable - { - public: - mutex(); - ~mutex(); - - void lock(); - - bool timed_lock( system_time const& abs_time); - - template< typename TimeDuration > - bool timed_lock( TimeDuration const& rel_time); - - bool try_lock(); - - void unlock(); - - typedef unique_lock< mutex > scoped_lock; - }; - -__spin_mutex__ implements the __lockable_concept__ to provide an exclusive-ownership mutex. At most one task can own the -lock on a given instance of __spin_mutex__ at any time. Multiple concurrent calls to __lock__, __try_lock__ and -__unlock__ shall be permitted. - -[note __spin_mutex__ is ['not] bound to a __scheduler__ and can only be used by tasks -managed by different schedulers or code not running in a task.] - -[endsect] - -[endsect] diff --git a/libs/task/doc/spin_synchronization.qbk b/libs/task/doc/spin_synchronization.qbk deleted file mode 100644 index ea7f7896..00000000 --- a/libs/task/doc/spin_synchronization.qbk +++ /dev/null @@ -1,18 +0,0 @@ -[/ - Copyright Oliver Kowalke 2009. - Distributed under the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt -] - -[section:spin_synchronization Synchronization] - -Synch. objects using spin-wait ops. reside in namespace `boost::tasks::spin`. - -[include spin_mutexes.qbk] -[include spin_condition_variables.qbk] -[include spin_barrier.qbk] -[include spin_event_variables.qbk] -[include spin_fifos.qbk] -[include spin_futures.qbk] -[endsect] diff --git a/libs/task/doc/static_pool.qbk b/libs/task/doc/static_pool.qbk deleted file mode 100644 index efed2a94..00000000 --- a/libs/task/doc/static_pool.qbk +++ /dev/null @@ -1,301 +0,0 @@ -[/ - Copyright Oliver Kowalke 2009. - Distributed under the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt -] - - -[section:static_pool Thread-Pool with fixed ] - -__boost_task__ provides __static_pool__ - which contains an fixed set of pre-forked __worker_threads__ (the size of the pool doesn't change during its lifetime). -__static_pool__ supports move semantics. - - boost::task::_static_pool< // pool type - boost::task::unbounded_fifo // queue where application threads enqueue tasks - > pool( - boost::task::poolsize( 6), // pool with 6 pre-forked worker-threads - boost::posix_time::posix_time::milliseconds( 50), // time to sleep if no work-item available - boost::task::scanns( 10) ); // iterations over local-queues before sleep - - -The first argument of the constructor specifies how many __worker_threads__ the pool will contain. The second -and third argument are used by the [link_work_stealing __work_stealing__] algorithm. - -[note If __bounded_queue__ is used as queuing policy the constructor has two additional arguments . ] - -__static_pool__ provides functionality to check the status of the pool - __fn_closed__ returns true when the pool was -shutdown and __fn_size__returns the number of __worker_threads__. - -[section:static_pool Class template `static_pool`] - - #include - - template< typename Channel > - class static_pool : private noncopyable - { - public: - static_pool(); - - explicit static_pool( - poolsize const& psize, - posix_time::time_duration const& asleep = posix_time::microseconds( 10), - scanns const& scns = scanns( 20) ); - - explicit static_pool( - poolsize const& psize, - high_watermark const& hwm, - low_watermark const& lwm, - posix_time::time_duration const& asleep = posix_time::milliseconds( 100), - scanns const& scns = scanns( 20) ); - - static_pool( static_pool &&); - - static_pool & operator=( static_pool &&); - - # if defined(BOOST_HAS_PROCESSOR_BINDINGS) - explicit static_pool( - <>, - posix_time::time_duration const& asleep = posix_time::microseconds( 10), - scanns const& scns = scanns( 20) ); - - explicit static_pool( - <>, - high_watermark const& hwm, - low_watermark const& lwm, - posix_time::time_duration const& asleep = posix_time::milliseconds( 100), - scanns const& scns = scanns( 20) ); - - static <> bind_to_processors(); - # endif - - ~static_pool(); - - std::size_t size(); - - void shutdown(); - void shutdown_now(); - - bool closed(); - - void interrupt_all_worker(); - - const std::size_t upper_bound(); - void upper_bound( high_watermark const& hwm); - const std::size_t lower_bound(); - void lower_bound( low_watermark const& lwm); - - template< typename R > - handle< R > submit( task< R > && t); - - template< typename R, typename Attr > - handle< R > submit( task< R > && t, Attr const& attr); - - void swap( static_pool & other); - - operator unspecified_bool_type() const; - bool operator!() const; - }; - - -[section `static_pool()`] -[variablelist -[[Effects:] [constructs an unitialized pool]] -[[Throws:] [nothing]] -] -[endsect] - -[section `explicit static_pool( - <>, - posix_time::time_duration const& asleep = posix_time::microseconds( 10), - scanns const& scns = scanns( 20) )`] -[variablelist -[[Preconditions:] [operating system provides functionality for processor binding]] -[[Effects:] [constructs a pool - for each processor a worker-thread is created and bound to one processor - global-queue can queue an unlimited number of tasks]] -[[Throws:] [`boost::thread_resource_error`, `boost::task::invalid_scanns`, `boost::task::invalid_timeduration`]] -[[Notes:] [constructor has to be called if a unbounded-queue is used and `bind_to_processors()` must be set as first argument]] -] -[endsect] - -[section `explicit static_pool( - poolsize const& psize, - posix_time::time_duration const& asleep = posix_time::microseconds( 10), - scanns const& scns = scanns( 20) )`] -[variablelist -[[Effects:] [constructs a pool containing psize worker-threads - global-queue can queue an unlimited number of tasks]] -[[Throws:] [`boost::thread_resource_error`, `boost::task::invalid_scanns`, `boost::task::invalid_timeduration`]] -[[Notes:] [constructor has to be called if a unbounded-queue is used]] -] -[endsect] - -[section `explicit static_pool( - <>, - high_watermark const& hwm, - low_watermark const& lwm, - posix_time::time_duration const& asleep = posix_time::milliseconds( 100), - scanns const& scns = scanns( 20) )`] -[variablelist -[[Preconditions:] [operating system provides functionality for processor binding]] -[[Effects:] [constructs a pool - for each processor a worker-thread is created and bound to one processor - global-queue can only queue a limited number of tasks]] -[[Throws:] [`boost::thread_resource_error`, `boost::task::invalid_scanns`, `boost::task::invalid_timeduration`, `boost::task::invalid_watermark`]] -[[Notes:] [constructor has to be called if a bounded-queue is used and `bind_to_processors()` must be set as first argument]] -] -[endsect] - -[section `explicit static_pool( - poolsize const& psize, - high_watermark const& hwm, - low_watermark const& lwm, - posix_time::time_duration const& asleep = posix_time::milliseconds( 100), - scanns const& scns = scanns( 20) )`] -[variablelist -[[Effects:] [constructs a pool containing psize worker-threads - global-queue can only queue a limited number of tasks]] -[[Throws:] [`boost::thread_resource_error`, `boost::task::invalid_scanns`, `boost::task::invalid_timeduration`, `boost::task::invalid_watermark`]] -[[Notes:] [constructor has to be called if a bounded-queue is used]] -] -[endsect] - -[section `static_pool( static_pool &&)`] -[variablelist -[[Effects:] [creates an pool out of another one which gets zeroed out]] -[[Throws:] [nothing]] -] -[endsect] - -[section `static_pool & operator=( static_pool &&)`] -[variablelist -[[Effects:] [creates an pool out of another one which gets zeroed out]] -[[Throws:] [nothing]] -] -[endsect] - -[section `~static_pool()`] -[variablelist -[[Effects:] [calls `shutdown()` if not already called]] -[[Throws:] [nothing]] -] -[endsect] - -[section `<> bind_to_processors()`] -[variablelist -[[Effects:] [used in order to let the pool create worker-threads as cores are available and bound the threads to the cores]] -[[Throws:] [nothing]] -] -[endsect] - -[section `std::size_t size()`] -[variablelist -[[Effects:] [returns how many worker-threads are running in the pool]] -[[Throws:] [`boost::task::pool_moved`]] -] -[endsect] - -[section `void shutdown()`] -[variablelist -[[Effects:] [deactivates the queue and joins all worker-threads - the pool is closed]] -[[Throws:] [`boost::thread_interrupted`, `boost::system::system_error`, `boost::task::pool_moved`]] -[[Notes:] [all pending tasks are processed]] -] -[endsect] - -[section `void shutdown_now()`] -[variablelist -[[Effects:] [deactivates the queue, send interruption request to all worker-threads and joins them - the pool is closed]] -[[Throws:] [`boost::thread_interrupted`, `boost::system::system_error`, `boost::task::pool_moved`]] -[[Notes:] [pending tasks are not processed but returned]] -] -[endsect] - -[section `void interrupt_all_worker()`] -[variablelist -[[Effects:] [interrupts all worker-threads without invalidating the pool]] -[[Throws:] [nothing]] -] -[endsect] - -[section `bool closed()`] -[variablelist -[[Effects:] [queries if the pool is closed (pool is shutdown)]] -[[Throws:] [`boost::task::pool_moved`]] -] -[endsect] - -[section `std::size_t upper_bound()`] -[variablelist -[[Preconditions:] [queue is of type bounded-queue]] -[[Effects:] [returns the upper bound of the bounded-queue]] -[[Throws:] [`boost::task::pool_moved`]] -[[Notes:] [can only be used if a bounded-queue is used]] -] -[endsect] - -[section `void upper_bound( high_watermark const& hwm)`] -[variablelist -[[Preconditions:] [queue is of type bounded-queue]] -[[Effects:] [sets the upper bound of the bounded-queue]] -[[Postconditions:] [`this->upper_bound() == hwm`]] -[[Throws:] [`boost::task::invalid_watermark`, `boost::task::pool_moved`]] -[[Notes:] [can only be used if a bounded-queue is used]] -] -[endsect] - -[section `std::size_t lower_bound()`] -[variablelist -[[Preconditions:] [queue is of type bounded-queue]] -[[Effects:] [returns the lower bound of the bounded-queue]] -[[Throws:] [`boost::task::pool_moved`]] -[[Notes:] [can only be used if a bounded-queue is used]] -] -[endsect] - -[section `void lower_bound( low_watermark const& lwm)`] -[variablelist -[[Preconditions:] [queue is of type bounded-queue]] -[[Effects:] [sets the lower bound of the bounded-queue]] -[[Postconditions:] [`this->lower_bound() == lwm`]] -[[Throws:] [`boost::task::invalid_watermark`, `boost::task::pool_moved`]] -[[Notes:] [can only be used if a bounded-queue is used]] -] -[endsect] - -[section `template< typename R > handle< R > submit( task< R > t)`] -[variablelist -[[Preconditions:] [has_attribute< pool >::value == false && ! closed()]] -[[Effects:] [moves an task to the pool and returns an associated handle]] -[[Throws:] [`boost::task::task_rejected`, `boost::task::pool_moved`]] -] -[endsect] - -[section `template< typename R, typename Attr > handle< R > submit( task< R > t, Attr const& attr)`] -[variablelist -[[Preconditions:] [has_attribute< pool >::value == true && ! closed()]] -[[Effects:] [moves an task to the pool and returns an associated handle - task is scheduled by the attribute]] -[[Throws:] [`boost::task::task_rejected`, `boost::task::pool_moved`]] -] -[endsect] - -[section `void swap( static_pool & other)`] -[variablelist -[[Effects:] [swaps pool]] -[[Throws:] [nothing]] -] -[endsect] - -[section `operator unspecified_bool_type() const`] -[variablelist -[[Effects:] [is static_pool valid == does static_pool own ownership]] -[[Throws:] [Nothing]] -] -[endsect] - -[section `bool operator!() const`] -[variablelist -[[Effects:] [is static_pool invalid == static_pool does not have ownership]] -[[Throws:] [Nothing]] -] -[endsect] - -[endsect] - -[endsect] - diff --git a/libs/task/doc/task.qbk b/libs/task/doc/task.qbk deleted file mode 100644 index 8f47904d..00000000 --- a/libs/task/doc/task.qbk +++ /dev/null @@ -1,126 +0,0 @@ -[/ - Copyright Oliver Kowalke 2009. - Distributed under the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt -] - -[article Task - [quickbook 1.4] - [authors [Kowalke, Oliver]] - [copyright 2009 Oliver Kowalke] - [purpose C++ Library for asynchronous execution of tasks] - [category text] - [license - Distributed under the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or copy at - [@http://www.boost.org/LICENSE_1_0.txt]) - ] -] - - -[def __boost_atomic__ [@http://www.chaoticmind.net/~hcb/projects/boost.atomic [*Boost.Atomic]]] -[def __boost_tasklet__ [@http://http://www.boostpro.com/vault/index.php?&direction=0&order=&directory=Concurrent%20Programming [*Boost.Tasklet]]] -[def __boost_move__ [@http://svn.boost.org/svn/boost/sandbox/move [*Boost.Move]]] -[def __boost_task__ [*Boost.Task]] -[def __boost_thread__ [@http://www.boost.org/libs/thread [*Boost.Thread]]] - -[template link_act[link_text] [link task.async_execution.async_completion_token [link_text]]] -[template link_as_subtask[link_text] [link task.async_execution.execution_policy.as_subtask [link_text]]] -[template link_async[link_text] [link task.async_execution.async [link_text]]] -[template link_ep[link_text] [link task.async_execution.execution_policy [link_text]]] -[template link_forkjoin[link_text] [link task.async_execution.execution_policy.threadpool.forkjoin [link_text]]] -[template link_handle[link_text] [link task.async_execution.async_completion_token.handle [link_text]]] -[template link_new_thread[link_text] [link task.async_execution.execution_policy.new_thread [link_text]]] -[template link_own_thread[link_text] [link task.async_execution.execution_policy.own_thread [link_text]]] -[template link_queue[link_text] [link task.async_execution.execution_policy.threadpool.queue [link_text]]] -[template link_task[link_text] [link task.task_management.task [link_text]]] -[template link_threadpool[link_text] [link task.async_execution.execution_policy.threadpool [link_text]]] -[template link_work_stealing[link_text] [link task.async_execution.execution_policy.threadpool.workstealing [link_text]]] - -[def __hardware_concurrency__ `boost::thread::hardware_concurrency()`] - -[def __as_sub_task__ `boost::tasks::as_sub_task`] -[def __attribute_type__ `boost::tasks::attribute_type`] -[def __bounded_queue__ `boost::tasks::bounded_queue`] -[def __dynamic_pool__ `boost::tasks::dynamic_pool`] -[def __has_attribute__ `boost::tasks::has_attribute`] -[def __hwm__ `boost::tasks::high_watermark`] -[def __lwm__ `boost::tasks::low_watermark`] -[def __pool_size__ `boost::tasks::poolsize`] -[def __priority__ `boost::tasks::priority`] -[def __replace_oldest__ `boost::tasks::replace_oldest`] -[def __static_pool__ `boost::tasks::static_pool`] -[def __system_time__ `boost::tasks::system_time`] -[def __take_oldest__ `boost::tasks::take_oldest`] -[def __task_interrupted__ `boost::tasks::task_interrupted`] -[def __unbounded_queue__ `boost::tasks::unbounded_queue`] - -[def __make_task__ `boost::tasks::make_task()`] -[def __waitfor_all__ `boost::tasks::waitfor_all()`] - -[def __fn_tt_interrupt__ `boost::this_task::interrupt()`] -[def __fn_interruption_requested__ `boost::this_thread::interruption_requested()`] -[def __fn_make_task__ `boost::tasks::make_task()`] -[def __fn_runs_in_pool__ `boost::this_task::runs_in_pool()`] -[def __fn_worker_id__ `boost::this_task::worker_id()`] -[def __fn_yield__ `boost::this_task::yield()`] - -[def __fn_async__ `boost::tasks::async()`] -[def __fn_make_task__ `boost::tasks::make_task()`] - -[def __fn_bind_to_processors__ `bind_to_processors()`] -[def __fn_closed__ `close()`] -[def __fn_get__ `get()`] -[def __fn_has_value__ `has_value()`] -[def __fn_has_exception__ `has_exception()`] -[def __fn_interrupt__ `interrupt()`] -[def __fn_interrupt_and_wait__ `interrupt_and_wait()`] -[def __fn_interrupt_and_wait_for__ `interrupt_and_wait_for()`] -[def __fn_interrupt_and_wait_until__ `interrupt_and_wait_until()`] -[def __fn_interruption_requested__ `interruption_requested()`] -[def __fn_is_ready__ `is_ready()`] -[def __fn_operator__ `operator()()`] -[def __fn_size__ `size()`] -[def __fn_shutdown__ `shutdown()`] -[def __fn_shutdown_now__ `shutdown_now()`] -[def __fn_wait__ `wait()`] -[def __fn_wait_for__ `wait_for()`] -[def __fn_wait_until__ `wait_until()`] - - -[def __act__ [link_act ['asynchronous-completion-token]]] -[def __async__ [link_async ['async()]]] -[def __ep__ [link_ep ['execution-policy]]] -[def __eps__ [link_ep ['execution-policies]]] -[def __blocked__ ['blocked]] -[def __callable__ ['callable]] -[def __coop_task__ ['cooperative task]] -[def __duration__ ['Duration]] -[def __fork_join__ [link_forkjoin ['fork/join]]] -[def __handle__ [link_handle ['handle]]] -[def __interruption_point__ ['interruption-point]] -[def __interruption_points__ ['interruption-points]] -[def __new_thread__ [link_new_thread ['new_thread]]] -[def __own_thread__ [link_own_thread ['own_thread]]] -[def __queue__ [link_queue ['queue]]] -[def __task__ [link_task ['task]]] -[def __thread_pool__ [link_threadpool ['thread-pool]]] -[def __thread_pools__ [link_threadpool ['thread-pools]]] -[def __sub_task__ ['sub-task]] -[def __sub_tasks__ ['sub-tasks]] -[def __work_item__ ['work-item]] -[def __work_items__ ['work-items]] -[def __work_stealing__ [link_work_stealing ['work-stealing]]] -[def __worker_queue__ ['worker-queue]] -[def __worker_thread__ ['worker-thread]] -[def __worker_threads__ ['worker-threads]] - - - -[include overview.qbk] -[include task_ref.qbk] -[include async_execution.qbk] -[include spin_synchronization.qbk] -[include todo.qbk] -[include acknowledgements.qbk] diff --git a/libs/task/doc/task_ref.qbk b/libs/task/doc/task_ref.qbk deleted file mode 100644 index 97459a10..00000000 --- a/libs/task/doc/task_ref.qbk +++ /dev/null @@ -1,407 +0,0 @@ -[/ - Copyright Oliver Kowalke 2009. - Distributed under the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt -] - - -[section:task_management Task Management] - -[heading Synopsis] - -A task is a chunk of code that can be executed independently and parallel. - -__task__ represents a __callable__ (provides __fn_operator__) object containing -the unit of code to be execute by a __ep__. Function __fn_async__ accepts a -__task__ and an __ep__ and returns a __act__ allowing to wait for the completion -of the computation of the task, for getting the result of a computation or for -transfering exceptions. -Objects of type __task__ are moveable. - - boost::task< int > t1( parallel_fib, 10); - boost::task< int > t2; // not-a-task - t2 = boost::move( t1); - - -[heading Launching] - -A new task is launched by passing an object of a callable type that can be invoked with no parameters to the -constructor and passing the task to function __fn_async__. The object is then copied into internal storage -of the __ep__, and invoked on the newly created task. - - struct callable - { void operator()(); }; - - boost::task copies_are_safe() - { - callable x; - return boost::task( x); - } // x is destroyed, but the newly-created task has a copy, so this is OK - - boost::task oops() - { - callable x; - return boost::task( boost::ref( x) ); - } // x is destroyed, but the newly-created task still has a reference - // this leads to undefined behaviour - -If you wish to construct an instance of __task__ with a function or callable object that requires arguments to be -supplied, this can be done by passing additional arguments to the __task__ constructor: - - void find_the_question( int the_answer); - - boost::task deep_thought_2( find_the_question, 42); - - // asynchr. execution - boost::tasks::async( boost::move( depp_thought_2) ); - -The arguments are ['copied] into the internal task structure: if a reference is required, use `boost::ref`, just as -for references to callable functions. - -For convinience `boost::tasks::make_task()` is provided: - - // asynchr. execution - boost::tasks::async( - boost::move( boost::tasks::make_task( find_the_question, 42) ), - boost::tasks::new_thread() ); - - -[heading Completion] - -In order to wait for the completion `boost::tasks::handle< R >::wait()` as to be called -on the __handle__ associated with the task. The fucntion returns if the task has completed. -The result of the task can be accessed via `boost::tasks::handle< R >::get()`. - - -[heading Interruption] - -Sometimes it is desired to stop a running task if it is no longer needed. In this case the thread is not killed - it -stops only at well-defined points (__interruption_points__) its execution. -A task can be ['interrupted] by invoking the __fn_interrupt__ member function from __act__ . When the interrupted -task next executes one of the specified __interruption_points__ (or if it is currently __blocked__ whilst executing -one) with interruption enabled, then a __task_interrupted__ exception will be thrown in the interrupted task. -In the context of ['task-interruption] a task is known as cooperative if it checks for an interruption request between -two __interruption_points__ via __fn_interruption_requested__ [footnote see [@http://www.ddj.com/architect/207100682 -'Interrupt Politely'], Herb Sutter]. - - -[heading Predefined Interruption Points] - -The following functions are ['interruption points], which will throw __task_interrupted__ if interruption is -enabled for the current tasklet, and interruption is requested for the current tasklet: - -* `boost::thread::join()` -* `boost::thread::timed_join()` -* `boost::condition_variable::wait()` -* `boost::condition_variable::timed_wait()` -* `boost::condition_variable_any::wait()` -* `boost::condition_variable_any::timed_wait()` -* `boost::tasks::spin::condition::wait()` -* `boost::tasks::spin::condition::timed_wait()` -* `boost::tasks::spin::auto_reset_event::wait()` -* `boost::tasks::spin::auto_reset_event::timed_wait()` -* `boost::tasks::spin::manual_reset_event::wait()` -* `boost::tasks::spin::manual_reset_event::timed_wait()` -* `boost::tasks::spin::count_down_event::wait()` -* `boost::tasks::spin::count_down_event::timed_wait()` -* `boost::thread::sleep()` -* `boost::this_thread::sleep()` -* `boost::this_thread::interruption_point()` - -A __interruption_point__ throws __task_interrupted__ if an interruption was requested. - - long cooperative( long n) - { - // interruption point - boost::this_thread::interruption_point(); - - if ( n == 0) return 0; - if ( n == 1) return 1; - long k1( 1), k2( 0); - for ( int i( 2); i <= n; ++i) - { - // check if interruption was requested - if ( boost::this_thread::interruption_requested() ) - return; - - long tmp( k1); - k1 = k1 + k2; - k2 = tmp; - } - - // interruption point - boost::this_thread::interruption_point(); - - return k1; - } - - void main() - { - // task for computing fibonacci-number - boost::task< long > t( cooperative, 10) ); - - // execute task in new thread - // move task ownership to executor - boost::tasks::handle< long > h( - boost::tasks::async( - boost::move( t), - boost::tasks::new_thread() ) ); - - // interrupt task an wait until - // the task is removed by the worker-thread - h.interrupt_and_wait(); - - // access the result - // throws boost::task_interrupted - std::cout << "fibonacci(10) == " << h.get() << std::endl; - } - -If a task wishes to avoid being interrupted, it can create an instance of `boost::disable_interruption`. -The effects of an instance of `boost::disable_interruption` can be temporarily reversed by constructing an instance of -`boost::restore_interruption`, passing in the `boost::disable_interruption` object in question. This will restore the -interruption state to what it was when the `boost::disable_interruption` object was constructed, and then disable -interruption again when the `boost::restore_interruption` object is destroyed. - - -[heading Exceptions] - -Exceptions thrown by the function or callable object passed to the __task__ constructor are consumed by the thes -associated __act__. The exception will be re-thrown by the associated __handle__. - - void throwing() - { - ... - throw std::domain_error("domain error"); - ... - } - - void main() - { - // create task throwing std::domain_error - boost::task void > t( throwing); - - // execute task asynchron - // move task ownership to executor - boost::tasks::handle< void > h( - boost::tasks::async( - boost::move( t), - boost::tasks::new_thread() ) ); - - // wait for task completion - // throws std::domain_error - std::cout << h.wait() << std::endl; - } - -Exceptions rethrown by type are: - -* `std::bad_alloc` -* `std::bad_cast` -* `std::bad_exception` -* `std::bad_typeid` -* `std::domain_error` -* `std::invalid_argument` -* `std::ios_base::failure` -* `std::length_error` -* `std::logic_error` -* `std::out_of_range` -* `std::overflow_error` -* `std::range_error` -* `std::runtime_error` -* `std::underflow_error` -* `boost::exception` -* `boost::future_already_set` -* `boost::future_cancel` -* `boost::invalid_thread_argument` -* `boost::lock_error` -* `boost::broken_task` -* `boost::pool_moved` -* `boost::task_already_executed` -* `boost::task_interrupted` -* `boost::task_moved` -* `boost::task_interrupted` -* `boost::task_task_rejected` -* `boost::task_unitialized` - -[warning Don't use the sjlj exception model.] - - -[heading Parent Task] - -Top-level tasks have no parent. A parent task can create child tasks when it creates another task by using -__as_sub_task__ as __ep__. These children are implicitly treated as __sub_tasks__ of the parent task. It is -assumed that that __sub_tasks__ can be executed in any order because only overall operation speed matters -(enabling strategies for fast execution of unordered __work_items__ as [link_work_stealing __work_stealing__]). - - long serial_fib( long n) - { - if( n < 2) return n; - else return serial_fib( n - 1) + serial_fib( n - 2); - } - - long parallel_fib( long n, long cutof) - { - if ( n < cutof) return serial_fib( n); - else - { - // sub-task for computing fibonacci(n-1) - boost::task< long > t1( - parallel_fib, - n - 1, - cutof); - // sub-task for computing fibonacci(n-2) - boost::task< long > t2( - parallel_fib, - n - 2, - cutof); - - // submit a sub-tasks to thread-pool - // move task ownership to executor - boost::tasks::handle< long > h1( - boost::tasks::async( - boost::move( t1) ); - boost::tasks::handle< long > h2( - boost::tasks::async( - boost::move( t2) ); - - // computing fibonacci(n) by - // joining results of both sub-tasks - return h1.get() + h2.get(); - } - } - - void main() - { - // create thread-pool with five worker-threads - boost::tasks::static_pool< boost::tasks::unbounded_fifo > pool( boost::tasks::poolsize( 5) ); - - // create task computing fibonacci-number for 10 - boost::task< long > t( - parallel_fib, - 10, - 5); - - // execute task asynchron in thread-pool - // move task ownership to executor - boost::tasks::handle< long > h( - boost::tasks::async( - boost::move( t), - pool) ); - - // access result - std::cout << "fibonacci(10) == " << h.get() << std::endl; - } - - -[section:task Class template `task`] - - #include - - template< typename R > - class task : private noncopyable - { - public: - task(); - - task( R( * fn)()); - - template< typename Fn > - task( Fn fn); - - template< typename Fn, typename A0, ... > - task( Fn fn, A0 a0, ...); - - task( task && x); - task & operator=( task && x); - - void operator()(); - - void swap( task< R > & other); - - operator unspecified_bool_type() const; - bool operator!() const; - }; - - template< typename Fn > - task< R > make_task( Fn fn); - template< typename Fn, typename A0, ... > - task< R > make_task( Fn fn, A0 a0, ...); - - -[section:default_constructor `task()`] -[variablelist -[[Effects:] [constructs a __task__ instance that refers to __not_a_task__.]] -[[Throws:] [Nothing]] -] -[endsect] - -[section:constructor `task( R( * fn)())`] -[variablelist -[[Effects:] [constructs a __task__ from a function pointer]] -[[Throws:] [Nothing]] -] -[endsect] - -[section:constructor_2 `template< typename Fn > task( Fn const& fn)`] -[variablelist -[[Effects:] [constructs a __task__ from a function object]] -[[Throws:] [Nothing]] -] -[endsect] - -[section:multi_argument_constructor `template< typename Fn, typename A0, ... > task( Fn fn, A0 a0, ...)`] -[variablelist -[[Effects:] [constructs a `boost::task::task< R >` from a function object and its arguments]] -[[Throws:] [Nothing]] -] -[endsect] - -[section:operator `operator()()`] -[variablelist -[[Effects:] [executes task's internal function object]] -[[Throws:] [Nothing]] -] -[endsect] - -[section:swap `swap( task< R > & other)`] -[variablelist -[[Effects:] [Exchanges the tasks associated with `*this` and `other`, so `*this` is associated with the task -associated with `other` prior to the call, and vice-versa.]] -[[Throws:] [Nothing]] -] -[endsect] - -[section:unspec_operator `operator unspecified_bool_type() const`] -[variablelist -[[Returns:] [If `*this` refers to a task, the function returns true. Otherwise false.]] -[[Throws:] [Nothing]] -] -[endsect] - -[section:not_operator `operator!()`] -[variablelist -[[Returns:] [If `*this` refers not to a task, the function returns true. Otherwise false.]] -[[Throws:] [Nothing]] -] -[endsect] - -[section:non_member_make_task Non-member template function `make_task()`] - - #include - - template< typename Fn > - tasklet make_task( Fn fn); - - template< typename Fn, typename A0, ... > - tasklet make_task( Fn fn, A0 a0, ..., std::size_t stack_size); - -[variablelist -[[Effects:] [Creates a task.]] -] -[endsect] - -[endsect] - -[include this_task.qbk] - -[endsect] diff --git a/libs/task/doc/this_task.qbk b/libs/task/doc/this_task.qbk deleted file mode 100644 index ae1309ee..00000000 --- a/libs/task/doc/this_task.qbk +++ /dev/null @@ -1,63 +0,0 @@ -[/ - Copyright Oliver Kowalke 2009. - Distributed under the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt -] - -[section:this_task Namespace `this_task`] - -[heading Synopsis] - -The non-member function in namespace `this_task` provide functionality to ['yield] the current task or -test if the task is executed inside a __thread_pool__. - -[section:block Non-member function `yield()`] - - #include - - namespace this_task - { - void yield() - } - -[variablelist -[[Effects:] [Blocks the current task and lets the worker-thread of the pool process another task. -The blocked task will be scheduled and return from this method.]] -[[Throws:] [nothing]] -] -[endsect] - -[section:runs_in_pool Non-member function `runs_in_pool()`] - - #include - - namespace this_task - { - bool runs_in_pool() - } - -[variablelist -[[Effects:] [Returns true if the current task is executed in a thread-pool.]] -[[Throws:] [nothing]] -[[Note:] [this function resides in namespace `boost::this_task`]] -] -[endsect] - - -[section:worker_id Non-member function `worker_id()`] - - #include - - namespace this_task - { - id worker_id() - } - -[variablelist -[[Effects:] [Returns returns the thread-id of the worker-thread form the thread-pool.]] -[[Throws:] [nothing]] -] -[endsect] - -[endsect] diff --git a/libs/task/doc/threadpool.qbk b/libs/task/doc/threadpool.qbk deleted file mode 100644 index 778412f0..00000000 --- a/libs/task/doc/threadpool.qbk +++ /dev/null @@ -1,63 +0,0 @@ -[/ - Copyright Oliver Kowalke 2009. - Distributed under the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt -] - - -[section:threadpool Execute in Thread-Pool] - -[heading Synopsis] - -Instead of creating a new thread and quickly throwing it away after the task is done, the overhead related to thread -creation and destruction can be avoided by running the __work_items__ on a __thread_pool__ (reusing an existing -__worker_thread__ instead). - -A __thread_pool__ maintains a global queue of __work_items__ to be processed, and a pool of __worker_threads__ which execute __work_items__ from the global queue. - -__boost_task__ provides __fn_async__ with support of executing an __task__ in __thread_pool__: - - - std::string echo( std::string const& msg) - { return msg; } - - void main() - { - // create a thread-pool with - // five worker-threads - // FIFO schduling of queued tasks - // and unlimited size of internal queue - boost::tasks::static_pool< boost::tasks::unbounded_fifo > pool( boost::tasks::poolsize( 5) ); - - // create task - boost::tasks::task< std::string > t( echo, "Hello World!"); - - // move task to executor - // let the task be executed by the thread-pool - boost::tasks::handle< std::string > h( - boost::tasks::async( - boost::move( t), - pool) ); - - // access the result - std::cout << h.get() << std::endl; - } - - -[important Tasks should not be too small (performance overhead dominates) and avoid blocking -tasks[footnote see [@http://www.ddj.com/go-parallel/article/showArticle.jhtml?articleID=216500409 -'Use Thread Pools Correctly'], Herb Sutter].] - - -[include static_pool.qbk] -[include meta_functions.qbk] -[include queue.qbk] -[include shutdown.qbk] -[include processor_binding.qbk] -[include work_stealing.qbk] -[include fork_join.qbk] - - -[endsect] - diff --git a/libs/task/doc/todo.qbk b/libs/task/doc/todo.qbk deleted file mode 100644 index 1faaa021..00000000 --- a/libs/task/doc/todo.qbk +++ /dev/null @@ -1,22 +0,0 @@ -[/ - Copyright Oliver Kowalke 2009. - Distributed under the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt -] - - -[section:todo Todo] - -* optimize memory ordering in atomic ops. - -* replace thread_specific_ptr by an specialiced implementation for `boost::tasks::detail::worker` - -* __dynamic_pool__ adds or removes __worker_threads__ from the __thread_pool__ - depending on the work-load (undersubscription/oversubscription). - -* task group defines a graph of interdependent tasks that can mostly be run in - parallel. The tasks in the group have dependencies or communicate with each - other. - -[endsect] diff --git a/libs/task/doc/work_stealing.qbk b/libs/task/doc/work_stealing.qbk deleted file mode 100644 index e16d685d..00000000 --- a/libs/task/doc/work_stealing.qbk +++ /dev/null @@ -1,50 +0,0 @@ -[/ - Copyright Oliver Kowalke 2009. - Distributed under the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt -] - - -[section:workstealing Work-Stealing] - -Traditional __thread_pools__ do not scale because they use a single global-queue protected by a global-lock. The frequency at which -__worker_threads__ aquire the global-lock becomes a limiting factor for the throughput if: - -* the tasks become smaller - -* more processors are added - - -A __work_stealing__ algorithm can be used to solve this problem. It uses a special kind of queue which has two ends, and allows -lock-free pushes and pops from the ['private end] (accessed by the __worker_thread__ owning the queue), but requires synchronization -from the ['public end] (accessed by the other __worker_threads__). Synchronization is necessary when the queue is sufficiently small -that private and public operations could conflict. - -The pool contains one global-queue (__bounded_queue__ or __unbounded_queue__) protected by a global-lock and each __worker_thread__ -has its own private local worker-queue. If work is enqueued by a __worker_thread__ the __task__ is stored in the worker queue. If the -work is enqueued by a application thread it goes into the global queue. When __worker_threads__ are looking for work, they have -following search order: - -* look into the private worker-queue - tasks can be dequeued without locks - -* look in the global-queue - locks are used for synchronization - -* check other worker-queues ('stealing' tasks from private worker queues of other __worker_threads__) - requires locks - - -For a lot of recursively queued tasks (so called __sub_tasks__), the use of a worker-queue per thread substantially reduces the -synchronization necessary to complete the work. There are also fewer cache effects due to sharing of the global-queue information. - -Operations on the private worker queue are executed in LIFO order and operations on worker queues of other __worker_threads__ in -FIFO order (steals). - -* There are chances that memory is still hot in the cache, if the tasks are pushed in LIFO order into the private worker queue. - -* If a __worker_thread__ steals work in FIFO order, increases the chances that a larger 'chunk' of work will be stolen (the need -for other steals will be possibly reduced). Because the __sub_tasks__ are stored in LIFO order, the oldest items are closer to the -['public end] of the queue (forming a tree). Stealing such an older __task__ also steals a (probably) larger subtree of tasks -unfolded if the stolen work item get executed. Since a __sub_task__ is just part of a larger __task__, we don’t need to worry about -execution order. - -[endsect] diff --git a/libs/task/examples/Jamfile.v2 b/libs/task/examples/Jamfile.v2 deleted file mode 100644 index 28fa38c6..00000000 --- a/libs/task/examples/Jamfile.v2 +++ /dev/null @@ -1,37 +0,0 @@ -# Boost.Task Library Examples Jamfile - -# Copyright Oliver Kowalke 2009. -# Distributed under the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) - -# For more information, see http://www.boost.org/ - -import os ; - -if [ os.name ] = SOLARIS -{ - lib socket ; -} - -project boost/task/example - : requirements - ../../tasklet/build//boost_tasklet - ../../thread/build//boost_thread - ../../system/build//boost_system - ../build//boost_task - static - multi - SOLARIS:socket - ; - -exe bind_to_processors : bind_to_processors.cpp ; -exe interrupt : interrupt.cpp ; -exe priority : priority.cpp ; -exe shutdown_now : shutdown_now.cpp ; -exe smart : smart.cpp ; -exe submit : submit.cpp ; -exe sub_tasks : sub_tasks.cpp ; -exe sync/fork_join_event : sync/fork_join_event.cpp ; -exe sync/message_passing : sync/message_passing.cpp ; -exe sync/ping_pong : sync/ping_pong.cpp ; diff --git a/libs/task/examples/bind_to_processors.cpp b/libs/task/examples/bind_to_processors.cpp deleted file mode 100644 index e85aac08..00000000 --- a/libs/task/examples/bind_to_processors.cpp +++ /dev/null @@ -1,116 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include -#include -#include - -#include -#include -#include - -#include "boost/task.hpp" - -namespace pt = boost::posix_time; -namespace tsk = boost::tasks; - -typedef tsk::static_pool< tsk::unbounded_fifo > pool_type; - -int serial_fib( int n) -{ - if( n < 2) - return n; - else - return serial_fib( n - 1) + serial_fib( n - 2); -} - -int parallel_fib( int n, int cutof) -{ - if ( n < cutof) - { - return serial_fib( n); - } - else - { - BOOST_ASSERT( boost::this_task::runs_in_pool() ); - tsk::handle< int > h1( - tsk::async( - tsk::make_task( - parallel_fib, - n - 1, - cutof), - tsk::as_sub_task() ) ); - tsk::handle< int > h2( - tsk::async( - tsk::make_task( - parallel_fib, - n - 2, - cutof), - tsk::as_sub_task() ) ); - return h1.get() + h2.get(); - } -} - -int main( int argc, char *argv[]) -{ -# if defined(BOOST_HAS_PROCESSOR_BINDINGS) - try - { - pool_type pool( pool_type::bind_to_processors() ); - - std::vector< tsk::handle< int > > results; - results.reserve( 10); - - pt::ptime start = pt::microsec_clock::universal_time(); - -// for ( int i = 0; i < 15; ++i) -// results.push_back( -// tsk::async( -// tsk::make_task( -// parallel_fib, -// 10, -// 5), -// pool) ); -// - - results.push_back( - tsk::async( - tsk::make_task( - parallel_fib, - 25, - 5), - pool) ); - - tsk::waitfor_all( results.begin(), results.end() ); - - pt::ptime stop = pt::microsec_clock::universal_time(); - - pt::time_duration elapsed = stop - start; - std::cout << "total microseconds == " << elapsed.total_microseconds() << std::endl; - std::cout << "total milliseconds == " << elapsed.total_milliseconds() << std::endl; - - int k = 0; - std::vector< tsk::handle< int > >::iterator e( results.end() ); - for ( - std::vector< tsk::handle< int > >::iterator i( results.begin() ); - i != e; - ++i) - std::cout << "fibonacci(" << k++ << ") == " << i->get() << std::endl; - - return EXIT_SUCCESS; - } - catch ( std::exception const& e) - { std::cerr << "exception: " << e.what() << std::endl; } - catch ( ... ) - { std::cerr << "unhandled" << std::endl; } - -# endif - - return EXIT_FAILURE; -} - - diff --git a/libs/task/examples/interrupt.cpp b/libs/task/examples/interrupt.cpp deleted file mode 100644 index 36590dcf..00000000 --- a/libs/task/examples/interrupt.cpp +++ /dev/null @@ -1,70 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include -#include -#include - -#include -#include - -#include "boost/task.hpp" - -namespace pt = boost::posix_time; -namespace tsk = boost::tasks; - -typedef tsk::static_pool< tsk::unbounded_fifo > pool_type; - -inline -int fibonacci_fn( int n) -{ - if ( n == 0) return 0; - if ( n == 1) return 1; - int k1( 1), k2( 0); - for ( int i( 2); i <= n; ++i) - { - boost::this_thread::interruption_point(); - int tmp( k1); - k1 = k1 + k2; - k2 = tmp; - } - boost::this_thread::interruption_point(); - return k1; -} - -inline -void long_running_fn() -{ boost::this_thread::sleep( pt::seconds( 1) ); } - -int main( int argc, char *argv[]) -{ - try - { - pool_type pool( tsk::poolsize( 5) ); - - tsk::async( - tsk::make_task( long_running_fn), - pool); - std::cout << "poolsize == " << pool.size() << std::endl; - tsk::handle< int > h( - tsk::async( - tsk::make_task( fibonacci_fn, 10), - pool) ); - h.interrupt(); - std::cout << h.get() << std::endl; - - return EXIT_SUCCESS; - } - catch ( tsk::task_interrupted const& ) - { std::cerr << "task_interrupted: task was interrupted" << std::endl; } - catch ( std::exception const& e) - { std::cerr << "exception: " << e.what() << std::endl; } - catch ( ... ) - { std::cerr << "unhandled" << std::endl; } - - return EXIT_FAILURE; -} diff --git a/libs/task/examples/priority.cpp b/libs/task/examples/priority.cpp deleted file mode 100644 index d83f4d06..00000000 --- a/libs/task/examples/priority.cpp +++ /dev/null @@ -1,64 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include -#include -#include - -#include -#include - -#include "boost/task.hpp" - -namespace pt = boost::posix_time; -namespace tsk = boost::tasks; - -inline -void print_fn( std::string const& msg) -{ printf("%s", msg.c_str() ); } - -inline -void long_running_fn() -{ boost::this_thread::sleep( pt::milliseconds( 250) ); } - -int main( int argc, char *argv[]) -{ - try - { - tsk::static_pool< tsk::unbounded_prio_queue< int > > pool( tsk::poolsize( 1) ); - - tsk::task< void > t1( long_running_fn); - tsk::task< void > t2( print_fn, "a text.\n"); - tsk::task< void > t3( print_fn, " is "); - tsk::task< void > t4( print_fn, "This"); - - tsk::async( - boost::move( t1), - 3, - pool); - tsk::async( - boost::move( t2), - 0, - pool); - tsk::async( - boost::move( t3), - 1, - pool); - tsk::async( - boost::move( t4), - 2, - pool); - - return EXIT_SUCCESS; - } - catch ( std::exception const& e) - { std::cerr << "exception: " << e.what() << std::endl; } - catch ( ... ) - { std::cerr << "unhandled" << std::endl; } - - return EXIT_FAILURE; -} diff --git a/libs/task/examples/shutdown_now.cpp b/libs/task/examples/shutdown_now.cpp deleted file mode 100644 index 78429d27..00000000 --- a/libs/task/examples/shutdown_now.cpp +++ /dev/null @@ -1,68 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include -#include -#include - -#include -#include -#include - -#include "boost/task.hpp" - -namespace pt = boost::posix_time; -namespace tsk = boost::tasks; - -inline -int fibonacci_fn( int n) -{ - boost::this_thread::sleep( pt::milliseconds( 500) ); - if ( n == 0) return 0; - if ( n == 1) return 1; - int k1( 1), k2( 0); - for ( int i( 2); i <= n; ++i) - { - boost::this_thread::interruption_point(); - int tmp( k1); - k1 = k1 + k2; - k2 = tmp; - } - boost::this_thread::interruption_point(); - return k1; -} - -int main( int argc, char *argv[]) -{ - try - { - tsk::static_pool< tsk::unbounded_fifo > pool( tsk::poolsize( 1) ); - - tsk::task< int > t( fibonacci_fn, 10); - - tsk::handle< int > h( - tsk::async( - boost::move( t), - pool) ); - - boost::this_thread::sleep( pt::milliseconds( 250) ); - - pool.shutdown_now(); - - std::cout << h.get() << std::endl; - - return EXIT_SUCCESS; - } - catch ( tsk::task_interrupted const& ) - { std::cerr << "task_interrupted: task was interrupted" << std::endl; } - catch ( std::exception const& e) - { std::cerr << "exception: " << e.what() << std::endl; } - catch ( ... ) - { std::cerr << "unhandled" << std::endl; } - - return EXIT_FAILURE; -} diff --git a/libs/task/examples/smart.cpp b/libs/task/examples/smart.cpp deleted file mode 100644 index 3cd777e2..00000000 --- a/libs/task/examples/smart.cpp +++ /dev/null @@ -1,88 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include -#include -#include - -#include -#include - -#include "boost/task.hpp" - -namespace pt = boost::posix_time; -namespace tsk = boost::tasks; - -inline -void fibonacci_fn( int n) -{ - if ( n == 0) - { - printf("fibonacci(%d) == 0\n", n); - return; - } - if ( n == 1) - { - printf("fibonacci(%d) == 1\n", n); - return; - } - int k1( 1), k2( 0); - for ( int i( 2); i <= n; ++i) - { - int tmp( k1); - k1 = k1 + k2; - k2 = tmp; - } - printf("fibonacci(%d) == %d\n", n, k1); -} - -inline -void long_running_fn() -{ boost::this_thread::sleep( pt::milliseconds( 500) ); } - -int main( int argc, char *argv[]) -{ - try - { - tsk::static_pool< - tsk::unbounded_smart_queue< - int, - std::less< int > - > - > pool( tsk::poolsize( 1) ); - - tsk::task< void > t1( long_running_fn); - tsk::task< void > t2( fibonacci_fn, 0); - tsk::task< void > t3( fibonacci_fn, 1); - tsk::task< void > t4( fibonacci_fn, 10); - - tsk::async( - boost::move( t1), - 0, - pool); - tsk::async( - boost::move( t2), - 1, - pool); - tsk::async( - boost::move( t3), - 2, - pool); - tsk::async( - boost::move( t4), - 2, - pool); - - return EXIT_SUCCESS; - } - catch ( std::exception const& e) - { std::cerr << "exception: " << e.what() << std::endl; } - catch ( ... ) - { std::cerr << "unhandled" << std::endl; } - - return EXIT_FAILURE; -} diff --git a/libs/task/examples/sub_tasks.cpp b/libs/task/examples/sub_tasks.cpp deleted file mode 100755 index c6bc9d88..00000000 --- a/libs/task/examples/sub_tasks.cpp +++ /dev/null @@ -1,88 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include -#include -#include - -#include -#include -#include - -#include "boost/task.hpp" - -namespace pt = boost::posix_time; -namespace tsk = boost::tasks; - -typedef tsk::static_pool< tsk::unbounded_fifo > pool_type; - -int serial_fib( int n) -{ - if( n < 2) - return n; - else - return serial_fib( n - 1) + serial_fib( n - 2); -} - -int parallel_fib( int n, int cutof) -{ - if ( n < cutof) - { - return serial_fib( n); - } - else - { - BOOST_ASSERT( boost::this_task::runs_in_pool() ); - - tsk::handle< int > h1( - tsk::async( - tsk::make_task( - parallel_fib, - n - 1, - cutof), - tsk::as_sub_task() ) ); - - tsk::handle< int > h2( - tsk::async( - tsk::make_task( - parallel_fib, - n - 2, - cutof), - tsk::as_sub_task() ) ); - - return h1.get() + h2.get(); - } -} - -int main( int argc, char *argv[]) -{ - try - { - pool_type pool( tsk::poolsize( 5) ); - - int n = 10; - tsk::handle< int > h( - tsk::async( - tsk::make_task( - parallel_fib, - n, - 5), - pool) ); - - std::cout << "fibonacci(" << n << ") == " << h.get() << std::endl; - - return EXIT_SUCCESS; - } - catch ( std::exception const& e) - { std::cerr << "exception: " << e.what() << std::endl; } - catch ( ... ) - { std::cerr << "unhandled" << std::endl; } - - return EXIT_FAILURE; -} - - diff --git a/libs/task/examples/submit.cpp b/libs/task/examples/submit.cpp deleted file mode 100644 index 989b924a..00000000 --- a/libs/task/examples/submit.cpp +++ /dev/null @@ -1,75 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include -#include - -#include - -#include "boost/task.hpp" - -namespace tsk = boost::tasks; - -inline -int fibonacci_fn( int n) -{ - if ( n == 0) return 0; - if ( n == 1) return 1; - int k1( 1), k2( 0); - for ( int i( 2); i <= n; ++i) - { - boost::this_thread::interruption_point(); - int tmp( k1); - k1 = k1 + k2; - k2 = tmp; - } - boost::this_thread::interruption_point(); - return k1; -} - -int main( int argc, char *argv[]) -{ - try - { - tsk::static_pool< tsk::unbounded_prio_queue< int > > pool( tsk::poolsize( 3) ); - - tsk::task< int > t1( fibonacci_fn, 10); - tsk::task< int > t2( fibonacci_fn, 10); - tsk::task< int > t3( fibonacci_fn, 10); - tsk::task< int > t4( fibonacci_fn, 10); - - tsk::handle< int > h1( - tsk::async( boost::move( t1) ) ); - tsk::handle< int > h2( - tsk::async( - boost::move( t2), - tsk::new_thread() ) ); - tsk::handle< int > h3( - tsk::async( - boost::move( t3), - 2, - pool) ); - tsk::handle< int > h4( - tsk::async( - boost::move( t4), - 2, - pool) ); - - std::cout << h1.get() << std::endl; - std::cout << h2.get() << std::endl; - std::cout << h3.get() << std::endl; - std::cout << h4.get() << std::endl; - - return EXIT_SUCCESS; - } - catch ( std::exception const& e) - { std::cerr << "exception: " << e.what() << std::endl; } - catch ( ... ) - { std::cerr << "unhandled" << std::endl; } - - return EXIT_FAILURE; -} diff --git a/libs/task/examples/sync/fork_join_event.cpp b/libs/task/examples/sync/fork_join_event.cpp deleted file mode 100755 index 29ac937b..00000000 --- a/libs/task/examples/sync/fork_join_event.cpp +++ /dev/null @@ -1,87 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "boost/task.hpp" - -namespace tsk = boost::tasks; - -typedef tsk::static_pool< tsk::unbounded_fifo > pool_type; - -void sub_task( int i, int n, tsk::spin::count_down_event & ev) -{ - BOOST_ASSERT( boost::this_task::runs_in_pool() ); - - fprintf( stderr, "t%d running ...\n", i); - - ev.set(); - - fprintf( stderr, "t%d finished ...\n", i); -} - -void main_task( - pool_type & pool, - int n, - tsk::spin::count_down_event & outer_ev) -{ - BOOST_ASSERT( boost::this_task::runs_in_pool() ); - - fprintf( stderr, "main-task running %d sub-tasks\n", n); - - tsk::spin::count_down_event inner_ev( n); - - for ( int i = 0; i < n; ++i) - tsk::async( - tsk::make_task( - & sub_task, - i, - n, - boost::ref( inner_ev) ), - tsk::as_sub_task() ); - - inner_ev.wait(); - outer_ev.set(); -} - -int main( int argc, char *argv[]) -{ - try - { - tsk::poolsize psize( boost::thread::hardware_concurrency() ); - pool_type pool( psize); - - int n = 32; - tsk::spin::count_down_event ev( 1); - tsk::async( - tsk::make_task( - & main_task, - boost::ref( pool), - n, - boost::ref( ev) ), - pool); - - fprintf( stderr, "main thread: waiting for t0 to finish\n"); - ev.wait(); - fprintf( stderr, "main thread: t0 finished\n"); - - return EXIT_SUCCESS; - } - catch ( std::exception const& e) - { std::cerr << "exception: " << e.what() << std::endl; } - catch ( ... ) - { std::cerr << "unhandled" << std::endl; } - - return EXIT_FAILURE; -} diff --git a/libs/task/examples/sync/message_passing.cpp b/libs/task/examples/sync/message_passing.cpp deleted file mode 100755 index ca03596f..00000000 --- a/libs/task/examples/sync/message_passing.cpp +++ /dev/null @@ -1,113 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "boost/task.hpp" - -namespace tsk = boost::tasks; - -typedef tsk::static_pool< tsk::unbounded_fifo > pool_type; - -int serial_fib( int n) -{ - if( n < 2) - return n; - else - return serial_fib( n - 1) + serial_fib( n - 2); -} - -int parallel_fib( int n, int cutof) -{ - if ( n < cutof) return serial_fib( n); - else - { - BOOST_ASSERT( boost::this_task::runs_in_pool() ); - tsk::task< int > t1( - parallel_fib, - n - 1, - cutof); - tsk::task< int > t2( - parallel_fib, - n - 2, - cutof); - tsk::handle< int > h1( - tsk::async( - boost::move( t1), - tsk::as_sub_task() ) ) ; - tsk::handle< int > h2( - tsk::async( - boost::move( t2), - tsk::as_sub_task() ) ); - return h1.get() + h2.get(); - } -} - -inline -void submit( - tsk::spin::unbounded_channel< int > & send, - tsk::spin::unbounded_channel< std::pair< int , int > > & recv, - int n) -{ - for ( int i = 0; i <= n; ++i) - send.put( i); - send.deactivate(); - boost::optional< std::pair< int , int > > r; - while ( recv.take( r) ) - { - BOOST_ASSERT( r); - printf("fib(%d) == %d\n", r->first, r->second); - } -} - -inline -void calculate( - tsk::spin::unbounded_channel< int > & recv, - tsk::spin::unbounded_channel< std::pair< int , int > > & send) -{ - boost::optional< int > n; - while ( recv.take( n) ) - { - BOOST_ASSERT( n); - int r = parallel_fib( * n, 5); - send.put( std::make_pair( * n, r) ); - } - send.deactivate(); -} - -int main( int argc, char *argv[]) -{ - try - { - pool_type pool( tsk::poolsize( 2) ); - - tsk::spin::unbounded_channel< int > buf1; - tsk::spin::unbounded_channel< std::pair< int , int > > buf2; - - tsk::async( - tsk::make_task( submit, buf1, buf2, 15), - pool); - tsk::async( - tsk::make_task( calculate, buf1, buf2), - pool); - - return EXIT_SUCCESS; - } - catch ( std::exception const& e) - { std::cerr << "exception: " << e.what() << std::endl; } - catch ( ... ) - { std::cerr << "unhandled" << std::endl; } - - return EXIT_FAILURE; -} diff --git a/libs/task/examples/sync/ping_pong.cpp b/libs/task/examples/sync/ping_pong.cpp deleted file mode 100755 index 998730d5..00000000 --- a/libs/task/examples/sync/ping_pong.cpp +++ /dev/null @@ -1,125 +0,0 @@ -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include - -typedef boost::tasks::static_pool< boost::tasks::unbounded_fifo > pool_t; -typedef boost::tasks::spin::unbounded_channel< std::string > fifo_t; - -inline -void ping( - fifo_t & recv_buf, - fifo_t & send_buf, - boost::tasks::spin::barrier & b) -{ - boost::this_thread::sleep( boost::posix_time::seconds( 1) ); - b.wait(); - - std::stringstream tss; - tss << boost::this_thread::get_id(); - std::stringstream fss; - fss << boost::this_tasklet::get_id(); - - fprintf( stderr, "start tasklet task %s in thread %s\n", fss.str().c_str(), tss.str().c_str() ); - - boost::optional< std::string > value; - - send_buf.put("ping"); - BOOST_ASSERT( recv_buf.take( value) ); - fprintf( stderr, "ping tasklet %s in thread %s recevied %s\n", fss.str().c_str(), tss.str().c_str(), value->c_str()); - value.reset(); - - send_buf.put("ping"); - BOOST_ASSERT( recv_buf.take( value) ); - fprintf( stderr, "ping tasklet %s in thread %s recevied %s\n", fss.str().c_str(), tss.str().c_str(), value->c_str()); - value.reset(); - - send_buf.put("ping"); - BOOST_ASSERT( recv_buf.take( value) ); - fprintf( stderr, "ping tasklet %s in thread %s recevied %s\n", fss.str().c_str(), tss.str().c_str(), value->c_str()); - value.reset(); - - send_buf.deactivate(); - - fprintf( stderr, "end ping tasklet %s in thread %s\n", fss.str().c_str(), tss.str().c_str() ); -} - -inline -void pong( - fifo_t & recv_buf, - fifo_t & send_buf, - boost::tasks::spin::barrier & b) -{ - b.wait(); - std::stringstream tss; - tss << boost::this_thread::get_id(); - std::stringstream fss; - fss << boost::this_tasklet::get_id(); - - fprintf( stderr, "start pong tasklet %s in thread %s\n", fss.str().c_str(), tss.str().c_str() ); - - boost::optional< std::string > value; - - BOOST_ASSERT( recv_buf.take( value) ); - fprintf( stderr, "pong tasklet %s in thread %s recevied %s\n", fss.str().c_str(), tss.str().c_str(), value->c_str()); - value.reset(); - send_buf.put("pong"); - - BOOST_ASSERT( recv_buf.take( value) ); - fprintf( stderr, "pong tasklet %s in thread %s recevied %s\n", fss.str().c_str(), tss.str().c_str(), value->c_str()); - value.reset(); - send_buf.put("pong"); - - BOOST_ASSERT( recv_buf.take( value) ); - fprintf( stderr, "pong tasklet %s in thread %s recevied %s\n", fss.str().c_str(), tss.str().c_str(), value->c_str()); - value.reset(); - send_buf.put("pong"); - - send_buf.deactivate(); - - fprintf( stderr, "end pong tasklet %s in thread %s\n", fss.str().c_str(), tss.str().c_str() ); -} - -int main() -{ - try - { - fifo_t buf1; - fifo_t buf2; - boost::tasks::spin::barrier b( 2); - - std::cout << "start" << std::endl; - - pool_t pool( boost::tasks::poolsize( 2) ); - - boost::tasks::async( - boost::tasks::make_task( ping, buf1, buf2, boost::ref( b) ), - pool); - - boost::tasks::async( - boost::tasks::make_task( pong, buf2, buf1, boost::ref( b) ), - pool); - - pool.shutdown(); - - std::cout << "finish" << std::endl; - - return EXIT_SUCCESS; - } - catch ( boost::system::system_error const& e) - { std::cerr << "system_error: " << e.code().value() << std::endl; } - catch ( std::exception const& e) - { std::cerr << "exception: " << e.what() << std::endl; } - catch (...) - { std::cerr << "unhandled exception" << std::endl; } - return EXIT_FAILURE; -} diff --git a/libs/task/src/callable.cpp b/libs/task/src/callable.cpp deleted file mode 100755 index 76737660..00000000 --- a/libs/task/src/callable.cpp +++ /dev/null @@ -1,36 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include "boost/task/callable.hpp" - -namespace boost { -namespace tasks { - -callable::callable() : - base_() -{} - -void -callable::operator()() -{ base_->run(); } - -bool -callable::empty() const -{ return ! base_; } - -void -callable::clear() -{ base_.reset(); } - -void -callable::reset( shared_ptr< thread > const& thrd) -{ base_->reset( thrd); } - -void -callable::swap( callable & other) -{ base_.swap( other.base_); } - -}} diff --git a/libs/task/src/context.cpp b/libs/task/src/context.cpp deleted file mode 100755 index f1583123..00000000 --- a/libs/task/src/context.cpp +++ /dev/null @@ -1,84 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include "boost/task/context.hpp" - -#include - -namespace boost { -namespace tasks { -namespace detail { - -void -context_base::reset_( shared_ptr< thread > const& thrd) -{ - thrd_ = thrd; - BOOST_ASSERT( thrd_); - if ( requested_) - if ( thrd_) thrd_->interrupt(); -} - -void -context_base::interrupt_() -{ - if ( ! requested_) - { - requested_ = true; - if ( thrd_) thrd_->interrupt(); - } -} - -context_base::context_base() : - use_count_( 0), - requested_( false), - mtx_(), - thrd_() -{} - -void -context_base::reset( shared_ptr< thread > const& thrd) -{ - lock_guard< mutex > lk( mtx_); - reset_( thrd); -} - -void -context_base::interrupt() -{ - lock_guard< mutex > lk( mtx_); - interrupt_(); -} - -bool -context_base::interruption_requested() -{ - lock_guard< mutex > lk( mtx_); - return requested_; -} - -} - -context::context() : - base_( new detail::context_base() ) -{} - -void -context::reset( shared_ptr< thread > const& thrd) -{ base_->reset( thrd); } - -void -context::interrupt() -{ base_->interrupt(); } - -bool -context::interruption_requested() -{ return base_->interruption_requested(); } - -void -context::swap( context & other) -{ base_.swap( other.base_); } - -}} diff --git a/libs/task/src/detail/worker.cpp b/libs/task/src/detail/worker.cpp deleted file mode 100644 index 003a3e29..00000000 --- a/libs/task/src/detail/worker.cpp +++ /dev/null @@ -1,51 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include "boost/task/detail/worker.hpp" - -namespace boost { -namespace tasks { -namespace detail { - -thread_specific_ptr< worker > worker::tss_; - -const thread::id -worker::get_id() const -{ return impl_->get_id(); } - -void -worker::join() const -{ impl_->join(); } - -void -worker::interrupt() const -{ impl_->interrupt(); } - -void -worker::put( callable const& ca) -{ impl_->put( ca); } - -bool -worker::try_steal( callable & ca) -{ return impl_->try_steal( ca); } - -void -worker::run() -{ - // FIXME: ugly - worker::tss_.reset( new worker( * this) ); - impl_->run(); -} - -void -worker::yield() -{ impl_->yield(); } - -worker * -worker::tss_get() -{ return worker::tss_.get(); } - -}}} diff --git a/libs/task/src/detail/worker_group.cpp b/libs/task/src/detail/worker_group.cpp deleted file mode 100644 index f8d398d3..00000000 --- a/libs/task/src/detail/worker_group.cpp +++ /dev/null @@ -1,88 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include "boost/task/detail/worker_group.hpp" - -#include -#include - -namespace boost { -namespace tasks { -namespace detail { - -worker_group::worker_group() : - cont_(), - id_idx_( cont_.get< id_idx_tag >() ), - rnd_idx_( cont_.get< rnd_idx_tag >() ) -{} - -worker_group::~worker_group() -{ - if ( ! empty() ) - join_all(); -} - -const worker -worker_group::operator[]( std::size_t pos) const -{ return rnd_idx_[pos]; } - -std::size_t -worker_group::size() const -{ return cont_.size(); } - -bool -worker_group::empty() const -{ return cont_.empty(); } - -const worker_group::iterator -worker_group::begin() -{ return id_idx_.begin(); } - -const worker_group::const_iterator -worker_group::begin() const -{ return id_idx_.begin(); } - -const worker_group::iterator -worker_group::end() -{ return id_idx_.end(); } - -const worker_group::const_iterator -worker_group::end() const -{ return id_idx_.end(); } - -const worker_group::const_iterator -worker_group::find( thread::id const& id) const -{ return id_idx_.find( id); } - -void -worker_group::insert( worker const& w) -{ cont_.insert( w); } - -worker_group::iterator -worker_group::erase( iterator const& i) -{ return id_idx_.erase( i); } - -void -worker_group::join_all() -{ - BOOST_FOREACH( worker w, cont_) - { - try - { w.join(); } - catch (...) - {} - } - cont_.clear(); -} - -void -worker_group::interrupt_all() -{ - BOOST_FOREACH( worker w, cont_) - { w.interrupt(); } -} - -}}} diff --git a/libs/task/src/detail/wsq.cpp b/libs/task/src/detail/wsq.cpp deleted file mode 100644 index 72a3784d..00000000 --- a/libs/task/src/detail/wsq.cpp +++ /dev/null @@ -1,120 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include "boost/task/detail/wsq.hpp" - -#include - -namespace boost { -namespace tasks { -namespace detail { - -wsq::wsq( fast_semaphore & fsem) : - initial_size_( 32), - array_( new callable[ initial_size_]), - capacity_( initial_size_), - mask_( initial_size_ - 1), - head_idx_( 0), - tail_idx_( 0), - mtx_(), - fsem_( fsem) -{} - -bool -wsq::empty() const -{ return head_idx_.load() >= tail_idx_.load(); } - -std::size_t -wsq::size() const -{ return tail_idx_.load() - head_idx_.load(); } - -void -wsq::put( callable const& ca) -{ - unsigned int tail( tail_idx_.load() ); - if ( tail <= head_idx_.load() + mask_) - { - array_[tail & mask_] = ca; - tail_idx_.fetch_add( 1); - } - else - { - lock_guard< recursive_mutex > lk( mtx_); - unsigned int head( head_idx_.load() ); - int count( size() ); - - if ( count >= mask_) - { - capacity_ <<= 1; - shared_array< callable > array( new callable[capacity_]); - for ( int i( 0); i != count; ++i) - array[i] = array_[(i + head) & mask_]; - array_.swap( array); - head_idx_.store( 0); - tail = count; - tail_idx_.store( tail); - mask_ = (mask_ << 1) | 1; - } - array_[tail & mask_] = ca; - tail_idx_.fetch_add( 1); - } - fsem_.post(); -} - -bool -wsq::try_take( callable & ca) -{ - unsigned int tail( tail_idx_.load() ); - if ( tail == 0) - return false; - tail -= 1; - tail_idx_.exchange( tail); - //tail_idx_.store( tail); - if ( head_idx_.load() <= tail) - { - ca.swap( array_[tail & mask_]); - return true; - } - else - { - lock_guard< recursive_mutex > lk( mtx_); - if ( head_idx_.load() <= tail) - { - ca.swap( array_[tail & mask_]); - return true; - } - else - { - tail_idx_.fetch_add( 1); - return false; - } - } -} - -bool -wsq::try_steal( callable & ca) -{ - recursive_mutex::scoped_try_lock lk( mtx_); - if ( lk.owns_lock() ) - { - unsigned int head( head_idx_.load() ); - head_idx_.exchange( head + 1); - //head_idx_.store( head + 1); - if ( head < tail_idx_.load() ) - { - ca.swap( array_[head & mask_]); - return true; - } - else - { - head_idx_.store( head); - return false; - } - } - return false; -} - -}}} diff --git a/libs/task/src/fast_semaphore.cpp b/libs/task/src/fast_semaphore.cpp deleted file mode 100755 index d6a534f1..00000000 --- a/libs/task/src/fast_semaphore.cpp +++ /dev/null @@ -1,74 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include "boost/task/fast_semaphore.hpp" - -#include -#include - -namespace boost { -namespace tasks { - -fast_semaphore::fast_semaphore( int sem_count, unsigned int spin_count) : - spin_count_( spin_count), - sem_count_( sem_count), - sem_active_( true), - sem_( sem_count) -{ - if ( 0 > sem_count_) - throw std::invalid_argument("count must not be negative"); -} - -fast_semaphore::~fast_semaphore() -{} - -void -fast_semaphore::post( int count) -{ - if ( 0 > count) - throw std::invalid_argument("count must not be negative"); - - int sem_count = sem_count_.fetch_add( count); - - if ( sem_count < 0) - sem_.post( ( std::min)( count, -sem_count) ); -} - -void -fast_semaphore::wait() -{ - unsigned int spin_count( spin_count_); - while ( 0 < spin_count--) - if ( try_wait() ) return; - - if ( 0 <= sem_count_.fetch_sub( 1) ) return; - - if ( ! sem_active_.load() ) return; - - sem_.wait(); -} - -bool -fast_semaphore::try_wait() -{ - int sem_count; - - do - { - sem_count = sem_count_.load(); - if ( ! sem_active_.load() ) return false; - } while ( sem_count > 0 && ! sem_count_.compare_exchange_strong( sem_count, sem_count - 1) ); - - return sem_count > 0; -} - -void -fast_semaphore::deactivate() { - sem_active_.store( false); - post( std::abs( sem_count_.load() ) ); -} - -}} diff --git a/libs/task/src/poolsize.cpp b/libs/task/src/poolsize.cpp deleted file mode 100755 index 7b19a561..00000000 --- a/libs/task/src/poolsize.cpp +++ /dev/null @@ -1,22 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include "boost/task/poolsize.hpp" - -#include - -namespace boost { -namespace tasks { - -poolsize::poolsize( std::size_t value) : - value_( value) -{ if ( value <= 0) throw invalid_poolsize(); } - -poolsize::operator std::size_t () const -{ return value_; } - -}} - diff --git a/libs/task/src/semaphore_posix.cpp b/libs/task/src/semaphore_posix.cpp deleted file mode 100755 index 55bbca3a..00000000 --- a/libs/task/src/semaphore_posix.cpp +++ /dev/null @@ -1,100 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include "boost/task/semaphore.hpp" - -extern "C" { - -#include - -} - -#include -#include - -#include -#include -#include -#include - -namespace { - -#if ! defined(__FreeBSD__) -union semun { - int val; - semid_ds * buf; - ushort * array; -}; -#endif - -} - -namespace boost { -namespace tasks { - -semaphore::semaphore( int sem_count) : - handle_( -1) -{ - if ( 0 > sem_count) - throw std::invalid_argument("count must not be negative"); - - semun ctl; - ctl.val = sem_count; - BOOST_ASSERT( ctl.val == sem_count); - - if ( ( handle_ = ::semget( IPC_PRIVATE, 1, S_IRUSR | S_IWUSR) ) == -1) - throw system::system_error( errno, system::system_category() ); - - if ( ::semctl( handle_, 0, SETVAL, ctl) == -1) - throw system::system_error( errno, system::system_category() ); -} - -semaphore::~semaphore() -{ ::semctl( handle_, 0, IPC_RMID); } - -void -semaphore::post( int n) -{ - if ( 0 >= n) - throw std::invalid_argument("invalid post-argument"); - - sembuf op; - - op.sem_num = 0; - op.sem_op = n; - op.sem_flg = 0; - BOOST_ASSERT( op.sem_op == n); - - if ( ::semop( handle_, & op, 1) == -1) - throw system::system_error( errno, system::system_category() ); -} - -void -semaphore::wait() -{ - sembuf op; - - op.sem_num = 0; - op.sem_op = -1; - op.sem_flg = 0; - - if ( ::semop( handle_, & op, 1) == -1) - throw system::system_error( errno, system::system_category() ); -} - -bool -semaphore::try_wait() -{ - sembuf op; - - op.sem_num = 0; - op.sem_op = -1; - op.sem_flg = IPC_NOWAIT; // Don't wait if we can't lock it now - - return ::semop( handle_, & op, 1) == 0; -} - -}} diff --git a/libs/task/src/semaphore_windows.cpp b/libs/task/src/semaphore_windows.cpp deleted file mode 100755 index 3115850c..00000000 --- a/libs/task/src/semaphore_windows.cpp +++ /dev/null @@ -1,57 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include "boost/task/semaphore.hpp" - -#include -#include - -#include -#include - -namespace boost { -namespace tasks { - -semaphore::semaphore( int value) : - handle_() -{ - if ( ( handle_ = ::CreateSemaphore( 0, value, ( std::numeric_limits< int >::max)(), 0) ) == 0) - throw system::system_error( ::GetLastError(), system::system_category() ); -} - -semaphore::~semaphore() -{ ::CloseHandle( handle_); } - -void -semaphore::post( int n) -{ - if ( ! ::ReleaseSemaphore( handle_, n, 0) ) - throw system::system_error( ::GetLastError(), system::system_category() ); -} - -void -semaphore::wait() -{ - if ( ::WaitForSingleObject( handle_, INFINITE) != WAIT_OBJECT_0) - throw system::system_error( ::GetLastError(), system::system_category() ); -} - -bool -semaphore::try_wait() -{ - switch ( ::WaitForSingleObject( handle_, 0) ) - { - case WAIT_OBJECT_0: - return true; - case WAIT_TIMEOUT: - return false; - default: - throw system::system_error( ::GetLastError(), system::system_category() ); - } - return true; -} - -}} diff --git a/libs/task/src/spin/auto_reset_event.cpp b/libs/task/src/spin/auto_reset_event.cpp deleted file mode 100644 index 9c7c82a9..00000000 --- a/libs/task/src/spin/auto_reset_event.cpp +++ /dev/null @@ -1,71 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include "boost/task/spin/auto_reset_event.hpp" - -#include - -#include - -namespace boost { -namespace tasks { -namespace spin { - -auto_reset_event::auto_reset_event( bool isset) : - state_( isset ? SET : RESET) -{} - -void -auto_reset_event::set() -{ state_.store( SET); } - -void -auto_reset_event::wait() -{ - state expected = SET; - while ( ! state_.compare_exchange_strong( expected, RESET) ) - { - this_thread::interruption_point(); - if ( this_task::runs_in_pool() ) - this_task::yield(); - else - this_thread::yield(); - this_thread::interruption_point(); - - expected = SET; - } -} - -bool -auto_reset_event::try_wait() -{ - state expected = SET; - return state_.compare_exchange_strong( expected, RESET); -} - -bool -auto_reset_event::timed_wait( system_time const& abs_time) -{ - if ( get_system_time() >= abs_time) return false; - - state expected = SET; - while ( ! state_.compare_exchange_strong( expected, RESET) ) - { - this_thread::interruption_point(); - if ( this_task::runs_in_pool() ) - this_task::yield(); - else - this_thread::yield(); - this_thread::interruption_point(); - - if ( get_system_time() >= abs_time) return false; - expected = SET; - } - - return true; -} - -}}} diff --git a/libs/task/src/spin/barrier.cpp b/libs/task/src/spin/barrier.cpp deleted file mode 100644 index f2beb7a4..00000000 --- a/libs/task/src/spin/barrier.cpp +++ /dev/null @@ -1,43 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include "boost/task/spin/barrier.hpp" - -#include - -namespace boost { -namespace tasks { -namespace spin { - -barrier::barrier( std::size_t initial) : - initial_( initial), - current_( initial_), - cycle_( true), - mtx_(), - cond_() -{ if ( initial == 0) throw std::invalid_argument("invalid barrier count"); } - -bool -barrier::wait() -{ - mutex::scoped_lock lk( mtx_); - bool cycle( cycle_); - if ( 0 == --current_) - { - cycle_ = ! cycle_; - current_ = initial_; - cond_.notify_all(); - return true; - } - else - { - while ( cycle == cycle_) - cond_.wait( lk); - } - return false; -} - -}}} diff --git a/libs/task/src/spin/condition.cpp b/libs/task/src/spin/condition.cpp deleted file mode 100644 index 32cdc66c..00000000 --- a/libs/task/src/spin/condition.cpp +++ /dev/null @@ -1,52 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include "boost/task/spin/condition.hpp" - -#include - -namespace boost { -namespace tasks { -namespace spin { - -void -condition::notify_( command cmd) -{ - enter_mtx_.lock(); - - if ( 0 == waiters_.load() ) - { - enter_mtx_.unlock(); - return; - } - - command expected = SLEEPING; - while ( ! cmd_.compare_exchange_strong( expected, cmd) ) - { - if ( this_tasklet::runs_as_tasklet() ) - this_tasklet::yield(); - else - this_thread::yield(); - expected = SLEEPING; - } -} - -condition::condition() : - cmd_( SLEEPING), - waiters_( 0), - enter_mtx_(), - check_mtx_() -{} - -void -condition::notify_one() -{ notify_( NOTIFY_ONE); } - -void -condition::notify_all() -{ notify_( NOTIFY_ALL); } - -}}} diff --git a/libs/task/src/spin/count_down_event.cpp b/libs/task/src/spin/count_down_event.cpp deleted file mode 100644 index a4c425fe..00000000 --- a/libs/task/src/spin/count_down_event.cpp +++ /dev/null @@ -1,82 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include "boost/task/spin/count_down_event.hpp" - -#include - -#include -#include - -namespace boost { -namespace tasks { -namespace spin { - -count_down_event::count_down_event( std::size_t initial) : - initial_( initial), - current_( initial_) -{} - -std::size_t -count_down_event::initial() const -{ return initial_; } - -std::size_t -count_down_event::current() const -{ return current_.load(); } - -bool -count_down_event::is_set() const -{ return 0 == current_.load(); } - -void -count_down_event::set() -{ - for (;;) - { - if ( 0 == current_.load() ) - return; - std::size_t expected = current_.load(); - if ( current_.compare_exchange_strong( expected, expected - 1) ) - return; - } -} - -void -count_down_event::wait() -{ - while ( 0 != current_.load() ) - { - this_thread::interruption_point(); - if ( this_task::runs_in_pool() ) - this_task::yield(); - else - this_thread::yield(); - this_thread::interruption_point(); - } -} - -bool -count_down_event::timed_wait( system_time const& abs_time) -{ - if ( get_system_time() >= abs_time) return false; - - while ( 0 != current_.load() ) - { - this_thread::interruption_point(); - if ( this_task::runs_in_pool() ) - this_task::yield(); - else - this_thread::yield(); - this_thread::interruption_point(); - - if ( get_system_time() >= abs_time) return false; - } - - return true; -} - -}}} diff --git a/libs/task/src/spin/manual_reset_event.cpp b/libs/task/src/spin/manual_reset_event.cpp deleted file mode 100644 index b1880def..00000000 --- a/libs/task/src/spin/manual_reset_event.cpp +++ /dev/null @@ -1,104 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include "boost/task/spin/manual_reset_event.hpp" - -#include -#include - -#include - -namespace boost { -namespace tasks { -namespace spin { - -manual_reset_event::manual_reset_event( bool isset) : - state_( isset ? SET : RESET), - waiters_( 0), - enter_mtx_() -{} - -void -manual_reset_event::set() -{ - enter_mtx_.lock(); - - state expected = RESET; - if ( ! state_.compare_exchange_strong( expected, SET) || - 0 == waiters_.load() ) - enter_mtx_.unlock(); -} - -void -manual_reset_event::reset() -{ - mutex::scoped_lock lk( enter_mtx_); - BOOST_ASSERT( lk); - - state_.store( RESET); -} - -void -manual_reset_event::wait() -{ - { - mutex::scoped_lock lk( enter_mtx_); - BOOST_ASSERT( lk); - waiters_.fetch_add( 1); - } - - while ( RESET == state_.load() ) - { - this_thread::interruption_point(); - if ( this_task::runs_in_pool() ) - this_task::yield(); - else - this_thread::yield(); - this_thread::interruption_point(); - } - - if ( 1 == waiters_.fetch_sub( 1) ) - enter_mtx_.unlock(); -} - -bool -manual_reset_event::timed_wait( system_time const& abs_time) -{ - if ( get_system_time() >= abs_time) return false; - - while ( RESET == state_.load() ) - { - this_thread::interruption_point(); - if ( this_task::runs_in_pool() ) - this_task::yield(); - else - this_thread::yield(); - this_thread::interruption_point(); - - if ( get_system_time() >= abs_time) return false; - } - - return true; -} - -bool -manual_reset_event::try_wait() -{ - { - mutex::scoped_lock lk( enter_mtx_); - BOOST_ASSERT( lk); - waiters_.fetch_add( 1); - } - - bool result = SET == state_.load(); - - if ( 1 == waiters_.fetch_sub( 1) ) - enter_mtx_.unlock(); - - return result; -} - -}}} diff --git a/libs/task/src/spin/mutex.cpp b/libs/task/src/spin/mutex.cpp deleted file mode 100644 index 387d4fcb..00000000 --- a/libs/task/src/spin/mutex.cpp +++ /dev/null @@ -1,77 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include - -#include - -#include - -namespace boost { -namespace tasks { -namespace spin { - -mutex::mutex() : - state_( UNLOCKED) -{} - -void -mutex::lock() -{ - for (;;) - { - state expected = UNLOCKED; - if ( state_.compare_exchange_strong( expected, LOCKED) ) - break; - if ( this_tasklet::runs_as_tasklet() ) - this_tasklet::yield(); - else - this_thread::yield(); - } -} - -bool -mutex::timed_lock( system_time const& abs_time) -{ - if ( abs_time.is_infinity() ) - { - lock(); - return true; - } - - if ( get_system_time() >= abs_time) - return false; - - for (;;) - { - if ( try_lock() ) break; - - if ( get_system_time() >= abs_time) - return false; - - this_thread::interruption_point(); - if ( this_task::runs_in_pool() ) - this_task::yield(); - else - this_thread::yield(); - this_thread::interruption_point(); - } - - return true; -} - -bool -mutex::try_lock() -{ - state expected = UNLOCKED; - return state_.compare_exchange_strong( expected, LOCKED); -} - -void -mutex::unlock() -{ state_.store( UNLOCKED); } - -}}} diff --git a/libs/task/src/stacksize.cpp b/libs/task/src/stacksize.cpp deleted file mode 100755 index 3c6548b0..00000000 --- a/libs/task/src/stacksize.cpp +++ /dev/null @@ -1,21 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include "boost/task/stacksize.hpp" - -#include - -namespace boost { -namespace tasks { - -stacksize::stacksize( std::size_t value) : - value_( value) -{ if ( value <= 0) throw invalid_stacksize(); } - -stacksize::operator std::size_t () const -{ return value_; } - -}} diff --git a/libs/task/src/watermark.cpp b/libs/task/src/watermark.cpp deleted file mode 100755 index fe2fc24b..00000000 --- a/libs/task/src/watermark.cpp +++ /dev/null @@ -1,34 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include "boost/task/watermark.hpp" - -#include - -namespace boost { -namespace tasks { - -high_watermark::high_watermark( std::size_t value) : - value_( value) -{ - if ( value <= 0) - throw invalid_watermark(); -} - -high_watermark::operator std::size_t () const -{ return value_; } - -low_watermark::low_watermark( std::size_t value) -: value_( value) -{ - if ( value < 0) - throw invalid_watermark(); -} - -low_watermark::operator std::size_t () const -{ return value_; } - -}} diff --git a/libs/task/test/Jamfile.v2 b/libs/task/test/Jamfile.v2 deleted file mode 100644 index 1aa4d0a2..00000000 --- a/libs/task/test/Jamfile.v2 +++ /dev/null @@ -1,46 +0,0 @@ -# Boost.Task Library Tests Jamfile - -# Copyright Oliver Kowalke 2009. -# Distributed under the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) - -import testing ; - -project boost/task/test - : requirements - ../../test/build//boost_unit_test_framework - ../../tasklet/build//boost_tasklet - ../../thread/build//boost_thread - ../../system/build//boost_system - ../build//boost_task - static - multi - ; - -rule task-test ( source ) -{ - return - [ run $(source).cpp ] - ; -} - -test-suite task : - [ task-test test_task ] - [ task-test test_own_thread ] - [ task-test test_tasklet ] - [ task-test test_new_thread ] - [ task-test test_unbounded_pool ] - [ task-test test_bounded_pool ] - [ task-test test_as_sub_task ] - [ task-test test_spin_mutex ] - [ task-test test_spin_condition ] - [ task-test test_spin_condition_notify_all ] - [ task-test test_spin_condition_notify_one ] - [ task-test test_spin_condition_timed_wait_times_out ] - [ task-test test_spin_count_down_event ] - [ task-test test_spin_auto_reset_event ] - [ task-test test_spin_manual_reset_event ] - [ task-test test_spin_unbounded_channel ] - [ task-test test_spin_bounded_channel ] - ; diff --git a/libs/task/test/condition_test_common.hpp b/libs/task/test/condition_test_common.hpp deleted file mode 100644 index 10b84d0c..00000000 --- a/libs/task/test/condition_test_common.hpp +++ /dev/null @@ -1,99 +0,0 @@ -#ifndef TASK_CONDITION_TEST_COMMON_HPP -#define TASK_CONDITION_TEST_COMMON_HPP -// Copyright (C) 2007 Anthony Williams -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -#include -#include - -#include - -namespace tsk = boost::tasks; - -unsigned const timeout_seconds=5; - -struct wait_for_flag : private boost::noncopyable -{ - tsk::spin::mutex mutex; - tsk::spin::condition cond_var; - bool flag; - unsigned woken; - - wait_for_flag(): - flag(false),woken(0) - {} - - struct check_flag - { - bool const& flag; - - check_flag(bool const& flag_): - flag(flag_) - {} - - bool operator()() const - { - return flag; - } - private: - void operator=(check_flag&); - }; - - - void wait_without_predicate() - { - tsk::spin::mutex::scoped_lock lock(mutex); - while(!flag) - { - cond_var.wait(lock); - } - ++woken; - } - - void wait_with_predicate() - { - tsk::spin::mutex::scoped_lock lock(mutex); - cond_var.wait(lock,check_flag(flag)); - if(flag) - { - ++woken; - } - } - - void timed_wait_without_predicate() - { - boost::system_time const timeout=boost::get_system_time()+boost::posix_time::seconds(timeout_seconds); - - tsk::spin::mutex::scoped_lock lock(mutex); - while(!flag) - { - if(!cond_var.timed_wait(lock,timeout)) - { - return; - } - } - ++woken; - } - - void timed_wait_with_predicate() - { - boost::system_time const timeout=boost::get_system_time()+boost::posix_time::seconds(timeout_seconds); - tsk::spin::mutex::scoped_lock lock(mutex); - if(cond_var.timed_wait(lock,timeout,check_flag(flag)) && flag) - { - ++woken; - } - } - void relative_timed_wait_with_predicate() - { - tsk::spin::mutex::scoped_lock lock(mutex); - if(cond_var.timed_wait(lock,boost::posix_time::seconds(timeout_seconds),check_flag(flag)) && flag) - { - ++woken; - } - } -}; - -#endif diff --git a/libs/task/test/test_as_sub_task.cpp b/libs/task/test/test_as_sub_task.cpp deleted file mode 100755 index f6ea7dfb..00000000 --- a/libs/task/test/test_as_sub_task.cpp +++ /dev/null @@ -1,70 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "test_functions.hpp" - -namespace pt = boost::posix_time; -namespace tsk = boost::tasks; - -namespace { - -bool exec_sub_task() -{ - tsk::handle< bool > h( - tsk::async( - tsk::make_task( runs_in_pool_fn), - tsk::as_sub_task() ) ); - return h.get(); -} - -void test_runs_not_in_pool() -{ - tsk::task< bool > t( runs_in_pool_fn); - tsk::handle< bool > h( - tsk::async( boost::move( t), tsk::as_sub_task() ) ); - BOOST_CHECK_EQUAL( h.get(), false); -} - -void test_runs_in_pool() -{ - tsk::static_pool< - tsk::unbounded_fifo - > pool( tsk::poolsize( 1) ); - tsk::handle< bool > h( - tsk::async( - tsk::make_task( exec_sub_task), - pool) ); - BOOST_CHECK_EQUAL( h.get(), true); -} - -} - -boost::unit_test::test_suite * init_unit_test_suite( int, char* []) -{ - boost::unit_test_framework::test_suite * test = - BOOST_TEST_SUITE("Boost.Task: as-sub-task test suite"); - - test->add( BOOST_TEST_CASE( & test_runs_in_pool) ); - test->add( BOOST_TEST_CASE( & test_runs_not_in_pool) ); - - return test; -} diff --git a/libs/task/test/test_bounded_pool.cpp b/libs/task/test/test_bounded_pool.cpp deleted file mode 100644 index 32397263..00000000 --- a/libs/task/test/test_bounded_pool.cpp +++ /dev/null @@ -1,509 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "test_functions.hpp" - -namespace pt = boost::posix_time; -namespace tsk = boost::tasks; - -// check size and move op -void test_case_1() -{ - tsk::static_pool< - tsk::bounded_fifo - > pool1( - tsk::poolsize( 3), - tsk::high_watermark( 10), - tsk::low_watermark( 5) ); - BOOST_CHECK( pool1); - BOOST_CHECK_EQUAL( pool1.size(), std::size_t( 3) ); - BOOST_CHECK_EQUAL( pool1.upper_bound(), std::size_t( 10) ); - BOOST_CHECK_EQUAL( pool1.lower_bound(), std::size_t( 5) ); - - tsk::static_pool< - tsk::bounded_fifo - > pool2; - BOOST_CHECK( ! pool2); - BOOST_CHECK_THROW( pool2.size(), tsk::pool_moved); - BOOST_CHECK_THROW( pool2.upper_bound(), tsk::pool_moved); - BOOST_CHECK_THROW( pool2.lower_bound(), tsk::pool_moved); - - pool2 = boost::move( pool1); - - BOOST_CHECK( ! pool1); - BOOST_CHECK_THROW( pool1.size(), tsk::pool_moved); - BOOST_CHECK_THROW( pool1.upper_bound(), tsk::pool_moved); - BOOST_CHECK_THROW( pool1.lower_bound(), tsk::pool_moved); - - BOOST_CHECK( pool2); - BOOST_CHECK_EQUAL( pool2.size(), std::size_t( 3) ); - BOOST_CHECK_EQUAL( pool2.upper_bound(), std::size_t( 10) ); - BOOST_CHECK_EQUAL( pool2.lower_bound(), std::size_t( 5) ); - - tsk::task< int > t( fibonacci_fn, 10); - tsk::handle< int > h( - tsk::async( boost::move( t), pool2) ); - BOOST_CHECK_EQUAL( h.get(), 55); -} - -// check submit -void test_case_2() -{ - tsk::static_pool< - tsk::bounded_fifo - > pool( - tsk::poolsize( 1), - tsk::high_watermark( 10), - tsk::low_watermark( 10) ); - tsk::task< int > t( fibonacci_fn, 10); - tsk::handle< int > h( - tsk::async( boost::move( t), pool) ); - BOOST_CHECK_EQUAL( h.get(), 55); -} - -// check assignment -void test_case_3() -{ - tsk::static_pool< - tsk::bounded_fifo - > pool( - tsk::poolsize( 5), - tsk::high_watermark( 10), - tsk::low_watermark( 10) ); - tsk::task< int > t( fibonacci_fn, 10); - tsk::handle< int > h1; - tsk::handle< int > h2( - tsk::async( boost::move( t), pool) ); - h1 = h2; - BOOST_CHECK_EQUAL( h1.get(), 55); - BOOST_CHECK_EQUAL( h2.get(), 55); -} - -// check swap -void test_case_4() -{ - tsk::static_pool< - tsk::bounded_fifo - > pool( - tsk::poolsize( 5), - tsk::high_watermark( 10), - tsk::low_watermark( 10) ); - tsk::task< int > t1( fibonacci_fn, 5); - tsk::task< int > t2( fibonacci_fn, 10); - tsk::handle< int > h1( - tsk::async( boost::move( t1), pool) ); - tsk::handle< int > h2( - tsk::async( boost::move( t2), pool) ); - BOOST_CHECK_EQUAL( h1.get(), 5); - BOOST_CHECK_EQUAL( h2.get(), 55); - BOOST_CHECK_NO_THROW( h1.swap( h2) ); - BOOST_CHECK_EQUAL( h1.get(), 55); - BOOST_CHECK_EQUAL( h2.get(), 5); -} - -// check runs in pool -void test_case_5() -{ - tsk::static_pool< - tsk::bounded_fifo - > pool( - tsk::poolsize( 1), - tsk::high_watermark( 10), - tsk::low_watermark( 10) ); - tsk::task< bool > t( runs_in_pool_fn); - tsk::handle< bool > h( - tsk::async( boost::move( t), pool) ); - BOOST_CHECK_EQUAL( h.get(), true); -} - -// check shutdown -void test_case_6() -{ - tsk::static_pool< - tsk::bounded_fifo - > pool( - tsk::poolsize( 1), - tsk::high_watermark( 10), - tsk::low_watermark( 10) ); - tsk::task< int > t( fibonacci_fn, 10); - tsk::handle< int > h( - tsk::async( boost::move( t), pool) ); - pool.shutdown(); - BOOST_CHECK( pool.closed() ); - BOOST_CHECK_EQUAL( h.get(), 55); -} - -// check runtime_error throw inside task -void test_case_7() -{ - tsk::static_pool< - tsk::bounded_fifo - > pool( - tsk::poolsize( 1), - tsk::high_watermark( 10), - tsk::low_watermark( 10) ); - tsk::task< void > t( throwing_fn); - tsk::handle< void > h( - tsk::async( boost::move( t), pool) ); - pool.shutdown(); - BOOST_CHECK_THROW( h.get(), std::runtime_error); -} - -// check shutdown with task_rejected exception -void test_case_8() -{ - tsk::static_pool< - tsk::bounded_fifo - > pool( - tsk::poolsize( 1), - tsk::high_watermark( 10), - tsk::low_watermark( 10) ); - tsk::task< int > t( fibonacci_fn, 10); - pool.shutdown(); - BOOST_CHECK( pool.closed() ); - BOOST_CHECK_THROW( - tsk::async( boost::move( t), pool), - tsk::task_rejected); -} - -// check shutdown_now with thread_interrupted exception -void test_case_9() -{ - tsk::static_pool< - tsk::bounded_fifo - > pool( - tsk::poolsize( 1), - tsk::high_watermark( 1), - tsk::low_watermark( 1) ); - tsk::task< void > t( delay_fn, pt::millisec( 500) ); - tsk::handle< void > h( - tsk::async( boost::move( t), pool) ); - boost::this_thread::sleep( pt::millisec( 250) ); - BOOST_CHECK_EQUAL( pool.size(), std::size_t( 1) ); - pool.shutdown_now(); - BOOST_CHECK( pool.closed() ); - BOOST_CHECK_EQUAL( pool.size(), std::size_t( 0) ); - BOOST_CHECK_THROW( h.get(), tsk::task_interrupted); -} - -// check wait -void test_case_10() -{ - tsk::static_pool< - tsk::bounded_fifo - > pool( - tsk::poolsize( 5), - tsk::high_watermark( 1), - tsk::low_watermark( 1) ); - tsk::task< int > t( fibonacci_fn, 10); - tsk::handle< int > h( - tsk::async( boost::move( t), pool) ); - h.wait(); - BOOST_CHECK( h.is_ready() ); - BOOST_CHECK( h.has_value() ); - BOOST_CHECK( ! h.has_exception() ); - BOOST_CHECK_EQUAL( h.get(), 55); -} - -// check wait_for -void test_case_11() -{ - tsk::static_pool< - tsk::bounded_fifo - > pool( - tsk::poolsize( 5), - tsk::high_watermark( 1), - tsk::low_watermark( 1) ); - tsk::task< void > t( delay_fn, pt::seconds( 1) ); - tsk::handle< void > h( - tsk::async( boost::move( t), pool) ); - BOOST_CHECK( h.wait_for( pt::seconds( 3) ) ); - BOOST_CHECK( h.is_ready() ); - BOOST_CHECK( h.has_value() ); - BOOST_CHECK( ! h.has_exception() ); -} - -// check wait_for -void test_case_12() -{ - tsk::static_pool< - tsk::bounded_fifo - > pool( - tsk::poolsize( 5), - tsk::high_watermark( 1), - tsk::low_watermark( 1) ); - tsk::task< void > t( delay_fn, pt::seconds( 3) ); - tsk::handle< void > h( - tsk::async( boost::move( t), pool) ); - BOOST_CHECK( ! h.wait_for( pt::seconds( 1) ) ); - BOOST_CHECK( ! h.is_ready() ); - BOOST_CHECK( ! h.has_value() ); - BOOST_CHECK( ! h.has_exception() ); -} - -// check wait_for -void test_case_13() -{ - tsk::static_pool< - tsk::bounded_fifo - > pool( - tsk::poolsize( 5), - tsk::high_watermark( 1), - tsk::low_watermark( 1) ); - tsk::task< void > t( delay_fn, pt::seconds( 1) ); - tsk::handle< void > h( - tsk::async( boost::move( t), pool) ); - BOOST_CHECK( h.wait_until( boost::get_system_time() + pt::seconds( 3) ) ); - BOOST_CHECK( h.is_ready() ); - BOOST_CHECK( h.has_value() ); - BOOST_CHECK( ! h.has_exception() ); -} - -// check wait_for -void test_case_14() -{ - tsk::static_pool< - tsk::bounded_fifo - > pool( - tsk::poolsize( 5), - tsk::high_watermark( 1), - tsk::low_watermark( 1) ); - tsk::task< void > t( delay_fn, pt::seconds( 3) ); - tsk::handle< void > h( - tsk::async( boost::move( t), pool) ); - BOOST_CHECK( ! h.wait_until( boost::get_system_time() + pt::seconds( 1) ) ); - BOOST_CHECK( ! h.is_ready() ); - BOOST_CHECK( ! h.has_value() ); - BOOST_CHECK( ! h.has_exception() ); -} - -// check interrupt -void test_case_15() -{ - tsk::static_pool< - tsk::bounded_fifo - > pool( - tsk::poolsize( 5), - tsk::high_watermark( 10), - tsk::low_watermark( 10) ); - tsk::task< void > t( delay_fn, pt::seconds( 3) ); - tsk::handle< void > h( - tsk::async( boost::move( t), pool) ); - h.interrupt(); - BOOST_CHECK( h.interruption_requested() ); - BOOST_CHECK_THROW( h.get(), tsk::task_interrupted); -} - -// check interrupt_all_worker -void test_case_16() -{ - tsk::static_pool< - tsk::bounded_fifo - > pool( - tsk::poolsize( 5), - tsk::high_watermark( 10), - tsk::low_watermark( 10) ); - tsk::task< void > t1( delay_fn, pt::seconds( 3) ); - tsk::task< void > t2( delay_fn, pt::seconds( 3) ); - tsk::task< void > t3( delay_fn, pt::seconds( 3) ); - tsk::handle< void > h1( - tsk::async( boost::move( t1), pool) ); - tsk::handle< void > h2( - tsk::async( boost::move( t2), pool) ); - tsk::handle< void > h3( - tsk::async( boost::move( t3), pool) ); - boost::this_thread::sleep( pt::millisec( 250) ); - pool.interrupt_all_worker(); - BOOST_CHECK( ! h1.interruption_requested() ); - BOOST_CHECK( ! h2.interruption_requested() ); - BOOST_CHECK( ! h3.interruption_requested() ); - BOOST_CHECK_THROW( h1.get(), tsk::task_interrupted); - BOOST_CHECK_THROW( h2.get(), tsk::task_interrupted); - BOOST_CHECK_THROW( h3.get(), tsk::task_interrupted); - BOOST_CHECK_EQUAL( pool.size(), std::size_t( 5) ); -} - -// check interrupt_and_wait -void test_case_17() -{ - tsk::static_pool< - tsk::bounded_fifo - > pool( - tsk::poolsize( 5), - tsk::high_watermark( 10), - tsk::low_watermark( 10) ); - bool finished( false); - tsk::task< void > t( interrupt_fn, pt::seconds( 1), boost::ref( finished) ); - tsk::handle< void > h( - tsk::async( boost::move( t), pool) ); - h.interrupt_and_wait(); - BOOST_CHECK( finished); - BOOST_CHECK( h.is_ready() ); - BOOST_CHECK( ! h.has_value() ); - BOOST_CHECK( h.has_exception() ); - BOOST_CHECK( h.interruption_requested() ); - BOOST_CHECK_THROW( h.get(), tsk::task_interrupted); -} - -// check interrupt_and_wait_for -void test_case_18() -{ - tsk::static_pool< - tsk::bounded_fifo - > pool( - tsk::poolsize( 5), - tsk::high_watermark( 10), - tsk::low_watermark( 10) ); - bool finished( false); - tsk::task< void > t( interrupt_fn, pt::seconds( 1), boost::ref( finished) ); - tsk::handle< void > h( - tsk::async( boost::move( t), pool) ); - BOOST_CHECK( h.interrupt_and_wait_for( pt::seconds( 3) ) ); - BOOST_CHECK( finished); - BOOST_CHECK( h.is_ready() ); - BOOST_CHECK( ! h.has_value() ); - BOOST_CHECK( h.has_exception() ); - BOOST_CHECK( h.interruption_requested() ); - BOOST_CHECK_THROW( h.get(), tsk::task_interrupted); -} - -// check interrupt_and_wait_for -void test_case_19() -{ - tsk::static_pool< - tsk::bounded_fifo - > pool( - tsk::poolsize( 5), - tsk::high_watermark( 10), - tsk::low_watermark( 10) ); - tsk::task< void > t( non_interrupt_fn, 3); - tsk::handle< void > h( - tsk::async( boost::move( t), pool) ); - BOOST_CHECK( ! h.interrupt_and_wait_for( pt::seconds( 1) ) ); -} - -// check interrupt_and_wait_until -void test_case_20() -{ - tsk::static_pool< - tsk::bounded_fifo - > pool( - tsk::poolsize( 5), - tsk::high_watermark( 10), - tsk::low_watermark( 10) ); - bool finished( false); - tsk::task< void > t( - interrupt_fn, - pt::seconds( 1), - boost::ref( finished) ); - tsk::handle< void > h( - tsk::async( boost::move( t), pool) ); - BOOST_CHECK( h.interrupt_and_wait_until( boost::get_system_time() + pt::seconds( 3) ) ); - BOOST_CHECK( finished); - BOOST_CHECK( h.is_ready() ); - BOOST_CHECK( ! h.has_value() ); - BOOST_CHECK( h.has_exception() ); - BOOST_CHECK( h.interruption_requested() ); - BOOST_CHECK_THROW( h.get(), tsk::task_interrupted); -} - -// check interrupt_and_wait_until -void test_case_21() -{ - tsk::static_pool< - tsk::bounded_fifo - > pool( - tsk::poolsize( 5), - tsk::high_watermark( 10), - tsk::low_watermark( 10) ); - tsk::task< void > t( non_interrupt_fn, 3); - tsk::handle< void > h( - tsk::async( boost::move( t), pool) ); - BOOST_CHECK( ! h.interrupt_and_wait_until( boost::get_system_time() + pt::seconds( 1) ) ); -} - -// check fifo scheduling -void test_case_22() -{ - typedef tsk::static_pool< - tsk::bounded_fifo - > pool_type; - BOOST_CHECK( ! tsk::has_attribute< pool_type >::value); - pool_type pool( - tsk::poolsize( 1), - tsk::high_watermark( 10), - tsk::low_watermark( 10) ); - boost::barrier b( 2); - std::vector< int > buffer; - tsk::task< void > t1( barrier_fn, boost::ref( b) ); - tsk::task< void > t2( - buffer_fibonacci_fn, - boost::ref( buffer), - 10); - tsk::task< void > t3( - buffer_fibonacci_fn, - boost::ref( buffer), - 0); - tsk::async( boost::move( t1), pool); - boost::this_thread::sleep( pt::millisec( 250) ); - tsk::async( boost::move( t2), pool); - tsk::async( boost::move( t3), pool); - b.wait(); - pool.shutdown(); - BOOST_CHECK_EQUAL( buffer[0], 55); - BOOST_CHECK_EQUAL( buffer[1], 0); - BOOST_CHECK_EQUAL( buffer.size(), std::size_t( 2) ); -} - -boost::unit_test::test_suite * init_unit_test_suite( int, char* []) -{ - boost::unit_test::test_suite * test = - BOOST_TEST_SUITE("Boost.Task: bounded-pool test suite"); - - test->add( BOOST_TEST_CASE( & test_case_1) ); - test->add( BOOST_TEST_CASE( & test_case_2) ); - test->add( BOOST_TEST_CASE( & test_case_3) ); - test->add( BOOST_TEST_CASE( & test_case_4) ); - test->add( BOOST_TEST_CASE( & test_case_5) ); - test->add( BOOST_TEST_CASE( & test_case_6) ); - test->add( BOOST_TEST_CASE( & test_case_7) ); - test->add( BOOST_TEST_CASE( & test_case_8) ); - test->add( BOOST_TEST_CASE( & test_case_9) ); - test->add( BOOST_TEST_CASE( & test_case_10) ); - test->add( BOOST_TEST_CASE( & test_case_11) ); - test->add( BOOST_TEST_CASE( & test_case_12) ); - test->add( BOOST_TEST_CASE( & test_case_13) ); - test->add( BOOST_TEST_CASE( & test_case_14) ); - test->add( BOOST_TEST_CASE( & test_case_15) ); - test->add( BOOST_TEST_CASE( & test_case_16) ); - test->add( BOOST_TEST_CASE( & test_case_17) ); - test->add( BOOST_TEST_CASE( & test_case_18) ); - test->add( BOOST_TEST_CASE( & test_case_19) ); - test->add( BOOST_TEST_CASE( & test_case_20) ); - test->add( BOOST_TEST_CASE( & test_case_21) ); - test->add( BOOST_TEST_CASE( & test_case_22) ); - - return test; -} - diff --git a/libs/task/test/test_functions.hpp b/libs/task/test/test_functions.hpp deleted file mode 100644 index 46d29e29..00000000 --- a/libs/task/test/test_functions.hpp +++ /dev/null @@ -1,99 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_TP_TEST_FUNCTIONS_H -#define BOOST_TP_TEST_FUNCTIONS_H - -#include -#include -#include -#include -#include - -#include - -extern "C" -{ -#if defined( BOOST_POSIX_API) -#include -# endif -# if defined( BOOST_WINDOWS_API) -#include -# endif -} - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace pt = boost::posix_time; -namespace tsk = boost::tasks; - -void barrier_fn( - boost::barrier & b) -{ b.wait(); } - -void delay_fn( pt::time_duration const& td) -{ boost::this_thread::sleep( td); } - -void non_interrupt_fn( int sec) -{ -# if defined( BOOST_WINDOWS_API) - ::Sleep( sec * 1000); -# else - ::sleep( sec); -# endif -} - -void interrupt_fn( pt::time_duration const& td, bool & finished) -{ - try - { boost::this_thread::sleep( td); } - catch (...) - { - finished = true; - throw; - } -} - -inline -int fibonacci_fn( int n) -{ - if ( n < 2) return n; - int k1( 1), k2( 0); - for ( int i( 2); i <= n; ++i) - { - boost::this_thread::interruption_point(); - int tmp( k1); - k1 = k1 + k2; - k2 = tmp; - } - boost::this_thread::interruption_point(); - return k1; -} - -inline -void buffer_fibonacci_fn( - std::vector< int > & buffer, - int n) -{ buffer.push_back( fibonacci_fn( n) ); } - -inline -bool runs_in_pool_fn() -{ return boost::this_task::runs_in_pool(); } - -inline -void throwing_fn() -{ throw std::runtime_error("exception thrown"); } - -#endif // BOOST_TP_TEST_FUNCTIONS_H diff --git a/libs/task/test/test_new_thread.cpp b/libs/task/test/test_new_thread.cpp deleted file mode 100644 index e5fd30b6..00000000 --- a/libs/task/test/test_new_thread.cpp +++ /dev/null @@ -1,284 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "test_functions.hpp" - -namespace pt = boost::posix_time; -namespace tsk = boost::tasks; - -// check assignment -void test_case_1() -{ - tsk::task< int > t( fibonacci_fn, 10); - tsk::handle< int > h1; - tsk::handle< int > h2( - tsk::async( boost::move( t), tsk::new_thread() ) ); - h1 = h2; - BOOST_CHECK_EQUAL( h1.get(), 55); - BOOST_CHECK_EQUAL( h2.get(), 55); -} - -// check swap -void test_case_2() -{ - tsk::task< int > t1( fibonacci_fn, 5); - tsk::task< int > t2( fibonacci_fn, 10); - tsk::handle< int > h1( - tsk::async( boost::move( t1), tsk::new_thread() ) ); - tsk::handle< int > h2( - tsk::async( boost::move( t2), tsk::new_thread() ) ); - BOOST_CHECK_EQUAL( h1.get(), 5); - BOOST_CHECK_EQUAL( h2.get(), 55); - BOOST_CHECK_NO_THROW( h1.swap( h2) ); - BOOST_CHECK_EQUAL( h1.get(), 55); - BOOST_CHECK_EQUAL( h2.get(), 5); -} - -// check runs not in pool -void test_case_3() -{ - tsk::task< bool > t( runs_in_pool_fn); - tsk::handle< bool > h( - tsk::async( boost::move( t), tsk::new_thread() ) ); - BOOST_CHECK_EQUAL( h.get(), false); -} - -// check runtime_error throw inside task -void test_case_4() -{ - tsk::task< void > t( throwing_fn); - tsk::handle< void > h( - tsk::async( boost::move( t), tsk::new_thread() ) ); - BOOST_CHECK_THROW( h.get(), std::runtime_error); -} - -// check wait -void test_case_5() -{ - tsk::task< int > t( fibonacci_fn, 10); - tsk::handle< int > h( - tsk::async( boost::move( t), tsk::new_thread() ) ); - h.wait(); - BOOST_CHECK( h.is_ready() ); - BOOST_CHECK( h.has_value() ); - BOOST_CHECK( ! h.has_exception() ); - BOOST_CHECK_EQUAL( h.get(), 55); -} - -// check wait_for -void test_case_6() -{ - tsk::task< void > t( delay_fn, pt::seconds( 1) ); - tsk::handle< void > h( - tsk::async( boost::move( t), tsk::new_thread() ) ); - BOOST_CHECK( h.wait_for( pt::seconds( 3) ) ); - BOOST_CHECK( h.is_ready() ); - BOOST_CHECK( h.has_value() ); - BOOST_CHECK( ! h.has_exception() ); -} - -// check wait_for -void test_case_7() -{ - tsk::task< void > t( delay_fn, pt::seconds( 3) ); - tsk::handle< void > h( - tsk::async( boost::move( t), tsk::new_thread() ) ); - BOOST_CHECK( ! h.wait_for( pt::seconds( 1) ) ); - BOOST_CHECK( ! h.is_ready() ); - BOOST_CHECK( ! h.has_value() ); - BOOST_CHECK( ! h.has_exception() ); -} - -// check wait_for -void test_case_8() -{ - tsk::task< void > t( delay_fn, pt::seconds( 1) ); - tsk::handle< void > h( - tsk::async( boost::move( t), tsk::new_thread() ) ); - BOOST_CHECK( h.wait_until( boost::get_system_time() + pt::seconds( 3) ) ); - BOOST_CHECK( h.is_ready() ); - BOOST_CHECK( h.has_value() ); - BOOST_CHECK( ! h.has_exception() ); -} - -// check wait_for -void test_case_9() -{ - tsk::task< void > t( delay_fn, pt::seconds( 3) ); - tsk::handle< void > h( - tsk::async( boost::move( t), tsk::new_thread() ) ); - BOOST_CHECK( ! h.wait_until( boost::get_system_time() + pt::seconds( 1) ) ); - BOOST_CHECK( ! h.is_ready() ); - BOOST_CHECK( ! h.has_value() ); - BOOST_CHECK( ! h.has_exception() ); -} - -// check interrupt -void test_case_10() -{ - tsk::task< void > t( delay_fn, pt::seconds( 3) ); - tsk::handle< void > h( - tsk::async( boost::move( t), tsk::new_thread() ) ); - h.interrupt(); - BOOST_CHECK( h.interruption_requested() ); - BOOST_CHECK_THROW( h.get(), tsk::task_interrupted); -} - -// check interrupt_and_wait -void test_case_11() -{ - bool finished( false); - tsk::task< void > t( - interrupt_fn, - pt::seconds( 1), - boost::ref( finished) ); - tsk::handle< void > h( - tsk::async( boost::move( t), tsk::new_thread() ) ); - h.interrupt_and_wait(); - BOOST_CHECK( finished); - BOOST_CHECK( h.is_ready() ); - BOOST_CHECK( ! h.has_value() ); - BOOST_CHECK( h.has_exception() ); - BOOST_CHECK( h.interruption_requested() ); - BOOST_CHECK_THROW( h.get(), tsk::task_interrupted); -} - -// check interrupt_and_wait_for -void test_case_12() -{ - bool finished( false); - tsk::task< void > t( - interrupt_fn, - pt::seconds( 1), - boost::ref( finished) ); - tsk::handle< void > h( - tsk::async( boost::move( t), tsk::new_thread() ) ); - BOOST_CHECK( h.interrupt_and_wait_for( pt::seconds( 3) ) ); - BOOST_CHECK( finished); - BOOST_CHECK( h.is_ready() ); - BOOST_CHECK( ! h.has_value() ); - BOOST_CHECK( h.has_exception() ); - BOOST_CHECK( h.interruption_requested() ); - BOOST_CHECK_THROW( h.get(), tsk::task_interrupted); -} - -// check interrupt_and_wait_for -void test_case_13() -{ - tsk::task< void > t( non_interrupt_fn, 3); - tsk::handle< void > h( - tsk::async( boost::move( t), tsk::new_thread() ) ); - BOOST_CHECK( ! h.interrupt_and_wait_for( pt::seconds( 1) ) ); -} - -// check interrupt_and_wait_until -void test_case_14() -{ - bool finished( false); - tsk::task< void > t( - interrupt_fn, - pt::seconds( 1), - boost::ref( finished) ); - tsk::handle< void > h( - tsk::async( boost::move( t), tsk::new_thread() ) ); - BOOST_CHECK( h.interrupt_and_wait_until( boost::get_system_time() + pt::seconds( 3) ) ); - BOOST_CHECK( finished); - BOOST_CHECK( h.is_ready() ); - BOOST_CHECK( ! h.has_value() ); - BOOST_CHECK( h.has_exception() ); - BOOST_CHECK( h.interruption_requested() ); - BOOST_CHECK_THROW( h.get(), tsk::task_interrupted); -} - -// check interrupt_and_wait_until -void test_case_15() -{ - tsk::task< void > t( non_interrupt_fn, 3); - tsk::handle< void > h( - tsk::async( boost::move( t), tsk::new_thread() ) ); - BOOST_CHECK( ! h.interrupt_and_wait_until( boost::get_system_time() + pt::seconds( 1) ) ); -} - -// check waitfor_all() -void test_case_16() -{ - std::vector< tsk::handle< int > > vec; - for ( int i = 0; i <= 5; ++i) - { - tsk::task< int > t( fibonacci_fn, i); - vec.push_back( - tsk::async( boost::move( t), tsk::new_thread() ) ); - } - tsk::waitfor_all( vec.begin(), vec.end() ); - BOOST_CHECK( vec[0].is_ready() ); - BOOST_CHECK( vec[1].is_ready() ); - BOOST_CHECK( vec[2].is_ready() ); - BOOST_CHECK( vec[3].is_ready() ); - BOOST_CHECK( vec[4].is_ready() ); - BOOST_CHECK( vec[5].is_ready() ); - BOOST_CHECK_EQUAL( vec[0].get(), 0); - BOOST_CHECK_EQUAL( vec[1].get(), 1); - BOOST_CHECK_EQUAL( vec[2].get(), 1); - BOOST_CHECK_EQUAL( vec[3].get(), 2); - BOOST_CHECK_EQUAL( vec[4].get(), 3); - BOOST_CHECK_EQUAL( vec[5].get(), 5); -} -/* -// check waitfor_any() -void test_case_17() -{ - tsk::task< void > t1( delay_fn, pt::seconds( 2) ); - tsk::task< void > t2( delay_fn, pt::seconds( 1) ); - tsk::handle< void > h1( - tsk::async( boost::move( t1), tsk::new_thread() ) ); - tsk::handle< void > h2( - tsk::async( boost::move( t2), tsk::new_thread() ) ); - tsk::waitfor_any( h1, h2); - BOOST_CHECK( ! h1.is_ready() ); - BOOST_CHECK( h2.is_ready() ); -} -*/ -boost::unit_test::test_suite * init_unit_test_suite( int, char* []) -{ - boost::unit_test::test_suite * test = - BOOST_TEST_SUITE("Boost.Task: new-thread test suite"); - - test->add( BOOST_TEST_CASE( & test_case_1) ); - test->add( BOOST_TEST_CASE( & test_case_2) ); - test->add( BOOST_TEST_CASE( & test_case_3) ); - test->add( BOOST_TEST_CASE( & test_case_4) ); - test->add( BOOST_TEST_CASE( & test_case_5) ); - test->add( BOOST_TEST_CASE( & test_case_6) ); - test->add( BOOST_TEST_CASE( & test_case_7) ); - test->add( BOOST_TEST_CASE( & test_case_8) ); - test->add( BOOST_TEST_CASE( & test_case_9) ); - test->add( BOOST_TEST_CASE( & test_case_10) ); - test->add( BOOST_TEST_CASE( & test_case_11) ); - test->add( BOOST_TEST_CASE( & test_case_12) ); - test->add( BOOST_TEST_CASE( & test_case_13) ); - test->add( BOOST_TEST_CASE( & test_case_14) ); - test->add( BOOST_TEST_CASE( & test_case_15) ); - test->add( BOOST_TEST_CASE( & test_case_16) ); -// test->add( BOOST_TEST_CASE( & test_case_17) ); - - return test; -} diff --git a/libs/task/test/test_own_thread.cpp b/libs/task/test/test_own_thread.cpp deleted file mode 100644 index 63c275ef..00000000 --- a/libs/task/test/test_own_thread.cpp +++ /dev/null @@ -1,312 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "test_functions.hpp" - -namespace pt = boost::posix_time; -namespace tsk = boost::tasks; - -// check assignment -void test_case_1() -{ - tsk::task< int > t( fibonacci_fn, 10); - tsk::handle< int > h1; - tsk::handle< int > h2( - tsk::async( boost::move( t), tsk::own_thread() ) ); - h1 = h2; - BOOST_CHECK_EQUAL( h1.get(), 55); - BOOST_CHECK_EQUAL( h2.get(), 55); -} - -// check swap -void test_case_2() -{ - tsk::task< int > t1( fibonacci_fn, 5); - tsk::task< int > t2( fibonacci_fn, 10); - tsk::handle< int > h1( - tsk::async( boost::move( t1), tsk::own_thread() ) ); - tsk::handle< int > h2( - tsk::async( boost::move( t2), tsk::own_thread() ) ); - BOOST_CHECK_EQUAL( h1.get(), 5); - BOOST_CHECK_EQUAL( h2.get(), 55); - BOOST_CHECK_NO_THROW( h1.swap( h2) ); - BOOST_CHECK_EQUAL( h1.get(), 55); - BOOST_CHECK_EQUAL( h2.get(), 5); -} - -// check runs not in pool -void test_case_3() -{ - tsk::task< bool > t( runs_in_pool_fn); - tsk::handle< bool > h( - tsk::async( boost::move( t), tsk::own_thread() ) ); - BOOST_CHECK_EQUAL( h.get(), false); -} - -// check runtime_error throw inside task -void test_case_4() -{ - tsk::task< void > t( throwing_fn); - tsk::handle< void > h( - tsk::async( boost::move( t), tsk::own_thread() ) ); - BOOST_CHECK_THROW( h.get(), std::runtime_error); -} - -// check task_uninitialized -void test_case_5() -{ - tsk::handle< int > h; - BOOST_CHECK_THROW( h.get(), tsk::task_uninitialized); - BOOST_CHECK_THROW( h.wait(), tsk::task_uninitialized); - BOOST_CHECK_THROW( h.wait_for( pt::seconds( 1) ), tsk::task_uninitialized); - BOOST_CHECK_THROW( - h.wait_until( boost::get_system_time() + pt::seconds( 1) ), - tsk::task_uninitialized); - BOOST_CHECK( ! h.is_ready() ); - BOOST_CHECK( ! h.has_value() ); - BOOST_CHECK( ! h.has_exception() ); -} - -// check wait -void test_case_6() -{ - tsk::task< int > t( fibonacci_fn, 10); - tsk::handle< int > h( - tsk::async( boost::move( t), tsk::own_thread() ) ); - h.wait(); - BOOST_CHECK( h.is_ready() ); - BOOST_CHECK( h.has_value() ); - BOOST_CHECK( ! h.has_exception() ); - BOOST_CHECK_EQUAL( h.get(), 55); -} - -// check wait_for -void test_case_7() -{ - tsk::task< void > t( delay_fn, pt::seconds( 1) ); - tsk::handle< void > h( - tsk::async( boost::move( t), tsk::own_thread() ) ); - BOOST_CHECK( h.wait_for( pt::seconds( 2) ) ); - BOOST_CHECK( h.is_ready() ); - BOOST_CHECK( h.has_value() ); - BOOST_CHECK( ! h.has_exception() ); -} - -// check wait_for -void test_case_8() -{ - tsk::task< void > t( delay_fn, pt::seconds( 2) ); - tsk::handle< void > h( - tsk::async( boost::move( t), tsk::own_thread() ) ); - BOOST_CHECK( h.wait_for( pt::seconds( 1) ) ); - BOOST_CHECK( h.is_ready() ); - BOOST_CHECK( h.has_value() ); - BOOST_CHECK( ! h.has_exception() ); -} - -// check wait_for -void test_case_9() -{ - tsk::task< void > t( delay_fn, pt::seconds( 1) ); - tsk::handle< void > h( - tsk::async( boost::move( t), tsk::own_thread() ) ); - BOOST_CHECK( h.wait_until( boost::get_system_time() + pt::seconds( 3) ) ); - BOOST_CHECK( h.is_ready() ); - BOOST_CHECK( h.has_value() ); - BOOST_CHECK( ! h.has_exception() ); -} - -// check wait_for -void test_case_10() -{ - tsk::task< void > t( delay_fn, pt::seconds( 2) ); - tsk::handle< void > h( - tsk::async( boost::move( t), tsk::own_thread() ) ); - BOOST_CHECK( h.wait_until( boost::get_system_time() + pt::seconds( 1) ) ); - BOOST_CHECK( h.is_ready() ); - BOOST_CHECK( h.has_value() ); - BOOST_CHECK( ! h.has_exception() ); -} - -// check interrupt -void test_case_11() -{ - tsk::task< void > t( delay_fn, pt::seconds( 3) ); - tsk::handle< void > h( - tsk::async( boost::move( t), tsk::own_thread() ) ); - h.interrupt(); - BOOST_CHECK( h.interruption_requested() ); - BOOST_CHECK_NO_THROW( h.get() ); -} - -// check interrupt_and_wait -void test_case_12() -{ - bool finished( false); - tsk::task< void > t( - interrupt_fn, - pt::seconds( 3), - boost::ref( finished) ); - tsk::handle< void > h( - tsk::async( boost::move( t), tsk::own_thread() ) ); - h.interrupt_and_wait(); - BOOST_CHECK( ! finished); - BOOST_CHECK( h.is_ready() ); - BOOST_CHECK( h.interruption_requested() ); - BOOST_CHECK_NO_THROW( h.get() ); -} - -// check interrupt_and_wait_for -void test_case_13() -{ - bool finished( false); - tsk::task< void > t( - interrupt_fn, - pt::seconds( 1), - boost::ref( finished) ); - tsk::handle< void > h( - tsk::async( boost::move( t), tsk::own_thread() ) ); - BOOST_CHECK( h.interrupt_and_wait_for( pt::seconds( 2) ) ); - BOOST_CHECK( ! finished); - BOOST_CHECK( h.is_ready() ); - BOOST_CHECK( h.has_value() ); - BOOST_CHECK( ! h.has_exception() ); - BOOST_CHECK( h.interruption_requested() ); - BOOST_CHECK_NO_THROW( h.get() ); -} - -// check interrupt_and_wait_for -void test_case_14() -{ - tsk::task< void > t( non_interrupt_fn, 2); - tsk::handle< void > h( - tsk::async( boost::move( t), tsk::own_thread() ) ); - BOOST_CHECK( h.interrupt_and_wait_for( pt::seconds( 1) ) ); - BOOST_CHECK_NO_THROW( h.get() ); -} - -// check interrupt_and_wait_until -void test_case_15() -{ - bool finished( false); - tsk::task< void > t( - interrupt_fn, - pt::seconds( 1), - boost::ref( finished) ); - tsk::handle< void > h( - tsk::async( boost::move( t), tsk::own_thread() ) ); - BOOST_CHECK( h.interrupt_and_wait_until( boost::get_system_time() + pt::seconds( 2) ) ); - BOOST_CHECK( ! finished); - BOOST_CHECK( h.is_ready() ); - BOOST_CHECK( h.has_value() ); - BOOST_CHECK( ! h.has_exception() ); - BOOST_CHECK( h.interruption_requested() ); - BOOST_CHECK_NO_THROW( h.get() ); -} - -// check interrupt_and_wait_until -void test_case_16() -{ - tsk::task< void > t( non_interrupt_fn, 2); - tsk::handle< void > h( - tsk::async( boost::move( t), tsk::own_thread() ) ); - BOOST_CHECK( h.interrupt_and_wait_until( boost::get_system_time() + pt::seconds( 1) ) ); - BOOST_CHECK_NO_THROW( h.get() ); -} - -// check waitfor_all() -void test_case_17() -{ - std::vector< tsk::handle< int > > vec; - for ( int i = 0; i <= 5; ++i) - { - tsk::task< int > t( fibonacci_fn, i); - vec.push_back( - tsk::async( boost::move( t), tsk::own_thread() ) ); - } - tsk::waitfor_all( vec.begin(), vec.end() ); - BOOST_CHECK( vec[0].is_ready() ); - BOOST_CHECK( vec[1].is_ready() ); - BOOST_CHECK( vec[2].is_ready() ); - BOOST_CHECK( vec[3].is_ready() ); - BOOST_CHECK( vec[4].is_ready() ); - BOOST_CHECK( vec[5].is_ready() ); - BOOST_CHECK_EQUAL( vec[0].get(), 0); - BOOST_CHECK_EQUAL( vec[1].get(), 1); - BOOST_CHECK_EQUAL( vec[2].get(), 1); - BOOST_CHECK_EQUAL( vec[3].get(), 2); - BOOST_CHECK_EQUAL( vec[4].get(), 3); - BOOST_CHECK_EQUAL( vec[5].get(), 5); -} -/* -// check waitfor_any() -void test_case_18() -{ - tsk::task< void > t1( delay_fn, pt::seconds( 2) ); - tsk::task< void > t2( delay_fn, pt::seconds( 1) ); - tsk::handle< void > h1( - tsk::async( boost::move( t1), tsk::own_thread() ) ); - tsk::handle< void > h2( - tsk::async( boost::move( t2), tsk::own_thread() ) ); - tsk::waitfor_any( h1, h2); - BOOST_CHECK( h1.is_ready() ); - BOOST_CHECK( h2.is_ready() ); -} -*/ -// check interrupt + wait -void test_case_19() -{ - tsk::task< void > t( delay_fn, pt::seconds( 3) ); - tsk::handle< void > h( - tsk::async( boost::move( t), tsk::own_thread() ) ); - h.interrupt(); - BOOST_CHECK_NO_THROW( h.wait() ); - BOOST_CHECK_NO_THROW( h.get() ); -} - -boost::unit_test::test_suite * init_unit_test_suite( int, char* []) -{ - boost::unit_test::test_suite * test = - BOOST_TEST_SUITE("Boost.Task: own-thread test suite"); - - test->add( BOOST_TEST_CASE( & test_case_1) ); - test->add( BOOST_TEST_CASE( & test_case_2) ); - test->add( BOOST_TEST_CASE( & test_case_3) ); - test->add( BOOST_TEST_CASE( & test_case_4) ); - test->add( BOOST_TEST_CASE( & test_case_5) ); - test->add( BOOST_TEST_CASE( & test_case_6) ); - test->add( BOOST_TEST_CASE( & test_case_7) ); - test->add( BOOST_TEST_CASE( & test_case_8) ); - test->add( BOOST_TEST_CASE( & test_case_9) ); - test->add( BOOST_TEST_CASE( & test_case_10) ); - test->add( BOOST_TEST_CASE( & test_case_11) ); - test->add( BOOST_TEST_CASE( & test_case_12) ); - test->add( BOOST_TEST_CASE( & test_case_13) ); - test->add( BOOST_TEST_CASE( & test_case_14) ); - test->add( BOOST_TEST_CASE( & test_case_15) ); - test->add( BOOST_TEST_CASE( & test_case_16) ); - test->add( BOOST_TEST_CASE( & test_case_17) ); -// test->add( BOOST_TEST_CASE( & test_case_18) ); - test->add( BOOST_TEST_CASE( & test_case_19) ); - - return test; -} diff --git a/libs/task/test/test_spin_auto_reset_event.cpp b/libs/task/test/test_spin_auto_reset_event.cpp deleted file mode 100755 index 363edd72..00000000 --- a/libs/task/test/test_spin_auto_reset_event.cpp +++ /dev/null @@ -1,210 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace pt = boost::posix_time; -namespace tsk = boost::tasks; - -boost::uint32_t wait_fn( boost::uint32_t n, tsk::spin::auto_reset_event & ev) -{ - ev.wait(); - return n; -} - -// check wait in new thread -void test_case_1() -{ - boost::uint32_t n = 3; - tsk::spin::auto_reset_event ev; - - tsk::handle< boost::uint32_t > h1( - tsk::async( - tsk::make_task( - wait_fn, - n, boost::ref( ev) ), - tsk::new_thread() ) ); - tsk::handle< boost::uint32_t > h2( - tsk::async( - tsk::make_task( - wait_fn, - n, boost::ref( ev) ), - tsk::new_thread() ) ); - - boost::this_thread::sleep( pt::millisec( 250) ); - BOOST_CHECK( ! h1.is_ready() ); - BOOST_CHECK( ! h2.is_ready() ); - - ev.set(); - - boost::this_thread::sleep( pt::millisec( 250) ); - BOOST_CHECK( h1.is_ready() || h2.is_ready() ); - if ( h1.is_ready() ) - { - BOOST_CHECK_EQUAL( h1.get(), n); - BOOST_CHECK( ! h2.is_ready() ); - - ev.set(); - - boost::this_thread::sleep( pt::millisec( 250) ); - BOOST_CHECK( h2.is_ready() ); - BOOST_CHECK_EQUAL( h2.get(), n); - } - else - { - BOOST_CHECK( h2.is_ready() ); - BOOST_CHECK_EQUAL( h2.get(), n); - BOOST_CHECK( ! h1.is_ready() ); - - ev.set(); - - boost::this_thread::sleep( pt::millisec( 250) ); - BOOST_CHECK( h1.is_ready() ); - BOOST_CHECK_EQUAL( h1.get(), n); - - } -} - -// check wait in pool -void test_case_2() -{ - tsk::static_pool< - tsk::unbounded_fifo - > pool( tsk::poolsize( 3) ); - - boost::uint32_t n = 3; - tsk::spin::auto_reset_event ev; - - tsk::handle< boost::uint32_t > h1( - tsk::async( - tsk::make_task( - wait_fn, - n, boost::ref( ev) ), - pool) ); - tsk::handle< boost::uint32_t > h2( - tsk::async( - tsk::make_task( - wait_fn, - n, boost::ref( ev) ), - pool) ); - boost::this_thread::sleep( pt::millisec( 250) ); - BOOST_CHECK( ! h1.is_ready() ); - BOOST_CHECK( ! h2.is_ready() ); - - ev.set(); - - boost::this_thread::sleep( pt::millisec( 250) ); - BOOST_CHECK( h1.is_ready() || h2.is_ready() ); - if ( h1.is_ready() ) - { - BOOST_CHECK_EQUAL( h1.get(), n); - BOOST_CHECK( ! h2.is_ready() ); - - ev.set(); - - boost::this_thread::sleep( pt::millisec( 250) ); - BOOST_CHECK( h2.is_ready() ); - BOOST_CHECK_EQUAL( h2.get(), n); - } - else - { - BOOST_CHECK( h2.is_ready() ); - BOOST_CHECK_EQUAL( h2.get(), n); - BOOST_CHECK( ! h1.is_ready() ); - - ev.set(); - - boost::this_thread::sleep( pt::millisec( 250) ); - BOOST_CHECK( h1.is_ready() ); - BOOST_CHECK_EQUAL( h1.get(), n); - - } -} - -void test_case_3() -{ - boost::uint32_t n = 3; - tsk::spin::auto_reset_event ev( true); - - tsk::handle< boost::uint32_t > h1( - tsk::async( - tsk::make_task( - wait_fn, - n, boost::ref( ev) ), - tsk::new_thread() ) ); - tsk::handle< boost::uint32_t > h2( - tsk::async( - tsk::make_task( - wait_fn, - n, boost::ref( ev) ), - tsk::new_thread() ) ); - - boost::this_thread::sleep( pt::millisec( 250) ); - BOOST_CHECK( h1.is_ready() || h2.is_ready() ); - if ( h1.is_ready() ) - { - BOOST_CHECK_EQUAL( h1.get(), n); - BOOST_CHECK( ! h2.is_ready() ); - - ev.set(); - - boost::this_thread::sleep( pt::millisec( 250) ); - BOOST_CHECK( h2.is_ready() ); - BOOST_CHECK_EQUAL( h2.get(), n); - } - else - { - BOOST_CHECK( h2.is_ready() ); - BOOST_CHECK_EQUAL( h2.get(), n); - BOOST_CHECK( ! h1.is_ready() ); - - ev.set(); - - boost::this_thread::sleep( pt::millisec( 250) ); - BOOST_CHECK( h1.is_ready() ); - BOOST_CHECK_EQUAL( h1.get(), n); - - } -} - -void test_case_4() -{ - tsk::spin::auto_reset_event ev; - - BOOST_CHECK_EQUAL( false, ev.try_wait() ); - - ev.set(); - - BOOST_CHECK_EQUAL( true, ev.try_wait() ); - BOOST_CHECK_EQUAL( false, ev.try_wait() ); -} - -boost::unit_test::test_suite * init_unit_test_suite( int, char* []) -{ - boost::unit_test::test_suite * test = - BOOST_TEST_SUITE("Boost.Task: spin-auto-reset-event test suite"); - - test->add( BOOST_TEST_CASE( & test_case_1) ); - test->add( BOOST_TEST_CASE( & test_case_2) ); - test->add( BOOST_TEST_CASE( & test_case_3) ); - - return test; -} diff --git a/libs/task/test/test_spin_bounded_channel.cpp b/libs/task/test/test_spin_bounded_channel.cpp deleted file mode 100644 index 1662af0a..00000000 --- a/libs/task/test/test_spin_bounded_channel.cpp +++ /dev/null @@ -1,171 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace pt = boost::posix_time; -namespace tsk = boost::tasks; - -struct send_data -{ - tsk::spin::bounded_channel< int > & buf; - - send_data( tsk::spin::bounded_channel< int > & buf_) : - buf( buf_) - {} - - void operator()( int value) - { buf.put( value); } -}; - -struct recv_data -{ - tsk::spin::bounded_channel< int > & buf; - int value; - - recv_data( tsk::spin::bounded_channel< int > & buf_) : - buf( buf_), value( 0) - {} - - void operator()( ) - { - boost::optional< int > res; - if ( buf.take( res) ) - value = * res; - } -}; - -void test_case_1() -{ - tsk::spin::bounded_channel< int > buf( tsk::high_watermark( 10), tsk::low_watermark( 10) ); - BOOST_CHECK_EQUAL( true, buf.empty() ); - BOOST_CHECK_EQUAL( true, buf.active() ); - int n = 1; - buf.put( n); - BOOST_CHECK_EQUAL( false, buf.empty() ); - boost::optional< int > res; - BOOST_CHECK_EQUAL( true, buf.take( res) ); - BOOST_CHECK( res); - BOOST_CHECK_EQUAL( n, res.get() ); - buf.deactivate(); - BOOST_CHECK_EQUAL( false, buf.active() ); - BOOST_CHECK_THROW( buf.put( 1), std::runtime_error); -} - -void test_case_2() -{ - tsk::spin::bounded_channel< int > buf( tsk::high_watermark( 10), tsk::low_watermark( 10) ); - BOOST_CHECK_EQUAL( true, buf.empty() ); - BOOST_CHECK_EQUAL( true, buf.active() ); - int n = 1; - buf.put( n); - BOOST_CHECK_EQUAL( false, buf.empty() ); - boost::optional< int > res; - BOOST_CHECK_EQUAL( true, buf.try_take( res) ); - BOOST_CHECK( res); - BOOST_CHECK_EQUAL( n, res.get() ); - BOOST_CHECK_EQUAL( false, buf.try_take( res) ); - BOOST_CHECK_EQUAL( false, buf.take( res, pt::milliseconds( 10) ) ); -} - -void test_case_3() -{ - tsk::static_pool< - tsk::unbounded_fifo - > pool( tsk::poolsize( 2) ); - - tsk::spin::bounded_channel< int > buf( tsk::high_watermark( 10), tsk::low_watermark( 10) ); - - int n = 37; - - recv_data receiver( buf); - BOOST_CHECK_EQUAL( 0, receiver.value); - tsk::handle< void > h = - tsk::async( - tsk::make_task( - & recv_data::operator(), - boost::ref( receiver) ), - pool); - - boost::this_thread::sleep( - pt::milliseconds( 250) ); - - BOOST_CHECK_EQUAL( false, h.is_ready() ); - buf.put( n); - - h.wait(); - - BOOST_CHECK_EQUAL( n, receiver.value); -} - -void test_case_4() -{ - tsk::static_pool< - tsk::unbounded_fifo - > pool( tsk::poolsize( 2) ); - - tsk::spin::bounded_channel< int > buf( tsk::high_watermark( 10), tsk::low_watermark( 10) ); - - int n = 37; - - send_data sender( buf); - recv_data receiver( buf); - BOOST_CHECK_EQUAL( 0, receiver.value); - - tsk::handle< void > h1 = - tsk::async( - tsk::make_task( - & recv_data::operator(), - boost::ref( receiver) ), - pool); - - boost::this_thread::sleep( - pt::milliseconds( 250) ); - BOOST_CHECK_EQUAL( false, h1.is_ready() ); - - tsk::handle< void > h2 = - tsk::async( - tsk::make_task( - & send_data::operator(), - boost::ref( sender), - n), - pool); - - h2.wait(); - BOOST_CHECK_EQUAL( true, h2.is_ready() ); - h1.wait(); - BOOST_CHECK_EQUAL( true, h1.is_ready() ); - - BOOST_CHECK_EQUAL( n, receiver.value); -} - -boost::unit_test::test_suite * init_unit_test_suite( int, char* []) -{ - boost::unit_test::test_suite * test = - BOOST_TEST_SUITE("Boost.Task: bounded-buffer test suite"); - - test->add( BOOST_TEST_CASE( & test_case_1) ); - test->add( BOOST_TEST_CASE( & test_case_2) ); - test->add( BOOST_TEST_CASE( & test_case_3) ); - test->add( BOOST_TEST_CASE( & test_case_4) ); - - return test; -} diff --git a/libs/task/test/test_spin_condition.cpp b/libs/task/test/test_spin_condition.cpp deleted file mode 100644 index eeeb7121..00000000 --- a/libs/task/test/test_spin_condition.cpp +++ /dev/null @@ -1,191 +0,0 @@ -// Copyright (C) 2001-2003 -// William E. Kempf -// Copyright (C) 2007 Anthony Williams -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -#include -#include -#include - -#include - -#include - -namespace tsk = boost::tasks; -namespace pt = boost::posix_time; - -struct condition_test_data -{ - condition_test_data() : notified(0), awoken(0) { } - - tsk::spin::mutex mutex; - tsk::spin::condition condition; - int notified; - int awoken; -}; - -void condition_test_thread(condition_test_data* data) -{ - tsk::spin::mutex::scoped_lock lock(data->mutex); - BOOST_CHECK(lock ? true : false); - while (!(data->notified > 0)) - data->condition.wait(lock); - BOOST_CHECK(lock ? true : false); - data->awoken++; -} - -struct cond_predicate -{ - cond_predicate(int& var, int val) : _var(var), _val(val) { } - - bool operator()() { return _var == _val; } - - int& _var; - int _val; -private: - void operator=(cond_predicate&); - -}; - -void condition_test_waits(condition_test_data* data) -{ - tsk::spin::mutex::scoped_lock lock(data->mutex); - BOOST_CHECK(lock ? true : false); - - // Test wait. - while (data->notified != 1) - data->condition.wait(lock); - BOOST_CHECK(lock ? true : false); - BOOST_CHECK_EQUAL(data->notified, 1); - data->awoken++; - data->condition.notify_one(); - - // Test predicate wait. - data->condition.wait(lock, cond_predicate(data->notified, 2)); - BOOST_CHECK(lock ? true : false); - BOOST_CHECK_EQUAL(data->notified, 2); - data->awoken++; - data->condition.notify_one(); - - // Test timed_wait. - pt::time_duration xt = pt::seconds(10); - while (data->notified != 3) - data->condition.timed_wait(lock, xt); - BOOST_CHECK(lock ? true : false); - BOOST_CHECK_EQUAL(data->notified, 3); - data->awoken++; - data->condition.notify_one(); - - // Test predicate timed_wait. - xt = pt::seconds(10); - cond_predicate pred(data->notified, 4); - BOOST_CHECK(data->condition.timed_wait(lock, xt, pred)); - BOOST_CHECK(lock ? true : false); - BOOST_CHECK(pred()); - BOOST_CHECK_EQUAL(data->notified, 4); - data->awoken++; - data->condition.notify_one(); - - // Test predicate timed_wait with relative timeout - cond_predicate pred_rel(data->notified, 5); - BOOST_CHECK(data->condition.timed_wait(lock, boost::posix_time::seconds(10), pred_rel)); - BOOST_CHECK(lock ? true : false); - BOOST_CHECK(pred_rel()); - BOOST_CHECK_EQUAL(data->notified, 5); - data->awoken++; - data->condition.notify_one(); -} - -void do_test_condition_waits() -{ - condition_test_data data; - - boost::thread thread(bind(&condition_test_waits, &data)); - - { - tsk::spin::mutex::scoped_lock lock(data.mutex); - BOOST_CHECK(lock ? true : false); - - boost::this_thread::sleep(pt::seconds(1)); - data.notified++; - data.condition.notify_one(); - while (data.awoken != 1) - data.condition.wait(lock); - BOOST_CHECK(lock ? true : false); - BOOST_CHECK_EQUAL(data.awoken, 1); - - boost::this_thread::sleep(pt::seconds(1)); - data.notified++; - data.condition.notify_one(); - while (data.awoken != 2) - data.condition.wait(lock); - BOOST_CHECK(lock ? true : false); - BOOST_CHECK_EQUAL(data.awoken, 2); - - boost::this_thread::sleep(pt::seconds(1)); - data.notified++; - data.condition.notify_one(); - while (data.awoken != 3) - data.condition.wait(lock); - BOOST_CHECK(lock ? true : false); - BOOST_CHECK_EQUAL(data.awoken, 3); - - boost::this_thread::sleep(pt::seconds(1)); - data.notified++; - data.condition.notify_one(); - while (data.awoken != 4) - data.condition.wait(lock); - BOOST_CHECK(lock ? true : false); - BOOST_CHECK_EQUAL(data.awoken, 4); - - - boost::this_thread::sleep(pt::seconds(1)); - data.notified++; - data.condition.notify_one(); - while (data.awoken != 5) - data.condition.wait(lock); - BOOST_CHECK(lock ? true : false); - BOOST_CHECK_EQUAL(data.awoken, 5); - } - - thread.join(); - BOOST_CHECK_EQUAL(data.awoken, 5); -} - -void test_condition_waits() -{ - // We should have already tested notify_one here, so - // a timed test with the default execution_monitor::use_condition - // should be OK, and gives the fastest performance - timed_test(&do_test_condition_waits, 12); -} - -void do_test_condition_wait_is_a_interruption_point() -{ - condition_test_data data; - - boost::thread thread(bind(&condition_test_thread, &data)); - - thread.interrupt(); - thread.join(); - BOOST_CHECK_EQUAL(data.awoken,0); -} - - -void test_condition_wait_is_a_interruption_point() -{ - timed_test(&do_test_condition_wait_is_a_interruption_point, 1); -} - -boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[]) -{ - boost::unit_test_framework::test_suite* test = - BOOST_TEST_SUITE("Boost.Task: condition test suite"); - - test->add(BOOST_TEST_CASE(&test_condition_waits)); - test->add(BOOST_TEST_CASE(&test_condition_wait_is_a_interruption_point)); - - return test; -} diff --git a/libs/task/test/test_spin_condition_notify_all.cpp b/libs/task/test/test_spin_condition_notify_all.cpp deleted file mode 100644 index f34b996a..00000000 --- a/libs/task/test/test_spin_condition_notify_all.cpp +++ /dev/null @@ -1,225 +0,0 @@ -// Copyright (C) 2007 Anthony Williams -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -#include -#include - -#include - -#include - -#include - -#include "condition_test_common.hpp" - -namespace tsk = boost::tasks; - -unsigned const number_of_test_threads=5; - -void do_test_condition_notify_all_wakes_from_wait() -{ - wait_for_flag data; - - boost::thread_group group; - - try - { - for(unsigned i=0;iadd(BOOST_TEST_CASE(&test_condition_notify_all)); - - return test; -} diff --git a/libs/task/test/test_spin_condition_notify_one.cpp b/libs/task/test/test_spin_condition_notify_one.cpp deleted file mode 100644 index 9986e1b1..00000000 --- a/libs/task/test/test_spin_condition_notify_one.cpp +++ /dev/null @@ -1,159 +0,0 @@ -// Copyright (C) 2007 Anthony Williams -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -#include -#include - -#include - -#include - -#include - -#include "condition_test_common.hpp" - -namespace tsk = boost::tasks; - -void do_test_condition_notify_one_wakes_from_wait() -{ - wait_for_flag data; - - boost::thread thread(boost::bind(&wait_for_flag::wait_without_predicate, boost::ref(data))); - - { - tsk::spin::mutex::scoped_lock lock(data.mutex); - data.flag=true; - data.cond_var.notify_one(); - } - - thread.join(); - BOOST_CHECK(data.woken); -} - -void do_test_condition_notify_one_wakes_from_wait_with_predicate() -{ - wait_for_flag data; - - boost::thread thread(boost::bind(&wait_for_flag::wait_with_predicate, boost::ref(data))); - - { - tsk::spin::mutex::scoped_lock lock(data.mutex); - data.flag=true; - data.cond_var.notify_one(); - } - - thread.join(); - BOOST_CHECK(data.woken); -} - -void do_test_condition_notify_one_wakes_from_timed_wait() -{ - wait_for_flag data; - - boost::thread thread(boost::bind(&wait_for_flag::timed_wait_without_predicate, boost::ref(data))); - - { - tsk::spin::mutex::scoped_lock lock(data.mutex); - data.flag=true; - data.cond_var.notify_one(); - } - - thread.join(); - BOOST_CHECK(data.woken); -} - -void do_test_condition_notify_one_wakes_from_timed_wait_with_predicate() -{ - wait_for_flag data; - - boost::thread thread(boost::bind(&wait_for_flag::timed_wait_with_predicate, boost::ref(data))); - - { - tsk::spin::mutex::scoped_lock lock(data.mutex); - data.flag=true; - data.cond_var.notify_one(); - } - - thread.join(); - BOOST_CHECK(data.woken); -} - -void do_test_condition_notify_one_wakes_from_relative_timed_wait_with_predicate() -{ - wait_for_flag data; - - boost::thread thread(boost::bind(&wait_for_flag::relative_timed_wait_with_predicate, boost::ref( data))); - - { - tsk::spin::mutex::scoped_lock lock(data.mutex); - data.flag=true; - data.cond_var.notify_one(); - } - - thread.join(); - BOOST_CHECK(data.woken); -} - -namespace -{ - tsk::spin::mutex multiple_wake_mutex; - tsk::spin::condition multiple_wake_cond; - unsigned multiple_wake_count=0; - - void wait_for_condvar_and_increase_count() - { - tsk::spin::mutex::scoped_lock lk(multiple_wake_mutex); - multiple_wake_cond.wait(lk); - ++multiple_wake_count; - } - -} - - -void do_test_multiple_notify_one_calls_wakes_multiple_threads() -{ - boost::thread thread1(wait_for_condvar_and_increase_count); - boost::thread thread2(wait_for_condvar_and_increase_count); - - boost::this_thread::sleep(boost::posix_time::milliseconds(200)); - multiple_wake_cond.notify_one(); - - boost::thread thread3(wait_for_condvar_and_increase_count); - - boost::this_thread::sleep(boost::posix_time::milliseconds(200)); - multiple_wake_cond.notify_one(); - multiple_wake_cond.notify_one(); - boost::this_thread::sleep(boost::posix_time::milliseconds(200)); - - { - tsk::spin::mutex::scoped_lock lk(multiple_wake_mutex); - BOOST_CHECK(multiple_wake_count==3); - } - - thread1.join(); - thread2.join(); - thread3.join(); -} - -void test_condition_notify_one() -{ - timed_test(&do_test_condition_notify_one_wakes_from_wait, timeout_seconds, execution_monitor::use_mutex); - timed_test(&do_test_condition_notify_one_wakes_from_wait_with_predicate, timeout_seconds, execution_monitor::use_mutex); - timed_test(&do_test_condition_notify_one_wakes_from_timed_wait, timeout_seconds, execution_monitor::use_mutex); - timed_test(&do_test_condition_notify_one_wakes_from_timed_wait_with_predicate, timeout_seconds, execution_monitor::use_mutex); - timed_test(&do_test_condition_notify_one_wakes_from_relative_timed_wait_with_predicate, timeout_seconds, execution_monitor::use_mutex); - timed_test(&do_test_multiple_notify_one_calls_wakes_multiple_threads, timeout_seconds, execution_monitor::use_mutex); -} - - -boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[]) -{ - boost::unit_test_framework::test_suite* test = - BOOST_TEST_SUITE("Boost.Task: condition test suite"); - - test->add(BOOST_TEST_CASE(&test_condition_notify_one)); - - return test; -} diff --git a/libs/task/test/test_spin_condition_timed_wait_times_out.cpp b/libs/task/test/test_spin_condition_timed_wait_times_out.cpp deleted file mode 100644 index 6e9d069b..00000000 --- a/libs/task/test/test_spin_condition_timed_wait_times_out.cpp +++ /dev/null @@ -1,175 +0,0 @@ -// Copyright (C) 2007-8 Anthony Williams -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -#include - -#include - -#include - -#include - -namespace tsk = boost::tasks; - -bool fake_predicate() -{ - return false; -} - -unsigned const timeout_seconds=2; -unsigned const timeout_grace=1; -boost::posix_time::milliseconds const timeout_resolution(100); - - -void do_test_timed_wait_times_out() -{ - tsk::spin::condition cond; - tsk::spin::mutex m; - - boost::posix_time::seconds const delay(timeout_seconds); - tsk::spin::mutex::scoped_lock lock(m); - boost::system_time const start=boost::get_system_time(); - boost::system_time const timeout=start+delay; - - while(cond.timed_wait(lock,timeout)); - - boost::system_time const end=boost::get_system_time(); - BOOST_CHECK((delay-timeout_resolution)<=(end-start)); -} - -void do_test_timed_wait_with_predicate_times_out() -{ - tsk::spin::condition cond; - tsk::spin::mutex m; - - boost::posix_time::seconds const delay(timeout_seconds); - tsk::spin::mutex::scoped_lock lock(m); - boost::system_time const start=boost::get_system_time(); - boost::system_time const timeout=start+delay; - - bool const res=cond.timed_wait(lock,timeout,fake_predicate); - - boost::system_time const end=boost::get_system_time(); - BOOST_CHECK(!res); - BOOST_CHECK((delay-timeout_resolution)<=(end-start)); -} - -void do_test_relative_timed_wait_with_predicate_times_out() -{ - tsk::spin::condition cond; - tsk::spin::mutex m; - - boost::posix_time::seconds const delay(timeout_seconds); - tsk::spin::mutex::scoped_lock lock(m); - boost::system_time const start=boost::get_system_time(); - - bool const res=cond.timed_wait(lock,delay,fake_predicate); - - boost::system_time const end=boost::get_system_time(); - BOOST_CHECK(!res); - BOOST_CHECK((delay-timeout_resolution)<=(end-start)); -} - -void do_test_timed_wait_relative_times_out() -{ - tsk::spin::condition cond; - tsk::spin::mutex m; - - boost::posix_time::seconds const delay(timeout_seconds); - tsk::spin::mutex::scoped_lock lock(m); - boost::system_time const start=boost::get_system_time(); - - while(cond.timed_wait(lock,delay)); - - boost::system_time const end=boost::get_system_time(); - BOOST_CHECK((delay-timeout_resolution)<=(end-start)); -} - -void do_test_cv_any_timed_wait_times_out() -{ - tsk::spin::condition cond; - tsk::spin::mutex m; - - boost::posix_time::seconds const delay(timeout_seconds); - tsk::spin::mutex::scoped_lock lock(m); - boost::system_time const start=boost::get_system_time(); - boost::system_time const timeout=start+delay; - - while(cond.timed_wait(lock,timeout)); - - boost::system_time const end=boost::get_system_time(); - BOOST_CHECK((delay-timeout_resolution)<=(end-start)); -} - -void do_test_cv_any_timed_wait_with_predicate_times_out() -{ - tsk::spin::condition cond; - tsk::spin::mutex m; - - boost::posix_time::seconds const delay(timeout_seconds); - tsk::spin::mutex::scoped_lock lock(m); - boost::system_time const start=boost::get_system_time(); - boost::system_time const timeout=start+delay; - - bool const res=cond.timed_wait(lock,timeout,fake_predicate); - - boost::system_time const end=boost::get_system_time(); - BOOST_CHECK(!res); - BOOST_CHECK((delay-timeout_resolution)<=(end-start)); -} - -void do_test_cv_any_relative_timed_wait_with_predicate_times_out() -{ - tsk::spin::condition cond; - tsk::spin::mutex m; - - boost::posix_time::seconds const delay(timeout_seconds); - tsk::spin::mutex::scoped_lock lock(m); - boost::system_time const start=boost::get_system_time(); - - bool const res=cond.timed_wait(lock,delay,fake_predicate); - - boost::system_time const end=boost::get_system_time(); - BOOST_CHECK(!res); - BOOST_CHECK((delay-timeout_resolution)<=(end-start)); -} - -void do_test_cv_any_timed_wait_relative_times_out() -{ - tsk::spin::condition cond; - tsk::spin::mutex m; - - boost::posix_time::seconds const delay(timeout_seconds); - tsk::spin::mutex::scoped_lock lock(m); - boost::system_time const start=boost::get_system_time(); - - while(cond.timed_wait(lock,delay)); - - boost::system_time const end=boost::get_system_time(); - BOOST_CHECK((delay-timeout_resolution)<=(end-start)); -} - - -void test_timed_wait_times_out() -{ - timed_test(&do_test_timed_wait_times_out, timeout_seconds+timeout_grace, execution_monitor::use_mutex); - timed_test(&do_test_timed_wait_with_predicate_times_out, timeout_seconds+timeout_grace, execution_monitor::use_mutex); - timed_test(&do_test_relative_timed_wait_with_predicate_times_out, timeout_seconds+timeout_grace, execution_monitor::use_mutex); - timed_test(&do_test_timed_wait_relative_times_out, timeout_seconds+timeout_grace, execution_monitor::use_mutex); - timed_test(&do_test_cv_any_timed_wait_times_out, timeout_seconds+timeout_grace, execution_monitor::use_mutex); - timed_test(&do_test_cv_any_timed_wait_with_predicate_times_out, timeout_seconds+timeout_grace, execution_monitor::use_mutex); - timed_test(&do_test_cv_any_relative_timed_wait_with_predicate_times_out, timeout_seconds+timeout_grace, execution_monitor::use_mutex); - timed_test(&do_test_cv_any_timed_wait_relative_times_out, timeout_seconds+timeout_grace, execution_monitor::use_mutex); -} - -boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[]) -{ - boost::unit_test_framework::test_suite* test = - BOOST_TEST_SUITE("Boost.Task: condition test suite"); - - test->add(BOOST_TEST_CASE(&test_timed_wait_times_out)); - - return test; -} diff --git a/libs/task/test/test_spin_count_down_event.cpp b/libs/task/test/test_spin_count_down_event.cpp deleted file mode 100755 index 6f0994af..00000000 --- a/libs/task/test/test_spin_count_down_event.cpp +++ /dev/null @@ -1,122 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace pt = boost::posix_time; -namespace tsk = boost::tasks; - -boost::uint32_t wait_fn( boost::uint32_t n, tsk::spin::count_down_event & ev) -{ - ev.wait(); - return n; -} - -// check initial + current -void test_case_1() -{ - boost::uint32_t n = 3; - tsk::spin::count_down_event ev( n); - BOOST_CHECK_EQUAL( ev.initial(), n); - BOOST_CHECK_EQUAL( ev.current(), n); - - ev.set(); - BOOST_CHECK_EQUAL( ev.initial(), n); - BOOST_CHECK_EQUAL( ev.current(), static_cast< boost::uint32_t >( 2) ); - - ev.set(); - BOOST_CHECK_EQUAL( ev.initial(), n); - BOOST_CHECK_EQUAL( ev.current(), static_cast< boost::uint32_t >( 1) ); - - ev.set(); - BOOST_CHECK_EQUAL( ev.initial(), n); - BOOST_CHECK_EQUAL( ev.current(), static_cast< boost::uint32_t >( 0) ); - - ev.set(); - BOOST_CHECK_EQUAL( ev.initial(), n); - BOOST_CHECK_EQUAL( ev.current(), static_cast< boost::uint32_t >( 0) ); -} - -// check wait in new thread -void test_case_2() -{ - boost::uint32_t n = 3; - tsk::spin::count_down_event ev( n); - BOOST_CHECK_EQUAL( ev.initial(), n); - BOOST_CHECK_EQUAL( ev.current(), n); - - tsk::handle< boost::uint32_t > h( - tsk::async( - tsk::make_task( - wait_fn, - n, boost::ref( ev) ), - tsk::new_thread() ) ); - BOOST_CHECK( ! h.is_ready() ); - for ( boost::uint32_t i = 0; i < n; ++i) - { - ev.set(); - BOOST_CHECK( ! h.is_ready() ); - } - BOOST_CHECK_EQUAL( ev.initial(), n); - BOOST_CHECK_EQUAL( ev.current(), static_cast< boost::uint32_t >( 0) ); - BOOST_CHECK_EQUAL( h.get(), n); -} - -// check wait in pool -void test_case_3() -{ - tsk::static_pool< - tsk::unbounded_fifo - > pool( tsk::poolsize( 3) ); - - boost::uint32_t n = 3; - tsk::spin::count_down_event ev( n); - BOOST_CHECK_EQUAL( ev.initial(), n); - BOOST_CHECK_EQUAL( ev.current(), n); - - tsk::handle< boost::uint32_t > h( - tsk::async( - tsk::make_task( - wait_fn, - n, boost::ref( ev) ), - pool) ); - BOOST_CHECK( ! h.is_ready() ); - for ( boost::uint32_t i = 0; i < n; ++i) - { - ev.set(); - BOOST_CHECK( ! h.is_ready() ); - } - BOOST_CHECK_EQUAL( ev.initial(), n); - BOOST_CHECK_EQUAL( ev.current(), static_cast< boost::uint32_t >( 0) ); - BOOST_CHECK_EQUAL( h.get(), n); -} - -boost::unit_test::test_suite * init_unit_test_suite( int, char* []) -{ - boost::unit_test::test_suite * test = - BOOST_TEST_SUITE("Boost.Task: spin-count-down-event test suite"); - - test->add( BOOST_TEST_CASE( & test_case_1) ); - test->add( BOOST_TEST_CASE( & test_case_2) ); - test->add( BOOST_TEST_CASE( & test_case_3) ); - - return test; -} diff --git a/libs/task/test/test_spin_manual_reset_event.cpp b/libs/task/test/test_spin_manual_reset_event.cpp deleted file mode 100755 index 848e9064..00000000 --- a/libs/task/test/test_spin_manual_reset_event.cpp +++ /dev/null @@ -1,234 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace pt = boost::posix_time; -namespace tsk = boost::tasks; - -boost::uint32_t wait_fn( boost::uint32_t n, tsk::spin::manual_reset_event & ev) -{ - ev.wait(); - return n; -} - -// check wait in new thread -void test_case_1() -{ - boost::uint32_t n = 3; - tsk::spin::manual_reset_event ev; - - tsk::handle< boost::uint32_t > h1( - tsk::async( - tsk::make_task( - wait_fn, - n, boost::ref( ev) ), - tsk::new_thread() ) ); - tsk::handle< boost::uint32_t > h2( - tsk::async( - tsk::make_task( - wait_fn, - n, boost::ref( ev) ), - tsk::new_thread() ) ); - - boost::this_thread::sleep( pt::millisec( 250) ); - BOOST_CHECK( ! h1.is_ready() ); - BOOST_CHECK( ! h2.is_ready() ); - - ev.set(); - - boost::this_thread::sleep( pt::millisec( 250) ); - BOOST_CHECK( h1.is_ready() ); - BOOST_CHECK( h2.is_ready() ); - BOOST_CHECK_EQUAL( h1.get(), n); - BOOST_CHECK_EQUAL( h2.get(), n); - - ev.reset(); - - tsk::handle< boost::uint32_t > h3( - tsk::async( - tsk::make_task( - wait_fn, - n, boost::ref( ev) ), - tsk::new_thread() ) ); - tsk::handle< boost::uint32_t > h4( - tsk::async( - tsk::make_task( - wait_fn, - n, boost::ref( ev) ), - tsk::new_thread() ) ); - - boost::this_thread::sleep( pt::millisec( 250) ); - BOOST_CHECK( ! h3.is_ready() ); - BOOST_CHECK( ! h4.is_ready() ); - - ev.set(); - - boost::this_thread::sleep( pt::millisec( 250) ); - BOOST_CHECK( h3.is_ready() ); - BOOST_CHECK( h4.is_ready() ); - BOOST_CHECK_EQUAL( h3.get(), n); - BOOST_CHECK_EQUAL( h4.get(), n); -} - -// check wait in pool -void test_case_2() -{ - tsk::static_pool< - tsk::unbounded_fifo - > pool( tsk::poolsize( 3) ); - - boost::uint32_t n = 3; - tsk::spin::manual_reset_event ev; - - tsk::handle< boost::uint32_t > h1( - tsk::async( - tsk::make_task( - wait_fn, - n, boost::ref( ev) ), - pool) ); - tsk::handle< boost::uint32_t > h2( - tsk::async( - tsk::make_task( - wait_fn, - n, boost::ref( ev) ), - pool) ); - - boost::this_thread::sleep( pt::millisec( 250) ); - BOOST_CHECK( ! h1.is_ready() ); - BOOST_CHECK( ! h2.is_ready() ); - - ev.set(); - - boost::this_thread::sleep( pt::millisec( 250) ); - BOOST_CHECK( h1.is_ready() ); - BOOST_CHECK( h2.is_ready() ); - BOOST_CHECK_EQUAL( h1.get(), n); - BOOST_CHECK_EQUAL( h2.get(), n); - - ev.reset(); - - tsk::handle< boost::uint32_t > h3( - tsk::async( - tsk::make_task( - wait_fn, - n, boost::ref( ev) ), - tsk::new_thread() ) ); - tsk::handle< boost::uint32_t > h4( - tsk::async( - tsk::make_task( - wait_fn, - n, boost::ref( ev) ), - tsk::new_thread() ) ); - - boost::this_thread::sleep( pt::millisec( 250) ); - BOOST_CHECK( ! h3.is_ready() ); - BOOST_CHECK( ! h4.is_ready() ); - - ev.set(); - - boost::this_thread::sleep( pt::millisec( 250) ); - BOOST_CHECK( h3.is_ready() ); - BOOST_CHECK( h4.is_ready() ); - BOOST_CHECK_EQUAL( h3.get(), n); - BOOST_CHECK_EQUAL( h4.get(), n); -} - -void test_case_3() -{ - boost::uint32_t n = 3; - tsk::spin::manual_reset_event ev( true); - - tsk::handle< boost::uint32_t > h1( - tsk::async( - tsk::make_task( - wait_fn, - n, boost::ref( ev) ), - tsk::new_thread() ) ); - tsk::handle< boost::uint32_t > h2( - tsk::async( - tsk::make_task( - wait_fn, - n, boost::ref( ev) ), - tsk::new_thread() ) ); - - boost::this_thread::sleep( pt::millisec( 250) ); - BOOST_CHECK( h1.is_ready() ); - BOOST_CHECK( h2.is_ready() ); - BOOST_CHECK_EQUAL( h1.get(), n); - BOOST_CHECK_EQUAL( h2.get(), n); - - ev.reset(); - - tsk::handle< boost::uint32_t > h3( - tsk::async( - tsk::make_task( - wait_fn, - n, boost::ref( ev) ), - tsk::new_thread() ) ); - tsk::handle< boost::uint32_t > h4( - tsk::async( - tsk::make_task( - wait_fn, - n, boost::ref( ev) ), - tsk::new_thread() ) ); - - boost::this_thread::sleep( pt::millisec( 250) ); - BOOST_CHECK( ! h3.is_ready() ); - BOOST_CHECK( ! h4.is_ready() ); - - ev.set(); - - boost::this_thread::sleep( pt::millisec( 250) ); - BOOST_CHECK( h3.is_ready() ); - BOOST_CHECK( h4.is_ready() ); - BOOST_CHECK_EQUAL( h3.get(), n); - BOOST_CHECK_EQUAL( h4.get(), n); -} - -void test_case_4() -{ - tsk::spin::manual_reset_event ev; - - BOOST_CHECK_EQUAL( false, ev.try_wait() ); - - ev.set(); - - BOOST_CHECK_EQUAL( true, ev.try_wait() ); - BOOST_CHECK_EQUAL( true, ev.try_wait() ); - ev.wait(); - BOOST_CHECK_EQUAL( true, ev.try_wait() ); - - ev.reset(); - BOOST_CHECK_EQUAL( false, ev.try_wait() ); -} - -boost::unit_test::test_suite * init_unit_test_suite( int, char* []) -{ - boost::unit_test::test_suite * test = - BOOST_TEST_SUITE("Boost.Task: spin-manual-reset-event test suite"); - - test->add( BOOST_TEST_CASE( & test_case_1) ); - test->add( BOOST_TEST_CASE( & test_case_2) ); - test->add( BOOST_TEST_CASE( & test_case_3) ); - - return test; -} diff --git a/libs/task/test/test_spin_mutex.cpp b/libs/task/test/test_spin_mutex.cpp deleted file mode 100644 index a90ad0fc..00000000 --- a/libs/task/test/test_spin_mutex.cpp +++ /dev/null @@ -1,85 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) -// -// This test is based on the tests of Boost.Thread - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -namespace pt = boost::posix_time; -namespace tsk = boost::tasks; - -template< typename M > -struct test_lock -{ - typedef M mutex_type; - typedef typename M::scoped_lock lock_type; - - void operator()() - { - mutex_type mutex; - tsk::spin::condition condition; - - // Test the lock's constructors. - { - lock_type lock(mutex, boost::defer_lock); - BOOST_CHECK(!lock); - } - lock_type lock(mutex); - BOOST_CHECK(lock ? true : false); - - // Construct and initialize an xtime for a fast time out. - pt::time_duration xt = pt::milliseconds( 100); - - // Test the lock and the mutex with condition variables. - // No one is going to notify this condition variable. We expect to - // time out. - BOOST_CHECK(!condition.timed_wait(lock, xt)); - BOOST_CHECK(lock ? true : false); - - // Test the lock and unlock methods. - lock.unlock(); - BOOST_CHECK(!lock); - lock.lock(); - BOOST_CHECK(lock ? true : false); - } -}; - -void do_test_mutex() -{ - test_lock< tsk::spin::mutex >()(); -} - -void test_mutex() -{ - timed_test(&do_test_mutex, 3); -} - - -boost::unit_test::test_suite * init_unit_test_suite( int, char* []) -{ - boost::unit_test_framework::test_suite * test = - BOOST_TEST_SUITE("Boost.Task: spin-mutex test suite"); - - test->add(BOOST_TEST_CASE(&test_mutex)); - - return test; -} diff --git a/libs/task/test/test_spin_unbounded_channel.cpp b/libs/task/test/test_spin_unbounded_channel.cpp deleted file mode 100644 index 1871a85f..00000000 --- a/libs/task/test/test_spin_unbounded_channel.cpp +++ /dev/null @@ -1,171 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace pt = boost::posix_time; -namespace tsk = boost::tasks; - -struct send_data -{ - tsk::spin::unbounded_channel< int > & buf; - - send_data( tsk::spin::unbounded_channel< int > & buf_) : - buf( buf_) - {} - - void operator()( int value) - { buf.put( value); } -}; - -struct recv_data -{ - tsk::spin::unbounded_channel< int > & buf; - int value; - - recv_data( tsk::spin::unbounded_channel< int > & buf_) : - buf( buf_), value( 0) - {} - - void operator()( ) - { - boost::optional< int > res; - if ( buf.take( res) ) - value = * res; - } -}; - -void test_case_1() -{ - tsk::spin::unbounded_channel< int > buf; - BOOST_CHECK_EQUAL( true, buf.empty() ); - BOOST_CHECK_EQUAL( true, buf.active() ); - int n = 1; - buf.put( n); - BOOST_CHECK_EQUAL( false, buf.empty() ); - boost::optional< int > res; - BOOST_CHECK_EQUAL( true, buf.take( res) ); - BOOST_CHECK( res); - BOOST_CHECK_EQUAL( n, res.get() ); - buf.deactivate(); - BOOST_CHECK_EQUAL( false, buf.active() ); - BOOST_CHECK_THROW( buf.put( 1), std::runtime_error); -} - -void test_case_2() -{ - tsk::spin::unbounded_channel< int > buf; - BOOST_CHECK_EQUAL( true, buf.empty() ); - BOOST_CHECK_EQUAL( true, buf.active() ); - int n = 1; - buf.put( n); - BOOST_CHECK_EQUAL( false, buf.empty() ); - boost::optional< int > res; - BOOST_CHECK_EQUAL( true, buf.try_take( res) ); - BOOST_CHECK( res); - BOOST_CHECK_EQUAL( n, res.get() ); - BOOST_CHECK_EQUAL( false, buf.try_take( res) ); - BOOST_CHECK_EQUAL( false, buf.take( res, pt::milliseconds( 10) ) ); -} - -void test_case_3() -{ - tsk::static_pool< - tsk::unbounded_fifo - > pool( tsk::poolsize( 2) ); - - tsk::spin::unbounded_channel< int > buf; - - int n = 37; - - recv_data receiver( buf); - BOOST_CHECK_EQUAL( 0, receiver.value); - tsk::handle< void > h = - tsk::async( - tsk::make_task( - & recv_data::operator(), - boost::ref( receiver) ), - pool); - - boost::this_thread::sleep( - pt::milliseconds( 250) ); - - BOOST_CHECK_EQUAL( false, h.is_ready() ); - buf.put( n); - - h.wait(); - - BOOST_CHECK_EQUAL( n, receiver.value); -} - -void test_case_4() -{ - tsk::static_pool< - tsk::unbounded_fifo - > pool( tsk::poolsize( 2) ); - - tsk::spin::unbounded_channel< int > buf; - - int n = 37; - - send_data sender( buf); - recv_data receiver( buf); - BOOST_CHECK_EQUAL( 0, receiver.value); - - tsk::handle< void > h1 = - tsk::async( - tsk::make_task( - & recv_data::operator(), - boost::ref( receiver) ), - pool); - - boost::this_thread::sleep( - pt::milliseconds( 250) ); - BOOST_CHECK_EQUAL( false, h1.is_ready() ); - - tsk::handle< void > h2 = - tsk::async( - tsk::make_task( - & send_data::operator(), - boost::ref( sender), - n), - pool); - - h2.wait(); - BOOST_CHECK_EQUAL( true, h2.is_ready() ); - h1.wait(); - BOOST_CHECK_EQUAL( true, h1.is_ready() ); - - BOOST_CHECK_EQUAL( n, receiver.value); -} - -boost::unit_test::test_suite * init_unit_test_suite( int, char* []) -{ - boost::unit_test::test_suite * test = - BOOST_TEST_SUITE("Boost.Task: unbounded-buffer test suite"); - - test->add( BOOST_TEST_CASE( & test_case_1) ); - test->add( BOOST_TEST_CASE( & test_case_2) ); - test->add( BOOST_TEST_CASE( & test_case_3) ); - test->add( BOOST_TEST_CASE( & test_case_4) ); - - return test; -} diff --git a/libs/task/test/test_task.cpp b/libs/task/test/test_task.cpp deleted file mode 100755 index 0d66a8c9..00000000 --- a/libs/task/test/test_task.cpp +++ /dev/null @@ -1,99 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "test_functions.hpp" - -namespace pt = boost::posix_time; -namespace tsk = boost::tasks; - -void zero_args_fn() {} -int one_arg_fn( int i) { return i; } -int two_args_fn( int i, std::string const& s) { return i; } - -// check vaild task -void test_case_1() -{ - tsk::task< int > t1( fibonacci_fn, 10); - tsk::task< int > t2; - BOOST_CHECK( t1); - BOOST_CHECK( ! t2); -} - -// check make_task -void test_case_2() -{ - tsk::task< void > t1; - BOOST_CHECK( ! t1); - t1 = tsk::make_task( zero_args_fn); - BOOST_CHECK( t1); - tsk::task< int > t2 = tsk::make_task( one_arg_fn, 1); - BOOST_CHECK( t2); - tsk::task< int > t3; - BOOST_CHECK( ! t3); - t3 = tsk::make_task( two_args_fn, 1, "abc"); - BOOST_CHECK( t3); -} - -// check moved task -void test_case_3() -{ - tsk::task< int > t1( fibonacci_fn, 10); - BOOST_CHECK( t1); - tsk::task< int > t2( boost::move( t1) ); - BOOST_CHECK( ! t1); - BOOST_CHECK_THROW( t1(), tsk::task_moved); - BOOST_CHECK_NO_THROW( t2() ); -} - -// check execute twice -void test_case_4() -{ - tsk::task< int > t1( fibonacci_fn, 10); - BOOST_CHECK_NO_THROW( t1() ); - BOOST_CHECK_THROW( t1(), tsk::task_already_executed); -} - -// check swap -void test_case_5() -{ - tsk::task< int > t1( fibonacci_fn, 10); - tsk::task< int > t2; - BOOST_CHECK_NO_THROW( t1() ); - BOOST_CHECK_THROW( t2(), tsk::task_moved); - t1.swap( t2); - BOOST_CHECK_THROW( t1(), tsk::task_moved); - BOOST_CHECK_THROW( t2(), tsk::task_already_executed); -} - -boost::unit_test::test_suite * init_unit_test_suite( int, char* []) -{ - boost::unit_test::test_suite * test = - BOOST_TEST_SUITE("Boost.Task: task test suite"); - - test->add( BOOST_TEST_CASE( & test_case_1) ); - test->add( BOOST_TEST_CASE( & test_case_2) ); - test->add( BOOST_TEST_CASE( & test_case_3) ); - test->add( BOOST_TEST_CASE( & test_case_4) ); - test->add( BOOST_TEST_CASE( & test_case_5) ); - - return test; -} diff --git a/libs/task/test/test_tasklet.cpp b/libs/task/test/test_tasklet.cpp deleted file mode 100644 index 1ed98077..00000000 --- a/libs/task/test/test_tasklet.cpp +++ /dev/null @@ -1,425 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "test_functions.hpp" - -namespace fi = boost::tasklets; -namespace pt = boost::posix_time; -namespace tsk = boost::tasks; - -// check assignment -void test_case_1() -{ - fi::scheduler<> sched; - tsk::task< int > t( fibonacci_fn, 10); - tsk::handle< int > h1; - tsk::handle< int > h2( - tsk::async( boost::move( t), sched) ); - h1 = h2; - for (;;) - { - while ( sched.run() ); - if ( sched.empty() ) break; - } - BOOST_CHECK_EQUAL( h1.get(), 55); - BOOST_CHECK_EQUAL( h2.get(), 55); -} - -// check swap -void test_case_2() -{ - fi::scheduler<> sched; - tsk::task< int > t1( fibonacci_fn, 5); - tsk::task< int > t2( fibonacci_fn, 10); - tsk::handle< int > h1( - tsk::async( boost::move( t1), sched) ); - tsk::handle< int > h2( - tsk::async( boost::move( t2), sched) ); - for (;;) - { - while ( sched.run() ); - if ( sched.empty() ) break; - } - BOOST_CHECK_EQUAL( h1.get(), 5); - BOOST_CHECK_EQUAL( h2.get(), 55); - BOOST_CHECK_NO_THROW( h1.swap( h2) ); - BOOST_CHECK_EQUAL( h1.get(), 55); - BOOST_CHECK_EQUAL( h2.get(), 5); -} - -// check runs not in pool -void test_case_3() -{ - fi::scheduler<> sched; - tsk::task< bool > t( runs_in_pool_fn); - tsk::handle< bool > h( - tsk::async( boost::move( t), sched) ); - for (;;) - { - while ( sched.run() ); - if ( sched.empty() ) break; - } - BOOST_CHECK_EQUAL( h.get(), false); -} - -// check runtime_error throw inside task -void test_case_4() -{ - fi::scheduler<> sched; - tsk::task< void > t( throwing_fn); - tsk::handle< void > h( - tsk::async( boost::move( t), sched) ); - for (;;) - { - while ( sched.run() ); - if ( sched.empty() ) break; - } - BOOST_CHECK_THROW( h.get(), std::runtime_error); -} - -// check task_uninitialized -void test_case_5() -{ - tsk::handle< int > h; - BOOST_CHECK_THROW( h.get(), tsk::task_uninitialized); - BOOST_CHECK_THROW( h.wait(), tsk::task_uninitialized); - BOOST_CHECK_THROW( h.wait_for( pt::seconds( 1) ), tsk::task_uninitialized); - BOOST_CHECK_THROW( - h.wait_until( boost::get_system_time() + pt::seconds( 1) ), - tsk::task_uninitialized); - BOOST_CHECK( ! h.is_ready() ); - BOOST_CHECK( ! h.has_value() ); - BOOST_CHECK( ! h.has_exception() ); -} - -// check wait -void test_case_6() -{ - fi::scheduler<> sched; - tsk::task< int > t( fibonacci_fn, 10); - tsk::handle< int > h( - tsk::async( boost::move( t), sched) ); - BOOST_CHECK( ! h.is_ready() ); - BOOST_CHECK( ! h.has_value() ); - BOOST_CHECK( ! h.has_exception() ); - for (;;) - { - while ( sched.run() ); - if ( sched.empty() ) break; - } - h.wait(); - BOOST_CHECK( h.is_ready() ); - BOOST_CHECK( h.has_value() ); - BOOST_CHECK( ! h.has_exception() ); - BOOST_CHECK_EQUAL( h.get(), 55); -} - -// check wait_for -void test_case_7() -{ - fi::scheduler<> sched; - tsk::task< void > t( delay_fn, pt::seconds( 1) ); - tsk::handle< void > h( - tsk::async( boost::move( t), sched) ); - for (;;) - { - while ( sched.run() ); - if ( sched.empty() ) break; - } - BOOST_CHECK( h.wait_for( pt::seconds( 2) ) ); - BOOST_CHECK( h.is_ready() ); - BOOST_CHECK( h.has_value() ); - BOOST_CHECK( ! h.has_exception() ); -} - -// check wait_for -void test_case_8() -{ - fi::scheduler<> sched; - tsk::task< void > t( delay_fn, pt::seconds( 2) ); - tsk::handle< void > h( - tsk::async( boost::move( t), sched) ); - for (;;) - { - while ( sched.run() ); - if ( sched.empty() ) break; - } - BOOST_CHECK( h.wait_for( pt::seconds( 1) ) ); - BOOST_CHECK( h.is_ready() ); - BOOST_CHECK( h.has_value() ); - BOOST_CHECK( ! h.has_exception() ); -} - -// check wait_for -void test_case_9() -{ - fi::scheduler<> sched; - tsk::task< void > t( delay_fn, pt::seconds( 1) ); - tsk::handle< void > h( - tsk::async( boost::move( t), sched) ); - for (;;) - { - while ( sched.run() ); - if ( sched.empty() ) break; - } - BOOST_CHECK( h.wait_until( boost::get_system_time() + pt::seconds( 3) ) ); - BOOST_CHECK( h.is_ready() ); - BOOST_CHECK( h.has_value() ); - BOOST_CHECK( ! h.has_exception() ); -} - -// check wait_for -void test_case_10() -{ - fi::scheduler<> sched; - tsk::task< void > t( delay_fn, pt::seconds( 2) ); - tsk::handle< void > h( - tsk::async( boost::move( t), sched) ); - for (;;) - { - while ( sched.run() ); - if ( sched.empty() ) break; - } - BOOST_CHECK( h.wait_until( boost::get_system_time() + pt::seconds( 1) ) ); - BOOST_CHECK( h.is_ready() ); - BOOST_CHECK( h.has_value() ); - BOOST_CHECK( ! h.has_exception() ); -} - -// check interrupt -void test_case_11() -{ - fi::scheduler<> sched; - tsk::task< void > t( delay_fn, pt::seconds( 3) ); - tsk::handle< void > h( - tsk::async( boost::move( t), sched) ); - h.interrupt(); - for (;;) - { - while ( sched.run() ); - if ( sched.empty() ) break; - } - BOOST_CHECK( h.interruption_requested() ); - BOOST_CHECK_NO_THROW( h.get() ); -} - -// check interrupt_and_wait -void test_case_12() -{ - fi::scheduler<> sched; - bool finished( false); - tsk::task< void > t( - interrupt_fn, - pt::seconds( 3), - boost::ref( finished) ); - tsk::handle< void > h( - tsk::async( boost::move( t), sched) ); - for (;;) - { - while ( sched.run() ); - if ( sched.empty() ) break; - } - h.interrupt_and_wait(); - BOOST_CHECK( ! finished); - BOOST_CHECK( h.is_ready() ); - BOOST_CHECK( h.interruption_requested() ); - BOOST_CHECK_NO_THROW( h.get() ); -} - -// check interrupt_and_wait_for -void test_case_13() -{ - fi::scheduler<> sched; - bool finished( false); - tsk::task< void > t( - interrupt_fn, - pt::seconds( 1), - boost::ref( finished) ); - tsk::handle< void > h( - tsk::async( boost::move( t), sched) ); - for (;;) - { - while ( sched.run() ); - if ( sched.empty() ) break; - } - BOOST_CHECK( h.interrupt_and_wait_for( pt::seconds( 2) ) ); - BOOST_CHECK( ! finished); - BOOST_CHECK( h.is_ready() ); - BOOST_CHECK( h.has_value() ); - BOOST_CHECK( ! h.has_exception() ); - BOOST_CHECK( h.interruption_requested() ); - BOOST_CHECK_NO_THROW( h.get() ); -} - -// check interrupt_and_wait_for -void test_case_14() -{ - fi::scheduler<> sched; - tsk::task< void > t( non_interrupt_fn, 2); - tsk::handle< void > h( - tsk::async( boost::move( t), sched) ); - for (;;) - { - while ( sched.run() ); - if ( sched.empty() ) break; - } - BOOST_CHECK( h.interrupt_and_wait_for( pt::seconds( 1) ) ); - BOOST_CHECK_NO_THROW( h.get() ); -} - -// check interrupt_and_wait_until -void test_case_15() -{ - fi::scheduler<> sched; - bool finished( false); - tsk::task< void > t( - interrupt_fn, - pt::seconds( 1), - boost::ref( finished) ); - tsk::handle< void > h( - tsk::async( boost::move( t), sched) ); - for (;;) - { - while ( sched.run() ); - if ( sched.empty() ) break; - } - BOOST_CHECK( h.interrupt_and_wait_until( boost::get_system_time() + pt::seconds( 2) ) ); - BOOST_CHECK( ! finished); - BOOST_CHECK( h.is_ready() ); - BOOST_CHECK( h.has_value() ); - BOOST_CHECK( ! h.has_exception() ); - BOOST_CHECK( h.interruption_requested() ); - BOOST_CHECK_NO_THROW( h.get() ); -} - -// check interrupt_and_wait_until -void test_case_16() -{ - fi::scheduler<> sched; - tsk::task< void > t( non_interrupt_fn, 2); - tsk::handle< void > h( - tsk::async( boost::move( t), sched) ); - for (;;) - { - while ( sched.run() ); - if ( sched.empty() ) break; - } - BOOST_CHECK( h.interrupt_and_wait_until( boost::get_system_time() + pt::seconds( 1) ) ); - BOOST_CHECK_NO_THROW( h.get() ); -} - -// check waitfor_all() -void test_case_17() -{ - fi::scheduler<> sched; - std::vector< tsk::handle< int > > vec; - for ( int i = 0; i <= 5; ++i) - { - tsk::task< int > t( fibonacci_fn, i); - vec.push_back( - tsk::async( boost::move( t), sched) ); - } - for (;;) - { - while ( sched.run() ); - if ( sched.empty() ) break; - } - tsk::waitfor_all( vec.begin(), vec.end() ); - BOOST_CHECK( vec[0].is_ready() ); - BOOST_CHECK( vec[1].is_ready() ); - BOOST_CHECK( vec[2].is_ready() ); - BOOST_CHECK( vec[3].is_ready() ); - BOOST_CHECK( vec[4].is_ready() ); - BOOST_CHECK( vec[5].is_ready() ); - BOOST_CHECK_EQUAL( vec[0].get(), 0); - BOOST_CHECK_EQUAL( vec[1].get(), 1); - BOOST_CHECK_EQUAL( vec[2].get(), 1); - BOOST_CHECK_EQUAL( vec[3].get(), 2); - BOOST_CHECK_EQUAL( vec[4].get(), 3); - BOOST_CHECK_EQUAL( vec[5].get(), 5); -} -/* -// check waitfor_any() -void test_case_18() -{ - fi::scheduler<> sched; - tsk::task< void > t1( delay_fn, pt::seconds( 2) ); - tsk::task< void > t2( delay_fn, pt::seconds( 1) ); - tsk::handle< void > h1( - tsk::async( boost::move( t1), sched) ); - tsk::handle< void > h2( - tsk::async( boost::move( t2), sched) ); - for (;;) - { - while ( sched.run() ); - if ( sched.empty() ) break; - } - tsk::waitfor_any( h1, h2); - BOOST_CHECK( h1.is_ready() ); - BOOST_CHECK( h2.is_ready() ); -} -*/ -// check interrupt + wait -void test_case_19() -{ - fi::scheduler<> sched; - tsk::task< void > t( delay_fn, pt::seconds( 3) ); - tsk::handle< void > h( - tsk::async( boost::move( t), sched) ); - for (;;) - { - while ( sched.run() ); - if ( sched.empty() ) break; - } - h.interrupt(); - BOOST_CHECK_NO_THROW( h.wait() ); - BOOST_CHECK_NO_THROW( h.get() ); -} - -boost::unit_test::test_suite * init_unit_test_suite( int, char* []) -{ - boost::unit_test::test_suite * test = - BOOST_TEST_SUITE("Boost.Task: tasklet test suite"); - - test->add( BOOST_TEST_CASE( & test_case_1) ); - test->add( BOOST_TEST_CASE( & test_case_2) ); - test->add( BOOST_TEST_CASE( & test_case_3) ); - test->add( BOOST_TEST_CASE( & test_case_4) ); - test->add( BOOST_TEST_CASE( & test_case_5) ); - test->add( BOOST_TEST_CASE( & test_case_6) ); - test->add( BOOST_TEST_CASE( & test_case_7) ); - test->add( BOOST_TEST_CASE( & test_case_8) ); - test->add( BOOST_TEST_CASE( & test_case_9) ); - test->add( BOOST_TEST_CASE( & test_case_10) ); - test->add( BOOST_TEST_CASE( & test_case_11) ); - test->add( BOOST_TEST_CASE( & test_case_12) ); - test->add( BOOST_TEST_CASE( & test_case_13) ); - test->add( BOOST_TEST_CASE( & test_case_14) ); - test->add( BOOST_TEST_CASE( & test_case_15) ); - test->add( BOOST_TEST_CASE( & test_case_16) ); - test->add( BOOST_TEST_CASE( & test_case_17) ); -// test->add( BOOST_TEST_CASE( & test_case_18) ); - test->add( BOOST_TEST_CASE( & test_case_19) ); - - return test; -} diff --git a/libs/task/test/test_unbounded_pool.cpp b/libs/task/test/test_unbounded_pool.cpp deleted file mode 100644 index 9e1c346e..00000000 --- a/libs/task/test/test_unbounded_pool.cpp +++ /dev/null @@ -1,440 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "test_functions.hpp" - -namespace pt = boost::posix_time; -namespace tsk = boost::tasks; - -// check size and move op -void test_case_1() -{ - tsk::static_pool< - tsk::unbounded_fifo - > pool1( tsk::poolsize( 3) ); - BOOST_CHECK( pool1); - BOOST_CHECK_EQUAL( pool1.size(), std::size_t( 3) ); - - tsk::static_pool< - tsk::unbounded_fifo - > pool2; - BOOST_CHECK( ! pool2); - BOOST_CHECK_THROW( pool2.size(), tsk::pool_moved); - - pool2 = boost::move( pool1); - - BOOST_CHECK( ! pool1); - BOOST_CHECK_THROW( pool1.size(), tsk::pool_moved); - - BOOST_CHECK( pool2); - BOOST_CHECK_EQUAL( pool2.size(), std::size_t( 3) ); - - tsk::task< int > t( fibonacci_fn, 10); - tsk::handle< int > h( - tsk::async( boost::move( t), pool2) ); - BOOST_CHECK_EQUAL( h.get(), 55); -} - -// check submit -void test_case_2() -{ - tsk::static_pool< - tsk::unbounded_fifo - > pool( tsk::poolsize( 3) ); - tsk::task< int > t( fibonacci_fn, 10); - tsk::handle< int > h( - tsk::async( boost::move( t), pool) ); - BOOST_CHECK_EQUAL( h.get(), 55); -} - -// check assignment -void test_case_3() -{ - tsk::static_pool< - tsk::unbounded_fifo - > pool( tsk::poolsize( 3) ); - tsk::task< int > t( fibonacci_fn, 10); - tsk::handle< int > h1; - tsk::handle< int > h2( - tsk::async( boost::move( t), pool) ); - h1 = h2; - BOOST_CHECK_EQUAL( h1.get(), 55); - BOOST_CHECK_EQUAL( h2.get(), 55); -} - -// check swap -void test_case_4() -{ - tsk::static_pool< - tsk::unbounded_fifo - > pool( tsk::poolsize( 3) ); - tsk::task< int > t1( fibonacci_fn, 5); - tsk::task< int > t2( fibonacci_fn, 10); - tsk::handle< int > h1( - tsk::async( boost::move( t1), pool) ); - tsk::handle< int > h2( - tsk::async( boost::move( t2), pool) ); - BOOST_CHECK_EQUAL( h1.get(), 5); - BOOST_CHECK_EQUAL( h2.get(), 55); - BOOST_CHECK_NO_THROW( h1.swap( h2) ); - BOOST_CHECK_EQUAL( h1.get(), 55); - BOOST_CHECK_EQUAL( h2.get(), 5); -} - -// check runs in pool -void test_case_5() -{ - tsk::static_pool< - tsk::unbounded_fifo - > pool( tsk::poolsize( 1) ); - tsk::task< bool > t( runs_in_pool_fn); - tsk::handle< bool > h( - tsk::async( boost::move( t), pool) ); - BOOST_CHECK_EQUAL( h.get(), true); -} - -// check shutdown -void test_case_6() -{ - tsk::static_pool< - tsk::unbounded_fifo - > pool( tsk::poolsize( 1) ); - tsk::task< int > t( fibonacci_fn, 10); - tsk::handle< int > h( - tsk::async( boost::move( t), pool) ); - pool.shutdown(); - BOOST_CHECK( pool.closed() ); - BOOST_CHECK_EQUAL( h.get(), 55); -} - -// check runtime_error throw inside task -void test_case_7() -{ - tsk::static_pool< - tsk::unbounded_fifo - > pool( tsk::poolsize( 1) ); - tsk::task< void > t( throwing_fn); - tsk::handle< void > h( - tsk::async( boost::move( t), pool) ); - pool.shutdown(); - BOOST_CHECK_THROW( h.get(), std::runtime_error); -} - -// check shutdown with task_rejected exception -void test_case_8() -{ - tsk::static_pool< - tsk::unbounded_fifo - > pool( tsk::poolsize( 1) ); - tsk::task< int > t( fibonacci_fn, 10); - pool.shutdown(); - BOOST_CHECK( pool.closed() ); - BOOST_CHECK_THROW( - tsk::async( boost::move( t), pool), - tsk::task_rejected); -} - -// check shutdown_now with thread_interrupted exception -void test_case_9() -{ - tsk::static_pool< - tsk::unbounded_fifo - > pool( tsk::poolsize( 1) ); - tsk::task< void > t( delay_fn, pt::millisec( 500) ); - tsk::handle< void > h( - tsk::async( boost::move( t), pool) ); - boost::this_thread::sleep( pt::millisec( 250) ); - BOOST_CHECK_EQUAL( pool.size(), std::size_t( 1) ); - pool.shutdown_now(); - BOOST_CHECK( pool.closed() ); - BOOST_CHECK_EQUAL( pool.size(), std::size_t( 0) ); - BOOST_CHECK_THROW( h.get(), tsk::task_interrupted); -} - -// check wait -void test_case_10() -{ - tsk::static_pool< - tsk::unbounded_fifo - > pool( tsk::poolsize( 3) ); - tsk::task< int > t( fibonacci_fn, 10); - tsk::handle< int > h( - tsk::async( boost::move( t), pool) ); - h.wait(); - BOOST_CHECK( h.is_ready() ); - BOOST_CHECK( h.has_value() ); - BOOST_CHECK( ! h.has_exception() ); - BOOST_CHECK_EQUAL( h.get(), 55); -} - -// check wait_for -void test_case_11() -{ - tsk::static_pool< - tsk::unbounded_fifo - > pool( tsk::poolsize( 3) ); - tsk::task< void > t( delay_fn, pt::seconds( 1) ); - tsk::handle< void > h( - tsk::async( boost::move( t), pool) ); - BOOST_CHECK( h.wait_for( pt::seconds( 3) ) ); - BOOST_CHECK( h.is_ready() ); - BOOST_CHECK( h.has_value() ); - BOOST_CHECK( ! h.has_exception() ); -} - -// check wait_for -void test_case_12() -{ - tsk::static_pool< - tsk::unbounded_fifo - > pool( tsk::poolsize( 3) ); - tsk::task< void > t( delay_fn, pt::seconds( 3) ); - tsk::handle< void > h( - tsk::async( boost::move( t), pool) ); - BOOST_CHECK( ! h.wait_for( pt::seconds( 1) ) ); - BOOST_CHECK( ! h.is_ready() ); - BOOST_CHECK( ! h.has_value() ); - BOOST_CHECK( ! h.has_exception() ); -} - -// check wait_until -void test_case_13() -{ - tsk::static_pool< - tsk::unbounded_fifo - > pool( tsk::poolsize( 3) ); - tsk::task< void > t( delay_fn, pt::seconds( 1) ); - tsk::handle< void > h( - tsk::async( boost::move( t), pool) ); - BOOST_CHECK( h.wait_until( boost::get_system_time() + pt::seconds( 3) ) ); - BOOST_CHECK( h.is_ready() ); - BOOST_CHECK( h.has_value() ); - BOOST_CHECK( ! h.has_exception() ); -} - -// check wait_until -void test_case_14() -{ - tsk::static_pool< - tsk::unbounded_fifo - > pool( tsk::poolsize( 3) ); - tsk::task< void > t( delay_fn, pt::seconds( 3) ); - tsk::handle< void > h( - tsk::async( boost::move( t), pool) ); - BOOST_CHECK( ! h.wait_until( boost::get_system_time() + pt::seconds( 1) ) ); - BOOST_CHECK( ! h.is_ready() ); - BOOST_CHECK( ! h.has_value() ); - BOOST_CHECK( ! h.has_exception() ); -} - -// check interrupt -void test_case_15() -{ - tsk::static_pool< - tsk::unbounded_fifo - > pool( tsk::poolsize( 3) ); - tsk::task< void > t( delay_fn, pt::seconds( 3) ); - tsk::handle< void > h( - tsk::async( boost::move( t), pool) ); - h.interrupt(); - BOOST_CHECK( h.interruption_requested() ); - BOOST_CHECK_THROW( h.get(), tsk::task_interrupted); -} - -// check interrupt_all_worker -void test_case_16() -{ - tsk::static_pool< - tsk::unbounded_fifo - > pool( tsk::poolsize( 5) ); - tsk::task< void > t1( delay_fn, pt::seconds( 3) ); - tsk::task< void > t2( delay_fn, pt::seconds( 3) ); - tsk::task< void > t3( delay_fn, pt::seconds( 3) ); - tsk::handle< void > h1( - tsk::async( boost::move( t1), pool) ); - tsk::handle< void > h2( - tsk::async( boost::move( t2), pool) ); - tsk::handle< void > h3( - tsk::async( boost::move( t3), pool) ); - boost::this_thread::sleep( pt::millisec( 250) ); - pool.interrupt_all_worker(); - BOOST_CHECK( ! h1.interruption_requested() ); - BOOST_CHECK( ! h2.interruption_requested() ); - BOOST_CHECK( ! h3.interruption_requested() ); - BOOST_CHECK_THROW( h1.get(), tsk::task_interrupted); - BOOST_CHECK_THROW( h2.get(), tsk::task_interrupted); - BOOST_CHECK_THROW( h3.get(), tsk::task_interrupted); - BOOST_CHECK_EQUAL( pool.size(), std::size_t( 5) ); -} - -// check interrupt_and_wait -void test_case_17() -{ - tsk::static_pool< - tsk::unbounded_fifo - > pool( tsk::poolsize( 3) ); - bool finished( false); - tsk::task< void > t( - interrupt_fn, - pt::seconds( 1), - boost::ref( finished) ); - tsk::handle< void > h( - tsk::async( boost::move( t), pool) ); - h.interrupt_and_wait(); - BOOST_CHECK( finished); - BOOST_CHECK( h.is_ready() ); - BOOST_CHECK( ! h.has_value() ); - BOOST_CHECK( h.has_exception() ); - BOOST_CHECK( h.interruption_requested() ); - BOOST_CHECK_THROW( h.get(), tsk::task_interrupted); -} - -// check interrupt_and_wait_for -void test_case_18() -{ - tsk::static_pool< - tsk::unbounded_fifo - > pool( tsk::poolsize( 3) ); - bool finished( false); - tsk::task< void > t( - interrupt_fn, - pt::seconds( 1), - boost::ref( finished) ); - tsk::handle< void > h( - tsk::async( boost::move( t), pool) ); - BOOST_CHECK( h.interrupt_and_wait_for( pt::seconds( 3) ) ); - BOOST_CHECK( finished); - BOOST_CHECK( h.is_ready() ); - BOOST_CHECK( ! h.has_value() ); - BOOST_CHECK( h.has_exception() ); - BOOST_CHECK( h.interruption_requested() ); - BOOST_CHECK_THROW( h.get(), tsk::task_interrupted); -} - -// check interrupt_and_wait_for -void test_case_19() -{ - tsk::static_pool< - tsk::unbounded_fifo - > pool( tsk::poolsize( 3) ); - tsk::task< void > t( non_interrupt_fn, 3); - tsk::handle< void > h( - tsk::async( boost::move( t), pool) ); - BOOST_CHECK( ! h.interrupt_and_wait_for( pt::seconds( 1) ) ); -} - -// check interrupt_and_wait_until -void test_case_20() -{ - tsk::static_pool< - tsk::unbounded_fifo - > pool( tsk::poolsize( 3) ); - bool finished( false); - tsk::task< void > t( - interrupt_fn, - pt::seconds( 1), - boost::ref( finished) ); - tsk::handle< void > h( - tsk::async( boost::move( t), pool) ); - BOOST_CHECK( h.interrupt_and_wait_until( boost::get_system_time() + pt::seconds( 3) ) ); - BOOST_CHECK( finished); - BOOST_CHECK( h.is_ready() ); - BOOST_CHECK( ! h.has_value() ); - BOOST_CHECK( h.has_exception() ); - BOOST_CHECK( h.interruption_requested() ); - BOOST_CHECK_THROW( h.get(), tsk::task_interrupted); -} - -// check interrupt_and_wait_until -void test_case_21() -{ - tsk::static_pool< - tsk::unbounded_fifo - > pool( tsk::poolsize( 3) ); - tsk::task< void > t( non_interrupt_fn, 3); - tsk::handle< void > h( - tsk::async( boost::move( t), pool) ); - BOOST_CHECK( ! h.interrupt_and_wait_until( boost::get_system_time() + pt::seconds( 1) ) ); -} - -// check fifo scheduling -void test_case_22() -{ - typedef tsk::static_pool< - tsk::unbounded_fifo - > pool_type; - BOOST_CHECK( ! tsk::has_attribute< pool_type >::value); - pool_type pool( tsk::poolsize( 1) ); - boost::barrier b( 2); - std::vector< int > buffer; - tsk::task< void > t1( barrier_fn, boost::ref( b) ); - tsk::task< void > t2( - buffer_fibonacci_fn, - boost::ref( buffer), - 10); - tsk::task< void > t3( - buffer_fibonacci_fn, - boost::ref( buffer), - 0); - tsk::async( boost::move( t1), pool); - boost::this_thread::sleep( pt::millisec( 250) ); - tsk::async( boost::move( t2), pool); - tsk::async( boost::move( t3), pool); - b.wait(); - pool.shutdown(); - BOOST_CHECK_EQUAL( buffer[0], 55); - BOOST_CHECK_EQUAL( buffer[1], 0); - BOOST_CHECK_EQUAL( buffer.size(), std::size_t( 2) ); -} - -boost::unit_test::test_suite * init_unit_test_suite( int, char* []) -{ - boost::unit_test::test_suite * test = - BOOST_TEST_SUITE("Boost.Task: unbounded-pool test suite"); - - test->add( BOOST_TEST_CASE( & test_case_1) ); - test->add( BOOST_TEST_CASE( & test_case_2) ); - test->add( BOOST_TEST_CASE( & test_case_3) ); - test->add( BOOST_TEST_CASE( & test_case_4) ); - test->add( BOOST_TEST_CASE( & test_case_5) ); - test->add( BOOST_TEST_CASE( & test_case_6) ); - test->add( BOOST_TEST_CASE( & test_case_7) ); - test->add( BOOST_TEST_CASE( & test_case_8) ); - test->add( BOOST_TEST_CASE( & test_case_9) ); - test->add( BOOST_TEST_CASE( & test_case_10) ); - test->add( BOOST_TEST_CASE( & test_case_11) ); - test->add( BOOST_TEST_CASE( & test_case_12) ); - test->add( BOOST_TEST_CASE( & test_case_13) ); - test->add( BOOST_TEST_CASE( & test_case_14) ); - test->add( BOOST_TEST_CASE( & test_case_15) ); - test->add( BOOST_TEST_CASE( & test_case_16) ); - test->add( BOOST_TEST_CASE( & test_case_17) ); - test->add( BOOST_TEST_CASE( & test_case_18) ); - test->add( BOOST_TEST_CASE( & test_case_19) ); - test->add( BOOST_TEST_CASE( & test_case_20) ); - test->add( BOOST_TEST_CASE( & test_case_21) ); - test->add( BOOST_TEST_CASE( & test_case_22) ); - - return test; -} diff --git a/libs/task/test/util.ipp b/libs/task/test/util.ipp deleted file mode 100644 index 7bcf96d9..00000000 --- a/libs/task/test/util.ipp +++ /dev/null @@ -1,159 +0,0 @@ -// Copyright (C) 2001-2003 -// William E. Kempf -// Copyright (C) 2007-8 Anthony Williams -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -#if !defined(UTIL_INL_WEK01242003) -#define UTIL_INL_WEK01242003 - -#include - -#include -#include -#include - -#ifndef DEFAULT_EXECUTION_MONITOR_TYPE -# define DEFAULT_EXECUTION_MONITOR_TYPE execution_monitor::use_condition -#endif - -// boostinspect:nounnamed -// - -namespace pt = boost::posix_time; - -namespace { - -class execution_monitor -{ -public: - enum wait_type { use_sleep_only, use_mutex, use_condition }; - - execution_monitor(wait_type type, int secs) - : done(false), type(type), secs(secs) { } - void start() - { - if (type != use_sleep_only) { - boost::mutex::scoped_lock lock(mutex); done = false; - } else { - done = false; - } - } - void finish() - { - if (type != use_sleep_only) { - boost::mutex::scoped_lock lock(mutex); - done = true; - if (type == use_condition) - cond.notify_one(); - } else { - done = true; - } - } - bool wait() - { - pt::time_duration xt = pt::seconds(secs); - if (type != use_condition) - boost::this_thread::sleep(xt); - if (type != use_sleep_only) { - boost::mutex::scoped_lock lock(mutex); - while (type == use_condition && !done) { - if (!cond.timed_wait(lock, xt)) - break; - } - return done; - } - return done; - } - -private: - boost::mutex mutex; - boost::condition cond; - bool done; - wait_type type; - int secs; -}; - -template -class indirect_adapter -{ -public: - indirect_adapter(F func, execution_monitor& monitor) - : func(func), monitor(monitor) { } - void operator()() const - { - try - { - boost::thread thrd(func); - thrd.join(); - } - catch (...) - { - monitor.finish(); - throw; - } - monitor.finish(); - } - -private: - F func; - execution_monitor& monitor; - void operator=(indirect_adapter&); -}; - -template -void timed_test(F func, int secs, - execution_monitor::wait_type type=DEFAULT_EXECUTION_MONITOR_TYPE) -{ - execution_monitor monitor(type, secs); - indirect_adapter ifunc(func, monitor); - monitor.start(); - boost::thread thrd(ifunc); - BOOST_REQUIRE_MESSAGE(monitor.wait(), - "Timed test didn't complete in time, possible deadlock."); -} - -template -class thread_binder -{ -public: - thread_binder(const F& func, const T& param) - : func(func), param(param) { } - void operator()() const { func(param); } - -private: - F func; - T param; -}; - -template -thread_binder bind(const F& func, const T& param) -{ - return thread_binder(func, param); -} - -template -class thread_member_binder -{ -public: - thread_member_binder(R (T::*func)(), T& param) - : func(func), param(param) { } - void operator()() const { (param.*func)(); } - -private: - void operator=(thread_member_binder&); - - R (T::*func)(); - T& param; -}; - - -template -thread_member_binder bind(R (T::*func)(), T& param) -{ - return thread_member_binder(func, param); -} -} // namespace - -#endif diff --git a/libs/tasklet/build/Jamfile.v2 b/libs/tasklet/build/Jamfile.v2 deleted file mode 100644 index 3b51a78f..00000000 --- a/libs/tasklet/build/Jamfile.v2 +++ /dev/null @@ -1,39 +0,0 @@ -# Boost.tasklet Library Build Jamfile - -# Copyright Oliver Kowalke 2009. -# Distributed under the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) - -import feature ; -import modules ; -import toolset ; - -project boost/tasklet - : source-location - ../src - : usage-requirements - shared:BOOST_TASKLET_DYN_LINK=1 - ; - -lib boost_tasklet - : auto_reset_event.cpp - barrier.cpp - condition.cpp - count_down_event.cpp - detail/tasklet_base.cpp - tasklet.cpp - manual_reset_event.cpp - mutex.cpp - round_robin.cpp - spin_condition.cpp - spin_mutex.cpp - strategy.cpp - ../../fiber/build//boost_fiber - ../../thread/build//boost_thread - : shared:BOOST_TASKLET_DYN_LINK=1 - : - : shared:../../fiber/build//boost_fiber - ; - -boost-install boost_tasklet ; diff --git a/libs/tasklet/doc/Jamfile.v2 b/libs/tasklet/doc/Jamfile.v2 deleted file mode 100644 index d6039250..00000000 --- a/libs/tasklet/doc/Jamfile.v2 +++ /dev/null @@ -1,33 +0,0 @@ -# (C) Copyright 2008 Anthony Williams -# -# Distributed under the Boost Software License, Version 1.0. (See accompanying -# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -path-constant boost-images : ../../../doc/src/images ; - -xml tasklet : tasklet.qbk ; - -boostbook standalone - : - tasklet - : - # HTML options first: - # Use graphics not text for navigation: - navig.graphics=1 - # How far down we chunk nested sections, basically all of them: - chunk.section.depth=3 - # Don't put the first section on the same page as the TOC: - chunk.first.sections=1 - # How far down sections get TOC's - toc.section.depth=10 - # Max depth in each TOC: - toc.max.depth=3 - # How far down we go with TOC's - generate.section.toc.level=10 - # Path for links to Boost: - boost.root=../../../.. - # Path for libraries index: - boost.libraries=../../../../libs/libraries.htm - # Use the main Boost stylesheet: - html.stylesheet=../../../../doc/html/boostbook.css - ; diff --git a/libs/tasklet/doc/barrier.qbk b/libs/tasklet/doc/barrier.qbk deleted file mode 100644 index 457d6840..00000000 --- a/libs/tasklet/doc/barrier.qbk +++ /dev/null @@ -1,52 +0,0 @@ -[/ - (C) Copyright 2007-8 Anthony Williams. - Distributed under the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt). -] - -[section:barriers Barriers] - -A barrier is a concept also known as a __rendezvous__, it is a synchronization -point between multiple contexts of execution (thread or tasklet). The barrier is -configured for a particular number of tasklets (`n`), and as tasklets reach the -barrier they must wait until all `n` tasklets have arrived. Once the `n`-th -tasklet has reached the barrier, all the waiting tasklets can proceed, and the -barrier is reset. - -[section:barrier Class `barrier`] - - #include - - class barrier - { - public: - barrier( unsigned int initial); - - bool wait(); - }; - - -Instances of __barrier__ are not copyable or movable. - -[section:constructor `barrier( unsigned int initial)`] -[variablelist -[[Effects:] [Construct a barrier for `initial` tasklets.]] -[[Throws:] [__invalid_argument__]] -] -[endsect] - -[section:wait `bool wait()`] -[variablelist -[[Effects:] [Block until `initial` tasklets have called `wait` on `*this`. When -the `initial`-th tasklet calls `wait`, all waiting tasklets are unblocked, and -the barrier is reset. ]] -[[Returns:] [`true` for exactly one tasklet from each batch of waiting tasklets, -`false` otherwise.]] -[[Throws:] [__tasklet_error__]] -] -[endsect] - -[endsect] - -[endsect] diff --git a/libs/tasklet/doc/channel.qbk b/libs/tasklet/doc/channel.qbk deleted file mode 100644 index a3e5ca33..00000000 --- a/libs/tasklet/doc/channel.qbk +++ /dev/null @@ -1,193 +0,0 @@ -[/ - Copyright Oliver Kowalke 2009. - Distributed under the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt -] - -[section:channels (Un)Bounded channels] - -__boost_tasklet__ provides a bounded and a unbounded channel suitable to -synchonize tasklets via message passing. - - typedef boost::tasklets::unbounded_channel< int > channel_t; - - void send( channel_t & channel) - { - for ( int i = 0; i < 5; ++i) - channel.put( i); - channel.deactivate(); - } - - void recv( channel_t & channel) - { - boost::optional< int > value; - while ( channel.take( value) ) - { std::cout << "received " << * value << std::endl; } - } - - boost::tasklets::scheduler<> sched; - channel_t channel; - sched.make_tasklet( send, ref( channel) ); - sched.make_tasklet( recv, ref( channel) ); - - for (;;) - { - while ( sched.run() ); - if ( sched.empty() ) break; - } - - -[section:unbounded_channel Template `template< typename T > unbounded_channel`] - - #include - - template< typename T > - class unbounded_channel : private noncopyable - { - public: - void deactivate(); - - bool empty(); - - void put( T const& t); - - bool take( boost::optional< T > & va); - - bool try_take( boost::optional< T > & va); - }; - -[section:deactivate `void deactivate()`] -[variablelist -[[Effects:] [Deactivates the channel. No values can be put after calling -`this->deactivate`. Tasklets blocked in -`this->take()` will be return.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:empty `bool empty()`] -[variablelist -[[Effects:] [Returns `true` if the channel currently contains no data.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:put `void put( T const& t)`] -[variablelist -[[Effects:] [Enqueues the value in the channel and wakes up a tasklet waiting -for new data available from the -channel.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:take `bool take( boost::optional< T > & va)`] -[variablelist -[[Effects:] [Dequeues a value from the channel. If no data is available from the -channel the tasklet gets suspended until new data are enqueued (return value -`true` and va contains dequeued value) or the channel gets deactiveted and the -function returns `false`.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:try_take `bool try_take( boost::optional< T > & va)`] -[variablelist -[[Effects:] [Dequeues a value from the channel. If no data is available from the -channel the function returns `false`. Otherwise it returns `true` and `va` -contains the dequed value.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[endsect] - - -[section:bounded_channel Template `template< typename T > bounded_channel`] - - #include - - template< typename T > - class bounded_channel : private noncopyable - { - public: - bounded_channel( std::size_t wm); - - bounded_channel( std::size_t hwm, std::size_t lwm); - - void deactivate(); - - bool empty(); - - void put( T const& t); - - bool take( boost::optional< T > & va); - - bool try_take( boost::optional< T > & va); - }; - -[section:constructor `bounded_channel( std::size_t wm)`] -[variablelist -[[Effects:] [Constructs an object of class `bounded_channel` which will contain -a maximum of `wm` items.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:constructor2 `bounded_channel( std::size_t hwm, std::size_t lwm)`] -[variablelist -[[Effects:] [Constructs an object of class `bounded_channel` which will contain -a high-watermark of `hwm` -and a low-watermark of `lwm` items.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:deactivate `void deactivate()`] -[variablelist -[[Effects:] [Deactivates the channel. No values can be put after calling -`this->deactivate`. Tasklets blocked in `this->take()` will be return.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:empty `bool empty()`] -[variablelist -[[Effects:] [Returns `true` if the channel currently contains no data.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:put `void put( T const& t)`] -[variablelist -[[Effects:] [Enqueues the value in the channel and wakes up a tasklet waiting -for new data available from the channel. If the watermark has reached the -tasklet putting the value will be supended until at least one item was -dequeued.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:take `bool take( boost::optional< T > & va)`] -[variablelist -[[Effects:] [Dequeues a value from the channel. If no data is available from the -channel the tasklet gets suspended until new data are enqueued (return value -`true` and va contains dequeued value) or the channel gets deactiveted and the -function returns `false`.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:try_take `bool try_take( boost::optional< T > & va)`] -[variablelist -[[Effects:] [Dequeues a value from the channel. If no data is available from the -channel the function returns `false`. Otherwise it returns `true` and `va` -contains the dequed value.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[endsect] - -[endsect] diff --git a/libs/tasklet/doc/condition_variables.qbk b/libs/tasklet/doc/condition_variables.qbk deleted file mode 100644 index f3007a7f..00000000 --- a/libs/tasklet/doc/condition_variables.qbk +++ /dev/null @@ -1,267 +0,0 @@ -[/ - (C) Copyright 2007-8 Anthony Williams. - Distributed under the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt). -] - -[section:conditions Condition Variables] - -[heading Synopsis] - -The class `condition` provides a mechanism for one tasklet to wait for -notification `condition`. When the tasklet is woken from the wait, then it -checks to see if the appropriate condition is now true, and continues if so. If -the condition is not true, then the tasklet then calls `wait` again to resume -waiting. In the simplest case, this condition is just a boolean variable: - - boost::tasklets::condition cond; - boost::tasklets::mutex mtx; - bool data_ready; - - void process_data(); - - void wait_for_data_to_process() - { - boost::unique_lock< boost::tasklets::mutex > lk( mtx); - while ( ! data_ready) - { - cond.wait( lk); - } - process_data(); - } - -Notice that the `lk` is passed to `wait`: `wait` will atomically add the tasklet -to the set of tasklets waiting on the condition variable, and unlock the mutex. -When the tasklet is woken, the mutex will be locked again before the call to -`wait` returns. This allows other tasklets to acquire the mutex in order to -update the shared data, and ensures that the data associated with the condition -is correctly synchronized. - -In the mean time, another tasklet sets the condition to `true`, and then calls -either `notify_one` or `notify_all` on the condition variable to wake one -waiting tasklet or all the waiting tasklets respectively. - - void retrieve_data(); - void prepare_data(); - - void prepare_data_for_processing() - { - retrieve_data(); - prepare_data(); - { - boost::lock_guard< boost::tasklets::mutex > lk( mtx); - data_ready = true; - } - cond.notify_one(); - } - -Note that the same mutex is locked before the shared data is updated, but that -the mutex does not have to be locked across the call to `notify_one`. - -[section:condition Class `condition`] - - #include - - class condition - { - public: - void notify_one(); - void notify_all(); - - void wait( boost::unique_lock< boost::tasklets::mutex > & lk); - - template< typename Pred > - void wait( boost::unique_lock< boost::tasklets::mutex > & lk, Pred pred); - - template< typename LockType > - void wait( LockType & lk); - - template< typename LockType, typename Pred > - void wait( LockType & lk, Pred predicate); - }; - -[section:notify_one `void notify_one()`] -[variablelist -[[Effects:] [If any tasklets are currently __blocked__ waiting on `*this` in a -call to `wait`, unblocks one of those tasklets.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:notify_all `void notify_all()`] -[variablelist -[[Effects:] [If any tasklets are currently __blocked__ waiting on `*this` in a -call to `wait`, unblocks all of those tasklets.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:wait `void wait( boost::unique_lock< boost::tasklets::mutex > & lk)`] -[variablelist -[[Precondition:] [`lk` is locked by the current tasklet, and either no other -tasklet is currently waiting on `*this`, or the execution of the `mutex()` -member function on the `lk` objects supplied in the calls to `wait` in all the -tasklets currently waiting on `*this` would return the same value as -`lk->mutex()` for this call to `wait`.]] -[[Effects:] [Atomically call `lk.unlock()` and blocks the current tasklet. The -tasklet will unblock when notified by a call to `this->notify_one()` or -`this->notify_all()`, or spuriously. When the tasklet is unblocked (for whatever -reason), the lock is reacquired by invoking `lk.lock()` before the call to -`wait` returns. The lock is also reacquired by invoking `lk.lock()` if the -function exits with an exception.]] -[[Postcondition:] [`lk` is locked by the current tasklet.]] -[[Throws:] [__tasklet_error__ if an error -occurs. __tasklet_interrupted__ if the wait was interrupted by a call to -__interrupt__ on the __tasklet__ object associated with the current tasklet of -execution.]] -] -[endsect] - -[section:wait_predicate `template< typename Pred > void wait( boost::unique_lock< boost::tasklets::mutex > & lk, Pred pred)`] -[variablelist -[[Effects:] [As-if `` -while ( ! pred()) -{ - wait( lk); -} -``]] - -] -[endsect] - -[section:wait_t `template< typename LockType > void wait( LockType & lk)`] -[variablelist -[[Effects:] [Atomically call `lk.unlock()` and blocks the current tasklet. The -tasklet will unblock when notified by a call to `this->notify_one()` or -`this->notify_all()`, or spuriously. When the tasklet is unblocked (for whatever -reason), the lock is reacquired by invoking `lk.lock()` before the call to -`wait` returns. The lock is also reacquired by invoking `lk.lock()` if the -function exits with an exception.]] -[[Postcondition:] [`lk` is locked by the current tasklet.]] -[[Throws:] [__tasklet_error__ if an error -occurs. __tasklet_interrupted__ if the wait was interrupted by a call to -__interrupt__ on the __tasklet__ object associated with the current tasklet of -execution.]] -] -[endsect] - -[section:wait_predicate_t `template< typename LockType, typename Pred > void wait( LockType & lk, Pred pred)`] -[variablelist -[[Effects:] [As-if `` -while ( ! pred()) -{ - wait( lock); -} -``]] - -] -[endsect] - -[endsect] - - -[section:spin_condition Class `spin_condition`] - - #include - - class spin_condition - { - public: - void notify_one(); - void notify_all(); - - void wait( boost::unique_lock< boost::tasklets::spin_mutex > & lk); - - template< typename Pred > - void wait( boost::unique_lock< boost::tasklets::spin_mutex > & lk, Pred pred); - - template< typename LockType > - void wait( LockType & lk); - - template< typename LockType, typename Pred > - void wait( LockType & lk, Pred predicate); - }; - -[section:notify_one `void notify_one()`] -[variablelist -[[Effects:] [If any tasklets are currently __blocked__ waiting on `*this` in a -call to `wait`, unblocks one of -those tasklets.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:notify_all `void notify_all()`] -[variablelist -[[Effects:] [If any tasklets are currently __blocked__ waiting on `*this` in a -call to `wait`, unblocks all of -those tasklets.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:wait `void wait( boost::unique_lock< boost::tasklets::spin_mutex > & lk)`] -[variablelist -[[Precondition:] [`lk` is locked by the current tasklet, and either no other -tasklet is currently waiting on `*this`, or the execution of the `spin_mutex()` -member function on the `lk` objects supplied in the calls to `wait` in all the -tasklets currently waiting on `*this` would return the same value as -`lk->mutex()` for this call to `wait`.]] -[[Effects:] [Atomically call `lk.unlock()` and blocks the current tasklet. The -tasklet will unblock when notified by a call to `this->notify_one()` or -`this->notify_all()`, or spuriously. When the tasklet is unblocked (for whatever -reason), the lock is reacquired by invoking `lk.lock()` before the call to -`wait` returns. The lock is also reacquired by invoking `lk.lock()` if the -function exits with an exception.]] -[[Postcondition:] [`lk` is locked by the current tasklet.]] -[[Throws:] [__tasklet_error__ if an error -occurs. __tasklet_interrupted__ if the wait was interrupted by a call to -__interrupt__ on the __tasklet__ object associated with the current tasklet of -execution.]] -] -[endsect] - -[section:wait_predicate `template< typename Pred > void wait( boost::unique_lock< boost::tasklets::spin_mutex > & lk, Pred pred)`] -[variablelist -[[Effects:] [As-if `` -while ( ! pred()) -{ - wait( lk); -} -``]] - -] -[endsect] - -[section:wait_t `template< typename LockType > void wait( LockType & lk)`] -[variablelist -[[Effects:] [Atomically call `lk.unlock()` and blocks the current tasklet. The -tasklet will unblock when notified by a call to `this->notify_one()` or -`this->notify_all()`, or spuriously. When the tasklet is unblocked (for whatever -reason), the lock is reacquired by invoking `lk.lock()` before the call to -`wait` returns. The lock is also reacquired by invoking `lk.lock()` if the -function exits with an exception.]] -[[Postcondition:] [`lk` is locked by the current tasklet.]] -[[Throws:] [__tasklet_error__ if an error -occurs. __tasklet_interrupted__ if the wait was interrupted by a call to -__interrupt__ on the __tasklet__ object associated with the current tasklet of -execution.]] -] -[endsect] - -[section:wait_predicate_t `template< typename LockType, typename Pred > void wait( LockType & lk, Pred pred)`] -[variablelist -[[Effects:] [As-if `` -while ( ! pred()) -{ - wait( lock); -} -``]] - -] -[endsect] - -[endsect] - -[endsect] diff --git a/libs/tasklet/doc/event_variables.qbk b/libs/tasklet/doc/event_variables.qbk deleted file mode 100644 index 216b8bb2..00000000 --- a/libs/tasklet/doc/event_variables.qbk +++ /dev/null @@ -1,283 +0,0 @@ -[/ - (C) Copyright 2007-8 Anthony Williams. - Distributed under the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt). -] - -[section:eventvar_ref Event Variables] - -[heading Synopsis] - -__boost_tasklet__ provides event variables to facilitate coordination between -tasklets. A event-variable has two states `set` (`signaled`) or `reset` -(`nonsignaled`). - - boost::tasklets::auto_reset_event ev; - - void process_data(); - - void wait_for_data_to_process() - { - ev.wait(); - process_data(); - } - -`wait` will atomically add the tasklet to the set of tasklets waiting on the -event variable. When the tasklet is woken, the event variable will be reset -again. - -In the mean time, another tasklet signals the event variable by calling `set` -on the event variable to wake one waiting tasklet. - - void retrieve_data(); - void prepare_data(); - - void prepare_data_for_processing() - { - retrieve_data(); - prepare_data(); - ev.set(); - } - - -[section:auto_reset_event Class `auto_reset_event`] - -[heading Synopsis] - -When the ['auto_reset_event] gets signaled, any one tasklet will see this -particular signal. When a tasklet observes the signal by waiting on the event, -it is automatically transitioned back to non-signaled state. Any tasklets can -subsequently set the event. - - #include - - class auto_reset_event : private boost::noncopyable - { - public: - auto_reset_event( bool isset = false); - - ~auto_reset_event(); - - void set(); - - void wait(); - - bool try_wait(); - }; - -[section:constructor `auto_reset_event( bool isset = false)`] -[variablelist -[[Effects:] [Constructs an object of class `auto_reset_event`. If isset is -`true` the variable is set.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:destructor `~auto_reset_event()`] -[variablelist -[[Precondition:] [All tasklets waiting on `*this` have been notified by a call -to `set` (though the respective calls to `wait` need not have returned).]] -[[Effects:] [Destroys the object.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:set `void set()`] -[variablelist -[[Effects:] [If any tasklets are currently __blocked__ waiting on `*this` in a -call to `wait`, unblocks one of those tasklets.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:wait `void wait()`] -[variablelist -[[Effects:] [Blocks the current tasklet. The tasklet will unblock when notified -by a call to `this->set()`. When the tasklet is unblocked, the variable is reset -before `wait` returns.]] -[[Throws:] [__tasklet_interrupted__ if the wait was interrupted by a call to -__interrupt__ on the __tasklet__ object associated with the current tasklet of -execution.]] -] -[endsect] - -[section:try_wait `bool try_wait()`] -[variablelist -[[Effects:] [Returns `true` if the event variable is set otherwise `false`.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[endsect] - - -[section:manual_reset_event Class `manual_reset_event`] - -[heading Synopsis] - -The ['manual_reset_event] remains signaled until it is manually reset. Multiple -tasklets wait on the same event and observe the same signal. - - #include - - class manual_reset_event : private boost::noncopyable - { - public: - manual_reset_event( bool isset = false); - - ~manual_reset_event(); - - void set(); - - void reset(); - - void wait(); - - bool try_wait(); - }; - -[section:constructor `manual_reset_event( bool isset = false)`] -[variablelist -[[Effects:] [Constructs an object of class `manual_reset_event`. If isset is -`true` the variable is set.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:destructor `~manual_reset_event()`] -[variablelist -[[Precondition:] [All tasklets waiting on `*this` have been notified by a call -to `set` (though the respective calls to `wait` need not have returned).]] -[[Effects:] [Destroys the object.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:set `void set()`] -[variablelist -[[Effects:] [If any tasklets are currently __blocked__ waiting on `*this` in a -call to `wait`, unblocks those tasklets. The variable remains signaled until -`this->reset()` gets called.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:reset `void reset()`] -[variablelist -[[Effects:] [The event variable gets nonsignaled and tasklets calling -`this->wait()` will block.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:wait `void wait()`] -[variablelist -[[Effects:] [Blocks the current tasklet. The tasklet will unblock when notified -by a call to `this->set()`. When the tasklet is unblocked, the variable remains -set.]] -[[Throws:] [__tasklet_interrupted__ if the wait was interrupted by a call to -__interrupt__ on the __tasklet__ object associated with the current tasklet of -execution.]] -] -[endsect] - -[section:trywait `boo try_wait()`] -[variablelist -[[Effects:] [Returns `true` if the event variable is set otherwise `false`.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[endsect] - - -[section:count_down_event Class `count_down_event`] - -[heading Synopsis] - -The ['count_down_event] decrements an internal counter (set in the constructor) -and all waiting tasklets are blocked until the count reaches zero. - - #include - - class count_down_event : private boost::noncopyable - { - public: - count_down_event( unsigned int initial); - - ~count_down_event(); - - unsigned int initial() const; - - unsigned int current() const; - - bool is_set() const; - - void set(); - - void wait(); - }; - -[section:constructor `count_down_event( unsigned int initial)`] -[variablelist -[[Effects:] [Constructs an object of class `count_down_event` with initial -value.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:destructor `~count_down_event()`] -[variablelist -[[Precondition:] [All tasklets waiting on `*this` have been notified by a call -to `set` (though the respective calls to `wait` need not have returned).]] -[[Effects:] [Destroys the object.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:initial `unsigned int initial()`] -[variablelist -[[Effects:] [Returns the initial value the event variable was initialized -with.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:current `unsigned int current()`] -[variablelist -[[Effects:] [Returns the value the variable currently holds.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:is_set `bool is_set()`] -[variablelist -[[Effects:] [Returns `true` if the varaible has reached zero.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:set `void set()`] -[variablelist -[[Effects:] [Decrements the current count. If the count reaches zero and any -tasklets are currently __blocked__ waiting on `*this` in a call to `wait`, -unblocks those tasklets. The variable remains signaled.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:wait `void wait()`] -[variablelist -[[Effects:] [Blocks the current tasklet. The tasklet will unblock when notified -by a call to `this->set()` and the count of the event variable reaches zero. -When the tasklet is unblocked, the variable remains set.]] -[[Throws:] [__tasklet_interrupted__ if the wait was interrupted by a call to -__interrupt__ on the __tasklet__ object associated with the current tasklet of -execution.]] -] -[endsect] - -[endsect] - -[endsect] diff --git a/libs/tasklet/doc/html/standalone_HTML.manifest b/libs/tasklet/doc/html/standalone_HTML.manifest deleted file mode 100644 index e125ad08..00000000 --- a/libs/tasklet/doc/html/standalone_HTML.manifest +++ /dev/null @@ -1,55 +0,0 @@ -index.html -tasklet/overview.html -tasklet/tasklet_management.html -tasklet/tasklet_management/tasklet.html -tasklet/tasklet_management/tasklet/default_constructor.html -tasklet/tasklet_management/tasklet/callable_constructor_stack.html -tasklet/tasklet_management/tasklet/multiple_argument_constructor.html -tasklet/tasklet_management/tasklet/destructor.html -tasklet/tasklet_management/tasklet/get_id.html -tasklet/tasklet_management/tasklet/join.html -tasklet/tasklet_management/tasklet/interrupt.html -tasklet/tasklet_management/tasklet/interruption_requested.html -tasklet/tasklet_management/tasklet/cancel.html -tasklet/tasklet_management/tasklet/is_alive.html -tasklet/tasklet_management/tasklet/unspec_operator.html -tasklet/tasklet_management/tasklet/not_operator.html -tasklet/tasklet_management/tasklet/equals.html -tasklet/tasklet_management/tasklet/not_equals.html -tasklet/tasklet_management/tasklet/swap.html -tasklet/tasklet_management/tasklet/non_member_swap.html -tasklet/tasklet_management/tasklet/non_member_make_tasklet.html -tasklet/tasklet_management/tasklet/id.html -tasklet/tasklet_management/this_tasklet.html -tasklet/tasklet_management/this_tasklet/get_id.html -tasklet/tasklet_management/this_tasklet/interruption_point.html -tasklet/tasklet_management/this_tasklet/interruption_requested.html -tasklet/tasklet_management/this_tasklet/interruption_enabled.html -tasklet/tasklet_management/this_tasklet/cancel.html -tasklet/tasklet_management/this_tasklet/non_member_yield.html -tasklet/tasklet_management/this_tasklet/attaskletexit.html -tasklet/tasklet_management/this_tasklet/submit.html -tasklet/tasklet_management/this_tasklet/disable_interruption.html -tasklet/tasklet_management/this_tasklet/restore_interruption.html -tasklet/tasklet_management/scheduler.html -tasklet/tasklet_management/scheduler/scheduler.html -tasklet/tasklet_management/strategy.html -tasklet/tasklet_management/strategy/strategy.html -tasklet/tasklet_management/strategy/round_robin.html -tasklet/synchronization.html -tasklet/synchronization/mutex_types.html -tasklet/synchronization/mutex_types/mutex.html -tasklet/synchronization/mutex_types/spin_mutex.html -tasklet/synchronization/conditions.html -tasklet/synchronization/conditions/condition.html -tasklet/synchronization/conditions/spin_condition.html -tasklet/synchronization/barriers.html -tasklet/synchronization/barriers/barrier.html -tasklet/synchronization/eventvar_ref.html -tasklet/synchronization/eventvar_ref/auto_reset_event.html -tasklet/synchronization/eventvar_ref/manual_reset_event.html -tasklet/synchronization/eventvar_ref/count_down_event.html -tasklet/synchronization/channels.html -tasklet/synchronization/channels/unbounded_channel.html -tasklet/synchronization/channels/bounded_channel.html -tasklet/todo.html diff --git a/libs/tasklet/doc/mutexes.qbk b/libs/tasklet/doc/mutexes.qbk deleted file mode 100644 index 8e75a337..00000000 --- a/libs/tasklet/doc/mutexes.qbk +++ /dev/null @@ -1,67 +0,0 @@ -[/ - (C) Copyright 2007-8 Anthony Williams. - Distributed under the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt). -] - -[section:mutex_types Mutex Types] - -[section:mutex Class `mutex`] - - #include - - class mutex : private boost::noncopyable - { - public: - mutex(); - - ~mutex(); - - void lock(); - bool try_lock(); - void unlock(); - - typedef unique_lock< mutex > scoped_lock; - }; - -__mutex__ implements the __lockable_concept__ to provide an exclusive-ownership -mutex. At most one tasklet can own the lock on a given instance of __mutex__ at -any time. Multiple concurrent calls to __lock__, __try_lock__ and __unlock__ -shall be permitted. - -The tasklets blocked in __lock__ are suspended in the scheduler until get -signaled. - -[endsect] - -[section:spin_mutex Class `spin_mutex`] - - #include - - class spin_mutex : private boost::noncopyable - { - public: - spin_mutex(); - - ~spin_mutex(); - - void lock(); - bool try_lock(); - void unlock(); - - typedef unique_lock< spin_mutex > scoped_lock; - }; - -__spin_mutex__ implements the __lockable_concept__ to provide an -exclusive-ownership mutex. At most one tasklet can own the lock on a given -instance of __mutex__ at any time. Multiple concurrent calls to __lock__, -__try_lock__ and __unlock__ shall be permitted. - -The tasklets and threads blocked in __lock__ are spin waiting until the lock get -released, e.g. try to get an calling __tasklet_yield__/__thread_yield__. - - -[endsect] - -[endsect] diff --git a/libs/tasklet/doc/overview.qbk b/libs/tasklet/doc/overview.qbk deleted file mode 100644 index 52a6cb87..00000000 --- a/libs/tasklet/doc/overview.qbk +++ /dev/null @@ -1,54 +0,0 @@ -[/ - Copyright Oliver Kowalke 2009. - Distributed under the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt -] - -[section:overview Overview] - -__boost_tasklet__ provides a framework of cooperative micro-tasks (tasklets) -scheduled inside a thread. -The API contains classes and functions to manage and synchronize tasklets ( -mutext, condition- and event-variables, ...). - -A tasklet is able to store the current execution state, including all registers -and CPU flags, the instruction pointer, and the stack pointer and later restore -this state. The idea is to have multiple execution paths running on a single -thread using a sort of cooperative scheduling (threads are preemptively -scheduled) - the running tasklet decides explicitly when its yields to allow -another tasklet to run (context switching). -A context switch between threads costs usally thousends of CPU cycles on x86 -compared to a tasklet switch with few hundreds of cycles. -A tasklet can only run on a single thread at any point in time but may be -migrated between threads. - -In order to use the classes and functions described here, you can either include -the specific headers specified by the descriptions of each class or function, or -include the master library header: - - #include - -which includes all the other headers in turn. - -Used namespaces are: - - namespace boost::tasklets - namespace boost::this_tasklet - - -[warning This library is ['not] an official Boost library] - -__boost_tasklet__ depends uppon __boost_atomic__, __boost_context__ and -__boost_move__. - - -[heading How to build and install] - -* download the sources from -[@http://www.boost-consulting.com/vault/index.php?directory=Concurrent%20Programming Boost Vault] -* extract the archive into the boost-source directory -* call ['bjam] (consider installation options of __boost_context__) - - -[endsect] diff --git a/libs/tasklet/doc/synchronization.qbk b/libs/tasklet/doc/synchronization.qbk deleted file mode 100644 index a9a26c35..00000000 --- a/libs/tasklet/doc/synchronization.qbk +++ /dev/null @@ -1,15 +0,0 @@ -[/ - Copyright Oliver Kowalke 2009. - Distributed under the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt -] - -[section:synchronization Synchronization] - -include mutexes.qbk] -[include condition_variables.qbk] -[include barrier.qbk] -[include event_variables.qbk] -[include channel.qbk] -[endsect] diff --git a/libs/tasklet/doc/tasklet.qbk b/libs/tasklet/doc/tasklet.qbk deleted file mode 100644 index 6032011f..00000000 --- a/libs/tasklet/doc/tasklet.qbk +++ /dev/null @@ -1,102 +0,0 @@ -[/ - Copyright Oliver Kowalke 2009. - Distributed under the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt -] - -[article Tasklet - [quickbook 1.4] - [authors [Kowalke, Oliver]] - [copyright 2009 Oliver Kowalke] - [purpose C++ Library for cooperativly schedule and synchronize multiple tasklets (micro-tasks) in one thread] - [category text] - [license - Distributed under the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or copy at - [@http://www.boost.org/LICENSE_1_0.txt]) - ] -] - - -[def __boost_atomic__ [*Boost.Atomic]] -[def __boost_context__ [*Boost.Context]] -[def __boost_move__ [*Boost.Move]] -[def __boost_tasklet__ [*Boost.Tasklet]] -[def __boost_thread__ [*Boost.Thread]] - -[template auto_reset_link[link_text] [link tasklet.synchronization.eventvar_ref.auto_reset_event [link_text]]] -[template barrier_link[link_text] [link tasklet.synchronization.barriers [link_text]]] -[template condition_link[link_text] [link tasklet.synchronization.conditions.condition [link_text]]] -[template count_down_link[link_text] [link tasklet.synchronization.eventvar_ref.count_down_event [link_text]]] -[template manual_reset_link[link_text] [link tasklet.synchronization.eventvar_ref.manual_reset_event [link_text]]] -[template mutex_link[link_text] [link tasklet.synchronization.mutex_types.mutex [link_text]]] -[template scheduler_link[link_text] [link tasklet.tasklet_management.scheduler [link_text]]] -[template scheduler_thread_link[link_text] [link tasklet.tasklet_management.scheduler_thread [link_text]]] -[template tasklet_id_link[link_text] [link tasklet.tasklet_management.tasklet.id [link_text]]] -[template tasklet_link[link_text] [link tasklet.tasklet_management.tasklet [link_text]]] - -[template auto_reset_wait_link[link_text] [link tasklet.synchronization.eventvar_ref.auto_reset_event.wait [link_text]]] -[template manual_reset_wait_link[link_text] [link tasklet.synchronization.eventvar_ref.manual_reset_event.wait [link_text]]] -[template count_down_wait_link[link_text] [link tasklet.synchronization.eventvar_ref.count_down_event.wait [link_text]]] -[template cond_wait_link[link_text] [link tasklet.synchronization.conditions.condition.wait [link_text]]] - -[template disable_interr_link[link_text] [link tasklet.tasklet_management.this_tasklet.disable_interruption [link_text]]] -[template interr_enabled_link[link_text] [link tasklet.tasklet_management.this_tasklet.interruption_enabled [link_text]]] -[template interr_point_link[link_text] [link tasklet.tasklet_management.this_tasklet.interruption_point [link_text]]] -[template interr_points_link[link_text] [link tasklet.tasklet_management.predefined_interruption_points [link_text]]] -[template interr_requested_link[link_text] [link tasklet.tasklet_management.this_tasklet.interruption_requested [link_text]]] -[template interrupt_link[link_text] [link tasklet.tasklet_management.tasklet.interrupt [link_text]]] -[template join_link[link_text] [link tasklet.tasklet_management.tasklet.join [link_text]]] -[template restore_interr_link[link_text] [link tasklet.tasklet_management.this_tasklet.restore_interruption [link_text]]] -[template tasklet_yield_link[link_text] [link tasklet.tasklet_management.this_tasklet.yield [link_text]]] -[template scheduler_yield_link[link_text] [link tasklet.tasklet_management.scheduler.yield [link_text]]] -[template scheduler_run_link[link_text] [link tasklet.tasklet_management.scheduler.run [link_text]]] -[template scheduler_empty_link[link_text] [link tasklet.tasklet_management.scheduler.empty [link_text]]] - -[def __blocked__ ['blocked]] -[def __not_a_tasklet__ ['not-a-tasklet]] -[def __lockable_concept__ ['lockable concept]] -[def __rendezvous__ ['rendezvous]] - -[def __auto_reset_event__ [auto_reset_link ['auto-reset event]]] -[def __barrier__ [barrier_link ['barrier]]] -[def __condition__ [condition_link ['condition]]] -[def __count_down_event__ [count_down_link ['count-down event]]] -[def __interruption_points__ [interr_points_link ['interruption points]]] -[def __manual_reset_event__ [manual_reset_link ['manual-reset event]]] -[def __mutex__ [mutex_link ['mutex]]] -[def __scheduler__ [scheduler_link ['scheduler]]] -[def __tasklet_id__ [tasklet_id_link ['tasklet-id]]] -[def __tasklet__ [tasklet_link ['tasklet]]] - -[def __cond_wait__ [cond_wait_link `wait()`]] -[def __interrupt__ [interrupt_link `interrupt()`]] -[def __join__ [join_link `join()`]] -[def __lock__ `lock()`] -[def __try_lock__ `try_lock()`] -[def __unlock__ `unlock()`] - -[def __interruption_enabled__ [interr_enabled_link `boost::this_tasklet::interruption_enabled()`]] -[def __interruption_requested__ [interr_requested_link `boost::this_tasklet::interruption_requested()`]] -[def __interruption_point__ [interr_point_link `boost::this_tasklet::interruption_point()`]] -[def __disable_interruption__ [disable_interr_link `boost::this_tasklet::disable_interruption`]] -[def __restore_interruption__ [restore_interr_link `boost::this_tasklet::restore_interruption`]] - -[def __scheduler_empty__ [scheduler_empty_link `boost::scheduler::empty()`]] -[def __scheduler_run__ [scheduler_run_link `boost::scheduler::run()`]] -[def __scheduler_yield__ [scheduler_yield_link `boost::scheduler::yield()`]] -[def __tasklet_yield__ [tasklet_yield_link `boost::this_tasklet::yield()`]] - -[def __tasklet_error__ `boost::tasklets::tasklet_error`] -[def __tasklet_interrupted__ `boost::tasklets::tasklet_interrupted`] -[def __tasklet_moved__ `boost::tasklets::tasklet_moved`] -[def __invalid_argument__ `std::invalid_argument`] -[def __lock_error__ `boost::tasklets::lock_error`] - - - -[include overview.qbk] -[include tasklet_ref.qbk] -[include synchronization.qbk] -[include todo.qbk] diff --git a/libs/tasklet/doc/tasklet_ref.qbk b/libs/tasklet/doc/tasklet_ref.qbk deleted file mode 100644 index eaef60a7..00000000 --- a/libs/tasklet/doc/tasklet_ref.qbk +++ /dev/null @@ -1,1255 +0,0 @@ -[/ - (C) Copyright 2007-8 Anthony Williams. - Distributed under the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt). -] - -[section:tasklet_management Tasklet Management] - -[heading Synopsis] - -Each __tasklet__ class represents a micro-task which will be launched and -managed by the __scheduler__ class. Objects of type __tasklet__ are copy- and -moveable. - - boost::tasklet f; // not-a-tasklet - - void f() - { - boost::tasklet f1( some_fn, boost::tasklet::default_stacksize); - - boost::scheduler::schedule( f1); // f1 gets copied - boost::scheduler::schedule( boost::move( f2) ); // f2 gets moved - - std::cout << f1.get_id() << std::endl; - std::cout << f2.get_id() << std::endl; - } - - -[note If tasklets are migrated between threads the code called by a tasklet must -not use thread-local-storage.] - - -[heading Launching] - -A new tasklet is launched by passing an object of a callable type that can be -invoked with no parameters to the constructor and submiting the tasklet (copy- -or move-op.) to __scheduler__. The object is then copied into -internal storage, and invoked on the newly-created tasklet. If the object must -not (or cannot) be copied, then `boost::ref` can be used to pass in a reference -to the function object. In this case, the user of __boost_tasklet__ must ensure -that the referred-to object outlives the newly-created tasklet. - - struct callable - { void operator()(); }; - - boost::tasklet copies_are_safe() - { - callable x; - return boost::tasklet( x); - } // x is destroyed, but the newly-created tasklet has a copy, so this is OK - - boost::tasklet oops() - { - callable x; - return boost::tasklet( boost::ref( x), boost::tasklet::default_stacksize); - } // x is destroyed, but the newly-created tasklet still has a reference - // this leads to undefined behaviour - -If you wish to construct an instance of __tasklet__ with a function or callable -object that requires arguments to be supplied, this can be done by passing -additional arguments to the __tasklet__ constructor: - - void find_the_question( int the_answer); - - boost::tasklet deep_thought_2( find_the_question, 42, boost::tasklet::default_stacksize); - -The arguments are ['copied] into the internal tasklet structure: if a reference -is required, use `boost::ref`, just as for references to callable functions. - -For convinience `boost::tasklets::make_tasklet()` is provided: - - boost::tasklet f( boost::tasklets::make_tasklet( new_fn, arg1, arg2, arg3, boost::tasklet::default_stacksize) ); - -Another alternative is to use `scheduler<>::make_tasklet()` which creates and -stores the new tasklet inside the scheduler. - - boost::tasklets::scheduler<> sched; - sched.make_tasklet( new_fn, arg1, arg2, arg3, boost::tasklet_default_stacksize); - - -[heading Exceptions] - -Exceptions thrown by the function or callable object passed to the __tasklet__ -constructor are consumed by the framework (if it required to know which -exceptions was thrown use __future__ and __packaged_task__). - -[warning Don't use the sjlj exception model. Frame-unwind-tables instead of -setjmp/longjmp based exception handling should be used.] - -[heading Joining] - -In order to wait for a tasklet to finish, the __join__ member functions of the -__tasklet__ object can be used. __join__ will block the calling tasklet until -the tasklet represented by the __tasklet__ object has completed. -If the tasklet has already completed, or the __tasklet__ object represents -__not_a_tasklet__, then __join__ returns immediately. - - void some_fn() - {} - - void joining_tasklet_fn( boost::tasklet f) - { f.join(); } - - boost:.tasklets::scheduler<> sched; - boost::tasklet f( some_fn, boost::tasklet_default_stacksize); - sched.submit_tasklet( f); - sched.make_tasklet( joining_tasklet, f, boost::tasklet_default_stacksize); - for (;;) - { - while ( sched.run() ); - if ( sched.empty() ) break; - } - - -[heading Interruption] - -A running tasklet can be ['interrupted] by invoking the __interrupt__ member -function. When the interrupted tasklet next executes one of the specified -__interruption_points__ (or if it is currently __blocked__ whilst executing one) -with interruption enabled, then a __tasklet_interrupted__ exception will be -thrown in the interrupted tasklet. If not caught, this will cause the execution -of the interrupted tasklet to terminate. - -If a tasklet wishes to avoid being interrupted, it can create an instance of -__disable_interruption__. Objects of this class disable interruption for the -tasklet that created them on construction, and restore the interruption state to -whatever it was before on destruction: - - void f() - { - // interruption enabled here - { - boost::this_tasklet::disable_interruption disabler1; - // interruption disabled - { - boost::this_tasklet::disable_interruption disabler2; - // interruption still disabled - } // disabler2 destroyed, interruption state restored - // interruption still disabled - } // disabler1 destroyed, interruption state restored - // interruption now enabled - } - -The effects of an instance of __disable_interruption__ can be temporarily -reversed by constructing an instance of __restore_interruption__, passing in the -__disable_interruption__ object in question. This will restore the interruption -state to what it was when the __disable_interruption__ object was constructed, -and then disable interruption again when the __restore_interruption__ object is -destroyed. - - void g() - { - // interruption enabled here - { - boost::this_tasklet::disable_interruption disabler; - // interruption disabled - { - boost::this_tasklet::restore_interruption restorer( disabler); - // interruption now enabled - } // restorer destroyed, interruption disable again - } // disabler destroyed, interruption state restored - // interruption now enabled - } - -At any point, the interruption state for the current tasklet can be queried by -calling __interruption_enabled__. - - -[heading Predefined Interruption Points] - -The following functions are ['interruption points], which will throw -__tasklet_interrupted__ if interruption is enabled for the current tasklet, and -interruption is requested for the current tasklet: - -* [join_link `boost::tasklet::join()`] -* [cond_wait_link `boost::tasklets::condition::wait()`] -* [auto_reset_wait_link `boost::tasklets::auto_reset_event::wait()`] -* [manual_reset_wait_link `boost::tasklets::manual_reset_event::wait()`] -* [count_down_wait_link `boost::tasklets::count_down_event::wait()`] -* __interruption_point__ - - -[heading Tasklet IDs] - -Objects of class __tasklet_id__ can be used to identify tasklets. Each running -tasklet has a unique ID obtainable from the corresponding __tasklet__ by calling -the `get_id()` member function, or by calling `boost::this_tasklet::get_id()` -from within the tasklet. Objects of class __tasklet_id__ can be copied, and used -as keys in associative containers: the full range of comparison operators is -provided. Tasklet IDs can also be written to an output stream using the stream -insertion operator, though the output format is unspecified. - -Each instance of __tasklet_id__ either refers to some tasklet, or -__not_a_tasklet__. Instances that refer to __not_a_tasklet__ compare equal to -each other, but not equal to any instances that refer to an actual tasklet. The -comparison operators on __tasklet_id__ yield a total order for every non-equal -tasklet ID. - - -[section:tasklet Class `tasklet`] - - #include - - class tasklet - { - public: - tasklet(); - ~tasklet(); - - template< typename Fn > - explicit tasklet( Fn fn, std::size_t stack_size); - - template< typename Fn, typename A1, typename A2,... > - tasklet( Fn fn, A1 a1, A2 a2,..., std::size_t stack_size); - - template< typename Fn > - explicit tasklet( Fn && fn, std::size_t stack_size); - - // move support - tasklet( tasklet && x); - tasklet & operator=( tasklet && x); - - operator unspecified-bool-type() const; - - bool operator!() const; - - void swap( tasklet & other); - - id get_id() const; - - bool operator==( tasklet const&) const; - bool operator!=( tasklet const&) const; - - bool is_alive() const; - - int priority() const; - - void priority( int); - - void interrupt(); - bool interruption_requested() const; - - void cancel(); - - void join(); - }; - - void swap( tasklet & lhs, tasklet & rhs); - - template< typename Fn > - tasklet make_tasklet( Fn fn, std::size_t stack_size); - - template< typename Fn, typename A1, typename A2,..., typename A10 > - tasklet make_tasklet( Fn fn, A1 a1, A2 a2,..., A10 a10, std::size_t stack_size); - - -[section:default_constructor `tasklet()`] -[variablelist -[[Effects:] [Constructs a __tasklet__ instance that refers to -__not_a_tasklet__.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:callable_constructor_stack `template< typename Fn > tasklet( Fn fn, std::size_t stack_size)`] -[variablelist -[[Preconditions:] [`Callable` must by copyable.]] -[[Effects:] [`fn` is copied into storage managed internally by the tasklet -library, and that copy is invoked on a newly-created tasklet. Second version -sets the stack-size of the tasklet.]] -[[Postconditions:] [`*this` refers to the newly created tasklet.]] -[[Throws:] [__bad_alloc__]] -] -[endsect] - -[section:multiple_argument_constructor `template< typename Fn, typename A1, typename A2,... > tasklet( Fn fn, A1 a1, A2 a2,..., std::size_t stack_size)`] -[variablelist -[[Preconditions:] [`Fn` and each `A`n must by copyable or movable.]] -[[Effects:] [As if `tasklet( boost::bind( fn, a1, a2,...) )`. Consequently, -`fn` and each `a`n are copied into internal storage for access by the new -tasklet. Second version additionaly sets the stack-size used by the tasklet.]] -[[Postconditions:] [`*this` refers to the newly created tasklet.]] -[[Throws:] [__bad_alloc__]] -[[Note:] [Currently up to nine additional arguments `a1` to `a9` can be -specified in addition to the function `fn`.]] -] -[endsect] - -[section:destructor `~tasklet()`] -[variablelist -[[Effects:] [Destroys `*this`.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:get_id `tasklet::id get_id() const`] -[variablelist -[[Returns:] [If `*this` refers to a tasklet, an instance of __tasklet_id__ that -represents that tasklet. Otherwise returns a default-constructed -__tasklet_id__.]] -[[Throws:] [Nothing.]] -] - -[endsect] - -[section:join `void join()`] -[variablelist -[[Effects:] [Waits for `*this` to complete.]] -[[Throws:] [__tasklet_interrupted__ if the current tasklet is interrupted.]] -[[Notes:] [`join()` is one of the predefined __interruption_points__.]] -] -[endsect] - -[section:interrupt `void interrupt()`] -[variablelist -[[Effects:] [If `*this` refers to a tasklet, request that the tasklet will be -interrupted the next time it enters one of the predefined -__interruption_points__ with interruption enabled, or if it is currently -__blocked__ in a call to one of the predefined __interruption_points__ with -interruption enabled .]] -[[Throws:] [__tasklet_moved__ if not a tasklet of execution.]] -] -[endsect] - -[section:interruption_requested `bool interruption_requested()`] -[variablelist -[[Effects:] [If `*this` refers to a tasklet, the function returns if the -interruption of the tasklet was already requested.]] -[[Throws:] [__tasklet_moved__ if `*this` is not a tasklet of execution.]] -] -[endsect] - -[section:cancel `void cancel()`] -[variablelist -[[Effects:] [If `*this` refers to a tasklet, request that the tasklet will be -canceled the next time it yields its execution.]] -[[Throws:] [__tasklet_moved__ if `*this` is not a tasklet of execution.]] -] -[endsect] - -[section:is_alive `bool is_alive()`] -[variablelist -[[Effects:] [If `*this` refers to a tasklet, the function returns false if the -tasklet is terminated or not started Otherwise it returns true.]] -[[Throws:] [__tasklet_moved__ if `*this` is not a tasklet of execution.]] -] -[endsect] - -[section:unspec_operator `operator unspecified-bool-type() const`] -[variablelist -[[Returns:] [If `*this` refers to a tasklet, the function returns true. -Otherwise false.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:not_operator `bool operator!() const`] -[variablelist -[[Returns:] [If `*this` refers not to a tasklet, the function returns true. -Otherwise false.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:equals `bool operator==( tasklet const& other) const`] -[variablelist -[[Returns:] [`get_id()==other.get_id()`]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:not_equals `bool operator!=( tasklet const& other) const`] -[variablelist -[[Returns:] [`get_id()!=other.get_id()`]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:swap `void swap( tasklet & other)`] -[variablelist -[[Effects:] [Exchanges the tasklets associated with `*this` and `other`, so -`*this` is associated with the tasklet associated with `other` prior to the -call, and vice-versa.]] -[[Postconditions:] [`this->get_id()` returns the same value as `other.get_id()` -prior to the call. `other.get_id()` returns the same value as `this->get_id()` -prior to the call.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:non_member_swap Non-member function `swap()`] - - #include - - void swap( tasklet & lhs, tasklet & rhs); - -[variablelist -[[Effects:] [[link tasklet.tasklet_management.tasklet.swap `lhs.swap( rhs)`].]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:non_member_make_tasklet Non-member template function `make_tasklet()`] - - #include - - template< typename Fn > - tasklet make_tasklet( Fn fn, std::size_t stack_size); - - template< typename Fn, typename A1, typename A2,... > - tasklet make_tasklet( Fn fn, A1 a1, A2 a2,..., std::size_t stack_size); - -[variablelist -[[Effects:] [Creates a tasklet.]] -] -[endsect] - -[section:id Class `boost::tasklet::id`] - - #include - - class tasklet::id - { - public: - id(); - - bool operator==( id const& y) const; - bool operator!=( id const& y) const; - bool operator<( id const& y) const; - bool operator>( id const& y) const; - bool operator<=( id const& y) const; - bool operator>=( id const& y) const; - - template< typename charT, typename traitsT > - friend std::basic_ostream< charT, traitsT > & - operator<<( std::basic_ostream & os, id const& x); - }; - -[section:constructor `id()`] -[variablelist -[[Effects:] [Constructs a __tasklet_id__ instance that represents -__not_a_tasklet__.]] -[[Throws:] [Nothing]] -] -[endsect] - -[section:is_equal `bool operator==( id const& y) const`] -[variablelist -[[Returns:] [`true` if `*this` and `y` both represent the same tasklet of -execution, or both represent __not_a_tasklet__, `false` otherwise.]] -[[Throws:] [Nothing]] -] -[endsect] - -[section:not_equal `bool operator!=( id const& y) const`] -[variablelist -[[Returns:] [`true` if `*this` and `y` represent different tasklets of -execution, or one represents a tasklet of execution, and the other represent -__not_a_tasklet__, `false` otherwise.]] -[[Throws:] [Nothing]] -] -[endsect] - -[section:less_than `bool operator<( id const& y) const`] -[variablelist -[[Returns:] [`true` if `*this!=y` is `true` and the implementation-defined total -order of __tasklet_id__ values places `*this` before `y`, `false` otherwise.]] -[[Throws:] [Nothing]] -[[Note:] [A __tasklet_id__ instance representing __not_a_tasklet__ will always -compare less than an instance representing a tasklet of execution.]] -] -[endsect] - -[section:greater_than `bool operator>( id const& y) const`] -[variablelist -[[Returns:] [`y<*this`]] -[[Throws:] [Nothing]] -] -[endsect] - -[section:less_than_or_equal `bool operator<=( id const& y) const`] -[variablelist -[[Returns:] [`!(y<*this)`]] -[[Throws:] [Nothing]] -] -[endsect] - -[section:greater_than_or_equal `bool operator>=( id const& y) const`] -[variablelist -[[Returns:] [`!(*this - friend std::basic_ostream< charT, traitsT > & - operator<<( std::basic_ostream & os, id const& x); - -[variablelist -[[Effects:] [Writes a representation of the __tasklet_id__ instance `x` to the -stream `os`, such that the representation of two instances of __tasklet_id__ `a` -and `b` is the same if `a==b`, and different if `a!=b`.]] -[[Returns:] [`os`]] -] -[endsect] - -[endsect] - -[endsect] - -[section:this_tasklet Namespace `this_tasklet`] - -[section:get_id Non-member function `get_id()`] - - #include - - namespace this_tasklet - { - tasklet::id get_id(); - } - -[variablelist -[[Returns:] [An instance of __tasklet_id__ that represents that currently -executing tasklet.]] -[[Throws:] [__tasklet_error__ if an error occurs.]] -] -[endsect] - -[section:interruption_point Non-member function `interruption_point()`] - - #include - - namespace this_tasklet - { - void interruption_point(); - } - -[variablelist -[[Effects:] [Check to see if the current tasklet has been interrupted.]] -[[Throws:] [__tasklet_interrupted__ if __interruption_enabled__ and -__interruption_requested__ both return `true`.]] -] -[endsect] - -[section:interruption_requested Non-member function `interruption_requested()`] - - #include - - namespace this_tasklet - { - bool interruption_requested(); - } - -[variablelist -[[Returns:] [`true` if interruption has been requested for the current tasklet, -`false` otherwise.]] -[[Throws:] [__tasklet_error__ if an error occurs.]] -] -[endsect] - -[section:interruption_enabled Non-member function `interruption_enabled()`] - - #include - - namespace this_tasklet - { - bool interruption_enabled(); - } - -[variablelist -[[Returns:] [`true` if interruption has been enabled for the current tasklet, -`false` otherwise.]] -[[Throws:] [__tasklet_error__ if an error occurs.]] -] -[endsect] - -[section:cancel Non-member function `cancel()`] - - #include - - namespace this_tasklet - { - void cancel(); - } - -[variablelist -[[Effects:] [Cancels the current tasklet.]] -[[Throws:] [__tasklet_error__ if an error occurs.]] -] -[endsect] - -[section:non_member_yield Non-member function `yield()`] - - #include - - namespace this_tasklet - { - void yield(); - } - -[variablelist -[[Effects:] [Gives up the remainder of the current tasklet's time slice, to -allow other tasklets to run.]] -[[Throws:] [__tasklet_error__ if an error occurs.]] -] -[endsect] - -[section:attaskletexit Non-member template function `at_tasklet_exit()`] - - #include - - template - void at_tasklet_exit(Callable func); - -[variablelist -[[Effects:] [A copy of `func` is placed in -tasklet-specific storage. This copy is invoked when the current tasklet -exits (even if the tasklet has been interrupted).]] -[[Postconditions:] [A copy of `func` has been saved for invocation on tasklet -exit.]] -[[Throws:] [`std::bad_alloc` if memory cannot be allocated for the copy of the -function, __tasklet_error__ if any other error occurs within the tasklet -library. Any exception thrown whilst copying `func` into internal storage.]] -[[Note:] [This function is *not* called if the tasklet was terminated -forcefully using platform-specific APIs, or if the tasklet is -terminated due to a call to `exit()`, `abort()` or -`std::terminate()`. In particular, returning from `main()` is -equivalent to call to `exit()`, so will not call any functions -registered with `at_tasklet_exit()`]] -] -[endsect] - -[section:submit Non-member function `submit_tasklet( tasklet)`] - - #include - - namespace this_tasklet - { - void submit_tasklet( tasklet); - } - -[variablelist -[[Effects:] [Submits the passed tasklet to the scheduler running the active -tasklet.]] -[[Throws:] [__tasklet_error__ if an error occurs.]] -] -[endsect] - -[section:disable_interruption Class `disable_interruption`] - - #include - - namespace this_tasklet - { - class disable_interruption - { - public: - disable_interruption(); - ~disable_interruption(); - }; - } - -`boost::this_tasklet::disable_interruption` disables interruption for the -current tasklet on construction, and restores the prior interruption state on -destruction. Instances of `disable_interruption` cannot be copied or moved. - -[section:constructor `disable_interruption()`] -[variablelist -[[Effects:] [Stores the current state of __interruption_enabled__ and disables -interruption for the current tasklet.]] -[[Postconditions:] [__interruption_enabled__ returns `false` for the current -tasklet.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:destructor `~disable_interruption()`] -[variablelist -[[Preconditions:] [Must be called from the same tasklet from which `*this` was -constructed.]] -[[Effects:] [Restores the current state of __interruption_enabled__ for the -current tasklet to that prior to the construction of `*this`.]] -[[Postconditions:] [__interruption_enabled__ for the current tasklet returns the -value stored in the constructor of `*this`.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[endsect] - -[section:restore_interruption Class `restore_interruption`] - - #include - - namespace this_tasklet - { - class restore_interruption - { - public: - explicit restore_interruption(disable_interruption& disabler); - ~restore_interruption(); - }; - } - -On construction of an instance of `boost::this_tasklet::restore_interruption`, -the interruption state for the current tasklet is restored to the interruption -state stored by the constructor of the supplied instance of -__disable_interruption__. When the instance is destroyed, interruption is again -disabled. Instances of `restore_interruption` cannot be copied or moved. - -[section:constructor `explicit restore_interruption(disable_interruption& disabler)`] -[variablelist -[[Preconditions:] [Must be called from the same tasklet from which `disabler` -was constructed.]] -[[Effects:] [Restores the current state of __interruption_enabled__ for the -current tasklet to that prior to the construction of `disabler`.]] -[[Postconditions:] [__interruption_enabled__ for the current tasklet returns the -value stored in the constructor of `disabler`.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:destructor `~restore_interruption()`] -[variablelist -[[Preconditions:] [Must be called from the same tasklet from which `*this` was -constructed.]] -[[Effects:] [Disables interruption for the current tasklet.]] -[[Postconditions:] [__interruption_enabled__ for the current tasklet returns -`false`.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[endsect] - -[endsect] - -[section:scheduler Scheduler] - -[heading Synopsis] - -The template __scheduler__ is responsible for managing and scheduling of -tasklets passed to it. The scheduling algorithm is provided as an template -argument to __scheduler__ (default is __round_robin__). The class implementing -the scheduling algorithm must derive from class __strategy__. It is possible to -migrate tasklets between schedulers. - -[note If the tasklet is not thread-affine (using thread-local-storage) it can be -migrated to a scheduler running in another thread.] - -Usally __scheduler__ will be invoked until all tasklets are scheduled and -finished. - - boost::tasklets::scheduler<> sched; - sched.make_tasklet( some_fn); - - for (;;) - { - while ( sched.run() ); - if ( sched.empty() ) break; - } - - -[section:scheduler Template `template< typename Strategy > scheduler`] - - #include - - template< typename Strategy > - class scheduler - { - public: - scheduler(); - - ~scheduler(); - - bool run(); - - bool empty(); - - std::size_t size(); - - std::size_t ready(); - - void submit_tasklet( tasklet); - - template< typename Fn > - void make_tasklet( Fn fn, std::size_t stack_size); - - template< typename Fn > - void make_tasklet( Fn && fn, std::size_t stack_size); - - template< typename Fn, typename A1, typename A2,..., typename A10 > - void make_tasklet( Fn fn, A0 a0, A1 a1,..., A10 a10, std:size_t stack_size); - - void migrate_tasklet( tasklet f); - - template< typename OtherStrategy > - void migrate_tasklet( tasklet::id const& id, scheduler< OtherStrategy & sched); - }; - - -[section:ctor `scheduler()`] -[variablelist -[[Effects:] [Creates an object of type scheduler< Strategy >.]] -[[Throws:] [Nothing.]] -] -[endsect] - - -[section:dtor `~scheduler()`] -[variablelist -[[Effects:] [Detaches all managed tasklets and destroys the scheduler.]] -[[Throws:] [Nothing.]] -] -[endsect] - - -[section:run `bool run()`] -[variablelist -[[Effects:] [Executes a tasklet from the internal storage and removes terminated -tasklets. The function returns `true` if a tasklet could be executed or a -terminated tasklet could be removed - otherwise `false`.]] -[[Throws:] [__system_error__ if a system call failed.]] -] -[endsect] - -[section:empty `bool empty()`] -[variablelist -[[Effects:] [Returns `true` if the scheduler contains tasklets (maybe runnable -or waiting).]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:size `std::size_t size()`] -[variablelist -[[Effects:] [Returns how many tasklets the scheduler contains (maybe runnable or -waiting).]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:ready `std::size_t ready()`] -[variablelist -[[Effects:] [Returns how many tasklets are ready to run in the scheduler.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:submit_tasklet `void submit_tasklet( tasklet f)`] -[variablelist -[[Effects:] [This function stores the passed tasklet in the scheduler.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:make_tasklet2 `template< typename Fn > void make_tasklet( Fn fn, std::size_t stack_size)`] -[variablelist -[[Effects:] [The functions create a tasklet which gets stored in the internal -structures from scheduler.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:make_tasklet3 `template< typename Fn, typename A1, typename A2,..., typename A10 > void make_tasklet( Fn fn, A0 a0, A1 a1,..., A10 a10, std::size_t stack_size)`] -[variablelist -[[Effects:] [The functions create a tasklet which gets stored in the internal -structures from scheduler.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:migrate_tasklet `void migrate_tasklet( tasklet f)`] -[variablelist -[[Effects:] [The tasklet will be migrated to the scheduler.]] -[[Throws:] [Throws __tasklet_moved__, tasklet_error, scheduler_error.]] -] -[endsect] - -[section:migrate_tasklet_t `template< typename OtherStrategy > void migrate_tasklet( tasklet::id const& id, scheduler< OtherStrategy > & sched)`] -[variablelist -[[Effects:] [The tasklet will be migrated to the scheduler.]] -[[Throws:] [Throws __tasklet_moved__, tasklet_error, scheduler_error.]] -] -[endsect] - -[endsect] - -[endsect] - -[section:strategy Strategy] - -[heading Synopsis] - -The template __scheduler__ accepts the implementation of the scheduling -algorithm as a template argument (currently __round_robin__ is the choosen as -the default). Each class destined to implement a scheduling algorithm must -derive from __strategy__. The member `active_tasklet` holds the current -(running) tasklet and `master_tasklet` executes the scheduling logic. - - -[section:strategy Class `strategy`] - - #include - - class strategy - { - protected: - static __thread tasklet * active_tasklet; - - void attach( tasklet &); - void detach( tasklet &); - - void call( tasklet &); - void yield( tasklet &); - - void enable_interruption( tasklet &); - bool interruption_enabled( tasklet const&); - - bool in_state_not_started( tasklet const&); - bool in_state_ready( tasklet const&); - bool in_state_running( tasklet const&); - bool in_state_wait_for_tasklet( tasklet const&); - bool in_state_wait_for_object( tasklet const&); - bool in_state_terminated( tasklet const&); - - void set_state_ready( tasklet &); - void set_state_running( tasklet &); - void set_state_wait_for_tasklet( tasklet &); - void set_state_wait_for_object( tasklet &); - void set_state_terminated( tasklet &); - - public: - strategy(); - - virtual ~strategy(); - virtual void add( tasklet) = 0; - virtual void join( tasklet::id const&) = 0; - virtual void interrupt( tasklet::id const&) = 0; - virtual void reschedule( tasklet::id const&) = 0; - virtual void cancel( tasklet::id const&) = 0; - virtual void yield( tasklet::id const&) = 0; - virtual void wait_for_object( object::id const&, spin_mutex::scoped_lock &) = 0; - virtual void object_notify_one( object::id const&) = 0; - virtual void object_notify_all( object::id const&) = 0; - virtual tasklet release( tasklet::id const&) = 0; - virtual void migrate( tasklet) = 0; - virtual void detach_all() = 0; - virtual bool run() = 0; - virtual bool empty() = 0; - virtual std::size_t size() = 0; - virtual std::size_t ready() = 0; - }; - - -[section:attach `void attach( tasklet &)`] -[variablelist -[[Effects:] [Protected member function in order to register the scheduler in -internal storage from the tasklet.]] -[[Throws:] [Nothing.]] -] -[endsect] - - -[section:detach `void detach( tasklet &)`] -[variablelist -[[Effects:] [Protected member function in order to unregister the scheduler in -internal storage from the tasklet.]] -[[Throws:] [Nothing.]] -] -[endsect] - - -[section:call `void call( tasklet & f)`] -[variablelist -[[Effects:] [Protected member function calls tasklet `f`.]] -[[Throws:] [Nothing.]] -] -[endsect] - - -[section:yield2 `void yield( tasklet & f)`] -[variablelist -[[Effects:] [Protected member function yield tasklet `f`.]] -[[Throws:] [Nothing.]] -] -[endsect] - - -[section:enable_interruption `void enable_interruption( tasklet &)`] -[variablelist -[[Effects:] [Protected member function enables interruption on the tasklet.]] -[[Throws:] [Nothing.]] -] -[endsect] - - -[section:interruption_enabled `bool interruption_enabled( tasklet const&)`] -[variablelist -[[Effects:] [Protected member function tests if interruption is enabled on the -tasklet.]] -[[Throws:] [Nothing.]] -] -[endsect] - - -[section:in_state_not_started `bool in_state_not_started( tasklet const&)`] -[variablelist -[[Effects:] [Protected member function tests if the tasklet is in the state -`started`.]] -[[Throws:] [Nothing.]] -] -[endsect] - - -[section:in_state_ready `bool in_state_ready( tasklet const&)`] -[variablelist -[[Effects:] [Protected member function tests if the tasklet is in the state -`ready`.]] -[[Throws:] [Nothing.]] -] -[endsect] - - -[section:in_state_running `bool in_state_running( tasklet const&)`] -[variablelist -[[Effects:] [Protected member function tests if the tasklet is in the state -`running`.]] -[[Throws:] [Nothing.]] -] -[endsect] - - -[section:in_state_wait_for_tasklet `bool in_state_wait_for_tasklet( tasklet const&)`] -[variablelist -[[Effects:] [Protected member function tests if the tasklet is in the state -`wait for tasklet`.]] -[[Throws:] [Nothing.]] -] -[endsect] - - -[section:in_state_wait_for_object `bool in_state_wait_for_object( tasklet const&)`] -[variablelist -[[Effects:] [Protected member function tests if the tasklet is in the state -`wait for object`.]] -[[Throws:] [Nothing.]] -] -[endsect] - - -[section:in_state_terminated `bool in_state_terminated( tasklet const&)`] -[variablelist -[[Effects:] [Protected member function tests if the tasklet is in the state -`terminated`.]] -[[Throws:] [Nothing.]] -] -[endsect] - - -[section:set_state_ready `void set_state_ready( tasklet &)`] -[variablelist -[[Effects:] [Protected member function sets the state of the tasklet to -`ready`.]] -[[Throws:] [Nothing.]] -] -[endsect] - - -[section:set_state_running `void set_state_running( tasklet &)`] -[variablelist -[[Effects:] [Protected member function sets the state of the tasklet to -`running`.]] -[[Throws:] [Nothing.]] -] -[endsect] - - -[section:set_state_wait_for_tasklet `void set_state_wait_for_tasklet( tasklet &)`] -[variablelist -[[Effects:] [Protected member function sets the state of the tasklet to -`wait for tasklet`.]] -[[Throws:] [Nothing.]] -] -[endsect] - - -[section:set_state_wait_for_object `void set_state_wait_for_object( tasklet &)`] -[variablelist -[[Effects:] [Protected member function sets the state of the tasklet to -`wait for object`.]] -[[Throws:] [Nothing.]] -] -[endsect] - - -[section:set_state_terminated `void set_state_terminated( tasklet &)`] -[variablelist -[[Effects:] [Protected member function sets the state of the tasklet to -`terminated`.]] -[[Throws:] [Nothing.]] -] -[endsect] - - -[section:ctor `strategy()`] -[variablelist -[[Effects:] [Creates an object of type strategy and initializes the -master_tasklet member.]] -[[Throws:] [Nothing.]] -] -[endsect] - - -[section:add `virtual void add( tasklet) = 0`] -[variablelist -[[Precondition:] [Tasklet was not assigned to another scheduler.]] -[[Effects:] [Add a tasklet to the scheduler.]] -] -[endsect] - - -[section:join `virtual void join( tasklet::id const&) = 0`] -[variablelist -[[Precondition:] [Tasklet belongs to this scheduler.]] -[[Effects:] [The active tasklet will yield until the tasklet identified by the -id has finished its -execution or was interrupted.]] -] -[endsect] - - -[section:interrupt `virtual void interrupt( tasklet::id const&) = 0`] -[variablelist -[[Precondition:] [Tasklet belongs to this scheduler.]] -[[Effects:] [The tasklet identified by the id will be interrupted by its next -execution.]] -] -[endsect] - - -[section:reschedule `virtual void reschedule( tasklet::id const&) = 0`] -[variablelist -[[Precondition:] [Tasklet belongs to this scheduler.]] -[[Effects:] [The scheduling-algorithm will be applied uppon the tasklet -identified by the id again.]] -] -[endsect] - - -[section:cancel `virtual void cancel( tasklet::id const&) = 0`] -[variablelist -[[Precondition:] [Tasklet belongs to this scheduler.]] -[[Effects:] [The tasklet with passed identifier will be stopped, e.g. removed -from the run-queue.]] -] -[endsect] - - -[section:yield1 `virtual void yield( tasklet::id const&) = 0`] -[variablelist -[[Precondition:] [Tasklet is the active tasklet.]] -[[Effects:] [Yield active tasklet and switch back to `master_tasklet` in order -to schedule another tasklet from the internal storage.]] -] -[endsect] - - -[section:wait_for_object `virtual void wait_for_object( object::id const&, spin_mutex::scoped_lock &) = 0`] -[variablelist -[[Effects:] [The active tasklet waits on object until notified.]] -] -[endsect] - - -[section:object_notify_one `virtual void object_notify_one( object::id const&) = 0`] -[variablelist -[[Effects:] [Notify one tasklet waiting on the object. The tasklet gets ready -for scheduling.]] -] -[endsect] - - -[section:object_notify_all `virtual void object_notify_all( object::id const&) = 0`] -[variablelist -[[Effects:] [Notify all tasklets waiting on the object. The tasklets get ready -for scheduling.]] -] -[endsect] - - -[section:release `virtual void release( tasklet::id const&) = 0`] -[variablelist -[[Postcondition:] [The tasklet is not terminated or waits on tasklet or -object.]] -[[Effects:] [Release tasklet from scheduler.]] -] -[endsect] - - -[section:migrate `virtual void migrate( tasklet) = 0`] -[variablelist -[[Postcondition:] [The tasklet is not already managed by scheduler.]] -[[Effects:] [Adds tasklet to scheduler.]] -] -[endsect] - - -[section:detach_all `virtual void detach_all() = 0`] -[variablelist -[[Effects:] [Detaches all managed tasklets from this.]] -] -[endsect] - - -[section:run `virtual bool run() = 0`] -[variablelist -[[Effects:] [Executes a tasklet from the internal storage and removes terminated -tasklets. The function returns `true` if a tasklet could be executed or a -terminated tasklet could be removed - otherwise `false`.]] -[[Throws:] [__system_error__ if a system call failed.]] -] -[endsect] - -[section:empty `virtual bool empty() = 0`] -[variablelist -[[Effects:] [Returns `true` if the scheduler contains tasklets (maybe runnable -or waiting).]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:size `virtual std::size_t size() = 0`] -[variablelist -[[Effects:] [Returns how many tasklets the scheduler contains (maybe runnable or -waiting).]] -[[Throws:] [Nothing.]] -] -[endsect] - -[section:ready `virtual std::size_t ready() = 0`] -[variablelist -[[Effects:] [Returns how many tasklets are ready to run in the scheduler.]] -[[Throws:] [Nothing.]] -] -[endsect] - -[endsect] - -[endsect] - -[endsect] diff --git a/libs/tasklet/doc/todo.qbk b/libs/tasklet/doc/todo.qbk deleted file mode 100644 index 0dcb2b19..00000000 --- a/libs/tasklet/doc/todo.qbk +++ /dev/null @@ -1,13 +0,0 @@ -[/ - Copyright Oliver Kowalke 2009. - Distributed under the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt -] - -[section:todo Todo] - -* optimizate memory ordering in atomic operations -* enhance the scheduler to reflect priorities - -[endsect] diff --git a/libs/tasklet/examples/Jamfile.v2 b/libs/tasklet/examples/Jamfile.v2 deleted file mode 100644 index 63c77ab8..00000000 --- a/libs/tasklet/examples/Jamfile.v2 +++ /dev/null @@ -1,27 +0,0 @@ -# Boost.Tasklet Library Examples Jamfile - -# Copyright Oliver Kowalke 2009. -# Distributed under the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) - -# For more information, see http://www.boost.org/ - -project boost/tasklet/example - : requirements - ../build//boost_tasklet - /boost/fiber//boost_fiber - /boost/thread//boost_thread - true - ; - -exe barrier_mt : barrier_mt.cpp ; -exe cancel : cancel.cpp ; -exe future : future.cpp ; -exe interrupt : interrupt.cpp ; -exe join : join.cpp ; -exe future_mt : future_mt.cpp ; -exe migrate_mt : migrate_mt.cpp ; -exe ping_pong_mt : ping_pong_mt.cpp ; -exe ping_pong : ping_pong.cpp ; -exe simple : simple.cpp ; diff --git a/libs/tasklet/examples/barrier_mt.cpp b/libs/tasklet/examples/barrier_mt.cpp deleted file mode 100644 index f5325c4a..00000000 --- a/libs/tasklet/examples/barrier_mt.cpp +++ /dev/null @@ -1,158 +0,0 @@ -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -int value1 = 0; -int value2 = 0; - -inline -void fn1( boost::tasklets::barrier & b) -{ - std::stringstream tss; - tss << boost::this_thread::get_id(); - std::stringstream fss; - fss << boost::this_tasklet::get_id(); - - fprintf( stderr, "start fn1 tasklet %s in thread %s\n", fss.str().c_str(), tss.str().c_str() ); - - ++value1; - fprintf( stderr, "fn1 tasklet %s in thread %s increment %d\n", fss.str().c_str(), tss.str().c_str(), value1); - - fprintf( stderr, "fn1 tasklet %s in thread %s before wait for barrier\n", fss.str().c_str(), tss.str().c_str()); - b.wait(); - fprintf( stderr, "fn1 tasklet %s in thread %s after wait for barrier\n", fss.str().c_str(), tss.str().c_str()); - - ++value1; - fprintf( stderr, "fn1 tasklet %s in thread %s increment %d\n", fss.str().c_str(), tss.str().c_str(), value1); - - ++value1; - fprintf( stderr, "fn1 tasklet %s in thread %s increment %d\n", fss.str().c_str(), tss.str().c_str(), value1); - - ++value1; - fprintf( stderr, "fn1 tasklet %s in thread %s increment %d\n", fss.str().c_str(), tss.str().c_str(), value1); - - ++value1; - fprintf( stderr, "fn1 tasklet %s in thread %s increment %d\n", fss.str().c_str(), tss.str().c_str(), value1); - - fprintf( stderr, "end fn1 tasklet %s in thread %s\n", fss.str().c_str(), tss.str().c_str() ); -} - -inline -void fn2( boost::tasklets::barrier & b) -{ - std::stringstream tss; - tss << boost::this_thread::get_id(); - std::stringstream fss; - fss << boost::this_tasklet::get_id(); - - fprintf( stderr, "start fn2 tasklet %s in thread %s\n", fss.str().c_str(), tss.str().c_str() ); - - ++value2; - fprintf( stderr, "fn2 tasklet %s in thread %s increment %d\n", fss.str().c_str(), tss.str().c_str(), value2); - - ++value2; - fprintf( stderr, "fn2 tasklet %s in thread %s increment %d\n", fss.str().c_str(), tss.str().c_str(), value2); - - ++value2; - fprintf( stderr, "fn2 tasklet %s in thread %s increment %d\n", fss.str().c_str(), tss.str().c_str(), value2); - - ++value2; - fprintf( stderr, "fn2 tasklet %s in thread %s increment %d\n", fss.str().c_str(), tss.str().c_str(), value2); - - fprintf( stderr, "fn2 tasklet %s in thread %s before wait for barrier\n", fss.str().c_str(), tss.str().c_str()); - b.wait(); - fprintf( stderr, "fn2 tasklet %s in thread %s after wait for barrier\n", fss.str().c_str(), tss.str().c_str()); - - ++value2; - fprintf( stderr, "fn2 tasklet %s in thread %s increment %d\n", fss.str().c_str(), tss.str().c_str(), value2); - - fprintf( stderr, "end fn2 tasklet %s in thread %s\n", fss.str().c_str(), tss.str().c_str() ); -} - -void f( - boost::barrier & tb, - boost::tasklets::barrier & fb) -{ - std::stringstream tss; - tss << boost::this_thread::get_id(); - - fprintf( stderr, "start thread %s\n", tss.str().c_str() ); - - boost::tasklets::scheduler<> sched; - - sched.submit_tasklet( - boost::tasklet( - & fn1, boost::ref( fb), boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - - tb.wait(); - - for (;;) - { - while ( sched.run() ); - if ( sched.empty() ) break; - } - - fprintf( stderr, "end thread %s\n", tss.str().c_str() ); -} - -void g( - boost::barrier & tb, - boost::tasklets::barrier & fb) -{ - std::stringstream tss; - tss << boost::this_thread::get_id(); - - fprintf( stderr, "start thread %s\n", tss.str().c_str() ); - - boost::tasklets::scheduler<> sched; - - sched.submit_tasklet( - boost::tasklet( - & fn2, boost::ref( fb), boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - - tb.wait(); - - for (;;) - { - while ( sched.run() ); - if ( sched.empty() ) break; - } - - fprintf( stderr, "end thread %s\n", tss.str().c_str() ); -} - -int main() -{ - try - { - boost::barrier tb( 2); - boost::tasklets::barrier fb( 2); - - std::cout << "start" << std::endl; - - boost::thread th1( boost::bind( & f, boost::ref( tb), boost::ref( fb) ) ); - boost::thread th2( boost::bind( & g, boost::ref( tb), boost::ref( fb) ) ); - - th1.join(); - th2.join(); - - std::cout << "finish" << std::endl; - - return EXIT_SUCCESS; - } - catch ( boost::tasklets::scheduler_error const& e) - { std::cerr << "scheduler_error: " << e.what() << std::endl; } - catch ( std::exception const& e) - { std::cerr << "exception: " << e.what() << std::endl; } - catch (...) - { std::cerr << "unhandled exception" << std::endl; } - return EXIT_FAILURE; -} diff --git a/libs/tasklet/examples/cancel.cpp b/libs/tasklet/examples/cancel.cpp deleted file mode 100644 index f5c00037..00000000 --- a/libs/tasklet/examples/cancel.cpp +++ /dev/null @@ -1,69 +0,0 @@ -#include -#include -#include - -#include - -#include - -int value1 = 0; -int value2 = 0; - -void fn_1() -{ - for ( int i = 0; i < 5; ++i) - { - ++value1; - std::cout << "fn_1() increment value1 " << value1 << std::endl; - boost::this_tasklet::yield(); - } -} - -void fn_2( boost::tasklet f) -{ - for ( int i = 0; i < 5; ++i) - { - ++value2; - std::cout << "fn_2() increment value2 " << value2 << std::endl; - if ( i == 1) - { - std::cout << "fn_2() cancel tasklet " << f.get_id() << std::endl; - f.cancel(); - } - boost::this_tasklet::yield(); - } -} - -int main() -{ - try - { - boost::tasklets::scheduler<> sched; - - boost::tasklet f( fn_1, boost::tasklet::default_stacksize, boost::protected_stack_allocator()); - sched.submit_tasklet( f); - sched.submit_tasklet( - boost::tasklet( - fn_2, f, boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - - std::cout << "start" << std::endl; - std::cout << "tasklet to be canceled " << f.get_id() << std::endl; - - for (;;) - { - while ( sched.run() ); - if ( sched.empty() ) break; - } - - std::cout << "finish: value1 == " << value1 << ", value2 == " << value2 << std::endl; - - return EXIT_SUCCESS; - } - catch ( boost::tasklets::scheduler_error const& e) - { std::cerr << "scheduler_error: " << e.what() << std::endl; } - catch ( std::exception const& e) - { std::cerr << "exception: " << e.what() << std::endl; } - catch (...) - { std::cerr << "unhandled exception" << std::endl; } - return EXIT_FAILURE; -} diff --git a/libs/tasklet/examples/future.cpp b/libs/tasklet/examples/future.cpp deleted file mode 100644 index fec7e657..00000000 --- a/libs/tasklet/examples/future.cpp +++ /dev/null @@ -1,44 +0,0 @@ -#include -#include -#include - -#include -#include -#include - -#include -#include - -inline -std::string helloworld_fn() -{ return "Hello World"; } - -int main() -{ - try - { - boost::tasklets::scheduler<> sched; - - boost::tasklets::packaged_task< std::string > pt( helloworld_fn); - boost::tasklets::unique_future< std::string > fu = pt.get_future(); - boost::tasklet t( boost::move( pt), boost::tasklet::default_stacksize, boost::protected_stack_allocator()); - sched.submit_tasklet( t); - - for (;;) - { - while ( sched.run() ); - if ( sched.empty() ) break; - } - - std::cout << fu.get() << std::endl; - - return EXIT_SUCCESS; - } - catch ( boost::tasklets::scheduler_error const& e) - { std::cerr << "scheduler_error: " << e.what() << std::endl; } - catch ( std::exception const& e) - { std::cerr << "exception: " << e.what() << std::endl; } - catch (...) - { std::cerr << "unhandled exception" << std::endl; } - return EXIT_FAILURE; -} diff --git a/libs/tasklet/examples/future_mt.cpp b/libs/tasklet/examples/future_mt.cpp deleted file mode 100644 index c1f70fde..00000000 --- a/libs/tasklet/examples/future_mt.cpp +++ /dev/null @@ -1,176 +0,0 @@ -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - -class callable -{ -private: - struct impl - { - virtual ~impl() {} - - virtual void exec() = 0; - }; - - template< typename T > - class timpl : public impl - { - private: - boost::tasklets::packaged_task< T > pt_; - - public: - timpl( boost::tasklets::packaged_task< T > & pt) : - pt_( boost::move( pt) ) - {} - - void exec() - { pt_(); } - }; - - boost::shared_ptr< impl > impl_; - -public: - template< typename T > - callable( boost::tasklets::packaged_task< T > & pt) : - impl_( new timpl< T >( pt) ) - {} - - void operator()() - { impl_->exec(); } -}; - -int value1 = 0; -int value2 = 0; - -inline -std::string helloworld_fn() -{ - std::stringstream ss; - ss << boost::this_thread::get_id(); - - fprintf( stderr, "thread %s returns 'Hello World'\n", ss.str().c_str() ); - return "Hello World"; -} - -void increment_fn1() -{ - std::stringstream ss; - ss << boost::this_thread::get_id(); - - for ( int i = 0; i < 5; ++i) - { - ++value1; - fprintf( stderr, "thread %s incremented value1 %d\n", ss.str().c_str(), value1); - boost::this_tasklet::yield(); - } -} - -void increment_fn2() -{ - std::stringstream ss; - ss << boost::this_thread::get_id(); - - for ( int i = 0; i < 3; ++i) - { - ++value2; - fprintf( stderr, "thread %s incremented value2 %d\n", ss.str().c_str(), value2); - } - - ++value2; - fprintf( stderr, "thread %s incremented value2 %d\n", ss.str().c_str(), value2); - boost::this_tasklet::yield(); - ++value2; - fprintf( stderr, "thread %s incremented value2 %d\n", ss.str().c_str(), value2); - boost::this_tasklet::yield(); -} - -void waiting_fn( boost::tasklets::shared_future< std::string > fu) -{ - std::stringstream ss; - ss << boost::this_thread::get_id(); - - fprintf( stderr, "thread %s waits for future\n", ss.str().c_str() ); - std::string result = fu.get(); - fprintf( stderr, "thread %s got string %s from future\n", ss.str().c_str(), result.c_str() ); -} - -void thread_fn1( boost::tasklets::shared_future< std::string > fu) -{ - std::stringstream ss; - ss << boost::this_thread::get_id(); - - fprintf( stderr, "thread %s started\n", ss.str().c_str() ); - - boost::tasklets::scheduler<> sched; - - sched.submit_tasklet( - boost::tasklet( - & increment_fn1, boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - sched.submit_tasklet( - boost::tasklet( - & waiting_fn, fu, boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - - for (;;) - { - while ( sched.run() ); - if ( sched.empty() ) break; - } - fprintf( stderr, "thread %s finished\n", ss.str().c_str() ); -} - -void thread_fn2( callable ca) -{ - std::stringstream ss; - ss << boost::this_thread::get_id(); - - fprintf( stderr, "thread %s started\n", ss.str().c_str() ); - - boost::tasklets::scheduler<> sched; - - sched.submit_tasklet( - boost::tasklet( - & increment_fn2, boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - sched.submit_tasklet( - boost::tasklet( - ca, boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - - for (;;) - { - while ( sched.run() ); - if ( sched.empty() ) break; - } - fprintf( stderr, "thread %s finished\n", ss.str().c_str() ); -} - -int main() -{ - try - { - boost::tasklets::packaged_task< std::string > pt( helloworld_fn); - boost::tasklets::unique_future< std::string > fu = pt.get_future(); - - boost::thread th1( boost::bind( & thread_fn1, boost::tasklets::shared_future< std::string >( fu) ) ); - boost::thread th2( boost::bind( & thread_fn2, callable( pt) ) ); - - th1.join(); - th2.join(); - - return EXIT_SUCCESS; - } - catch ( boost::tasklets::scheduler_error const& e) - { std::cerr << "scheduler_error: " << e.what() << std::endl; } - catch ( std::exception const& e) - { std::cerr << "exception: " << e.what() << std::endl; } - catch (...) - { std::cerr << "unhandled exception" << std::endl; } - return EXIT_FAILURE; -} diff --git a/libs/tasklet/examples/interrupt.cpp b/libs/tasklet/examples/interrupt.cpp deleted file mode 100644 index cef5ea6c..00000000 --- a/libs/tasklet/examples/interrupt.cpp +++ /dev/null @@ -1,124 +0,0 @@ -#include -#include -#include - -#include - -#include - -int value1 = 0; -int value2 = 0; -int value3 = 0; - -void fn_1() -{ - for ( int i = 0; i < 10; ++i) - { - ++value1; - std::cout << "fn_1() increment value1 " << value1 << std::endl; - boost::this_tasklet::interruption_point(); - boost::this_tasklet::yield(); - } -} - -void fn_2() -{ - boost::this_tasklet::disable_interruption disabled; - for ( int i = 0; i < 10; ++i) - { - ++value2; - std::cout << "fn_2() increment value2 " << value2 << std::endl; - boost::this_tasklet::interruption_point(); - boost::this_tasklet::yield(); - } -} - -void fn_3() -{ - boost::this_tasklet::disable_interruption disabled; - for ( int i = 0; i < 10; ++i) - { - ++value3; - std::cout << "fn_3() increment value3 " << value3 << std::endl; - boost::this_tasklet::restore_interruption restored( disabled); - boost::this_tasklet::interruption_point(); - boost::this_tasklet::yield(); - } -} - -void fn_4( boost::tasklet f) -{ - for ( int i = 0; i < 10; ++i) - { - if ( i == 1) - { - std::cout << "fn_4() interrupt tasklet " << f.get_id() << std::endl; - f.interrupt(); - break; - } - boost::this_tasklet::yield(); - } -} - -int main() -{ - try - { - boost::tasklets::scheduler<> sched; - - boost::tasklet f1( fn_1, boost::tasklet::default_stacksize, boost::protected_stack_allocator()); - sched.submit_tasklet( f1); - sched.submit_tasklet( - boost::tasklet( - fn_4, f1, boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - - std::cout << "start: interrupt fn_1()" << std::endl; - - for (;;) - { - while ( sched.run() ); - if ( sched.empty() ) break; - } - - std::cout << "finish: value1 == " << value1 << std::endl; - - boost::tasklet f2( fn_2, boost::tasklet::default_stacksize, boost::protected_stack_allocator()); - sched.submit_tasklet( f2); - sched.submit_tasklet( - boost::tasklet( - fn_4, f2, boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - std::cout << "start: interrupt fn_2()" << std::endl; - - for (;;) - { - while ( sched.run() ); - if ( sched.empty() ) break; - } - - std::cout << "finish: value2 == " << value2 << std::endl; - - boost::tasklet f3( fn_3, boost::tasklet::default_stacksize, boost::protected_stack_allocator()); - sched.submit_tasklet( f3); - sched.submit_tasklet( - boost::tasklet( - fn_4, f3, boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - std::cout << "start: interrupt fn_3()" << std::endl; - - for (;;) - { - while ( sched.run() ); - if ( sched.empty() ) break; - } - - std::cout << "finish: value3 == " << value3 << std::endl; - - return EXIT_SUCCESS; - } - catch ( boost::tasklets::scheduler_error const& e) - { std::cerr << "scheduler_error: " << e.what() << std::endl; } - catch ( std::exception const& e) - { std::cerr << "exception: " << e.what() << std::endl; } - catch (...) - { std::cerr << "unhandled exception" << std::endl; } - return EXIT_FAILURE; -} diff --git a/libs/tasklet/examples/join.cpp b/libs/tasklet/examples/join.cpp deleted file mode 100644 index 64ccb5dd..00000000 --- a/libs/tasklet/examples/join.cpp +++ /dev/null @@ -1,70 +0,0 @@ -#include -#include -#include - -#include - -#include - -int value1 = 0; -int value2 = 0; - -void fn_1() -{ - for ( int i = 0; i < 5; ++i) - { - ++value1; - std::cout << "fn_1() increment value1 " << value1 << std::endl; - boost::this_tasklet::yield(); - } -} - -void fn_2( boost::tasklet f) -{ - for ( int i = 0; i < 5; ++i) - { - ++value2; - std::cout << "fn_2() increment value2 " << value2 << std::endl; - if ( i == 1) - { - std::cout << "fn_2() join tasklet " << f.get_id() << std::endl; - f.join(); - std::cout << "fn_2() tasklet " << f.get_id() << " joined" << std::endl; - } - boost::this_tasklet::yield(); - } -} - -int main() -{ - try - { - boost::tasklets::scheduler<> sched; - - boost::tasklet f( fn_1, boost::tasklet::default_stacksize, boost::protected_stack_allocator()); - sched.submit_tasklet( f); - sched.submit_tasklet( - boost::tasklet( - fn_2, f, boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - - std::cout << "start" << std::endl; - std::cout << "tasklet to be joined " << f.get_id() << std::endl; - - for (;;) - { - while ( sched.run() ); - if ( sched.empty() ) break; - } - - std::cout << "finish: value1 == " << value1 << ", value2 == " << value2 << std::endl; - - return EXIT_SUCCESS; - } - catch ( boost::tasklets::scheduler_error const& e) - { std::cerr << "scheduler_error: " << e.what() << std::endl; } - catch ( std::exception const& e) - { std::cerr << "exception: " << e.what() << std::endl; } - catch (...) - { std::cerr << "unhandled exception" << std::endl; } - return EXIT_FAILURE; -} diff --git a/libs/tasklet/examples/migrate_mt.cpp b/libs/tasklet/examples/migrate_mt.cpp deleted file mode 100644 index 8fff637c..00000000 --- a/libs/tasklet/examples/migrate_mt.cpp +++ /dev/null @@ -1,124 +0,0 @@ -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -void g( std::string const& str, int n) -{ - for ( int i = 0; i < n; ++i) - { - std::ostringstream os1; - std::ostringstream os2; - os1 << boost::this_thread::get_id(); - os2 << boost::this_tasklet::get_id(); - fprintf( stderr, "(thread: %s, tasklet: %s) %d: %s\n", os1.str().c_str(), os2.str().c_str(), i, str.c_str() ); - boost::this_tasklet::yield(); - } -} - -void fn1( - boost::tasklet & t, - boost::barrier & b, - boost::tasklets::scheduler<> & sched2, - std::string const& msg, int n) -{ - std::ostringstream os; - os << boost::this_thread::get_id(); - fprintf( stderr, "start (thread1: %s)\n", os.str().c_str() ); - - boost::tasklets::scheduler<> sched1; - sched1.submit_tasklet( - boost::tasklet( - & g, msg, n, boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - - for ( int i = 0; i < 2; ++i) - sched1.run(); - - b.wait(); - - sched2.migrate_tasklet( t); - - b.wait(); - - std::ostringstream id_os; - id_os << t.get_id(); - - fprintf( stderr, "thread1: tasklet %s migrated\n", id_os.str().c_str() ); - fprintf( stderr, "thread1: scheduler runs %d tasklets\n", static_cast< int >( sched1.size() ) ); - - for (;;) - { - while ( sched1.run() ); - if ( sched1.empty() ) break; - } - - fprintf( stderr, "finish (thread1: %s)\n", os.str().c_str() ); -} - -void fn2( - boost::tasklet & f, - boost::barrier & b, - boost::tasklets::scheduler<> & sched) -{ - std::ostringstream os; - os << boost::this_thread::get_id(); - fprintf( stderr, "start (thread2: %s)\n", os.str().c_str() ); - - sched.submit_tasklet( f); - - sched.run(); - sched.run(); - - b.wait(); - b.wait(); - - fprintf( stderr, "thread2: scheduler runs %d tasklets\n", static_cast< int >( sched.size() ) ); - - fprintf( stderr, "finish (thread2: %s)\n", os.str().c_str() ); -} - -int main() -{ - try - { - boost::tasklets::scheduler<> sched; - boost::barrier b( 2); - - boost::tasklet f( & g, "xyz", 4, boost::tasklet::default_stacksize, boost::protected_stack_allocator()); - - std::cout << "start" << std::endl; - - boost::thread th1( - fn1, - f, - boost::ref( b), - boost::ref( sched), - "abc", 5); - boost::thread th2( - fn2, - f, - boost::ref( b), - boost::ref( sched) ); - - th1.join(); - th2.join(); - - std::cout << "finish" << std::endl; - - return EXIT_SUCCESS; - } - catch ( boost::tasklets::scheduler_error const& e) - { std::cerr << "scheduler_error: " << e.what() << std::endl; } - catch ( std::exception const& e) - { std::cerr << "exception: " << e.what() << std::endl; } - catch (...) - { std::cerr << "unhandled exception" << std::endl; } - return EXIT_FAILURE; -} diff --git a/libs/tasklet/examples/ping_pong.cpp b/libs/tasklet/examples/ping_pong.cpp deleted file mode 100644 index 4a98b23c..00000000 --- a/libs/tasklet/examples/ping_pong.cpp +++ /dev/null @@ -1,107 +0,0 @@ -#include -#include -#include - -#include -#include -#include -#include - -#include - -typedef boost::tasklets::unbounded_channel< std::string > fifo_t; -typedef boost::intrusive_ptr< fifo_t > fifo_ptr; - -inline -void ping( - fifo_t & recv_buf, - fifo_t & send_buf) -{ - boost::optional< std::string > value; - - send_buf.put("ping"); - BOOST_ASSERT( recv_buf.take( value) ); - std::cout << * value << std::endl; - value.reset(); - - send_buf.put("ping"); - BOOST_ASSERT( recv_buf.take( value) ); - std::cout << * value << std::endl; - value.reset(); - - send_buf.put("ping"); - BOOST_ASSERT( recv_buf.take( value) ); - std::cout << * value << std::endl; - value.reset(); - - send_buf.deactivate(); -} - -inline -void pong( - fifo_t & recv_buf, - fifo_t & send_buf) -{ - boost::optional< std::string > value; - - BOOST_ASSERT( recv_buf.take( value) ); - std::cout << * value << std::endl; - value.reset(); - send_buf.put("pong"); - - BOOST_ASSERT( recv_buf.take( value) ); - std::cout << * value << std::endl; - value.reset(); - send_buf.put("pong"); - - BOOST_ASSERT( recv_buf.take( value) ); - std::cout << * value << std::endl; - value.reset(); - send_buf.put("pong"); - - send_buf.deactivate(); -} - -void f( boost::tasklets::scheduler<> & sched) -{ - fifo_t buf1; - fifo_t buf2; - - sched.submit_tasklet( - boost::tasklet( - & ping, boost::ref( buf1), boost::ref( buf2), boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - sched.submit_tasklet( - boost::tasklet( - & pong, boost::ref( buf2), boost::ref( buf1), boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); -} - -int main() -{ - try - { - boost::tasklets::scheduler<> sched; - - sched.submit_tasklet( - boost::tasklet( - & f, boost::ref( sched), boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - - std::cout << "start" << std::endl; - - for (;;) - { - while ( sched.run() ); - if ( sched.empty() ) break; - } - - std::cout << "finish" << std::endl; - - return EXIT_SUCCESS; - } - catch ( boost::tasklets::scheduler_error const& e) - { std::cerr << "scheduler_error: " << e.what() << std::endl; } - catch ( std::exception const& e) - { std::cerr << "exception: " << e.what() << std::endl; } - catch (...) - { std::cerr << "unhandled exception" << std::endl; } - return EXIT_FAILURE; -} diff --git a/libs/tasklet/examples/ping_pong_mt.cpp b/libs/tasklet/examples/ping_pong_mt.cpp deleted file mode 100644 index 965c48b4..00000000 --- a/libs/tasklet/examples/ping_pong_mt.cpp +++ /dev/null @@ -1,160 +0,0 @@ -#include -#include -#include -#include -#include - - -#include -#include -#include -#include -#include - -#include - -typedef boost::tasklets::unbounded_channel< std::string > fifo_t; - -inline -void ping( - fifo_t & recv_buf, - fifo_t & send_buf) -{ - std::stringstream tss; - tss << boost::this_thread::get_id(); - std::stringstream fss; - fss << boost::this_tasklet::get_id(); - - fprintf( stderr, "start ping tasklet %s in thread %s\n", fss.str().c_str(), tss.str().c_str() ); - - boost::optional< std::string > value; - - send_buf.put("ping"); - BOOST_ASSERT( recv_buf.take( value) ); - fprintf( stderr, "ping tasklet %s in thread %s recevied %s\n", fss.str().c_str(), tss.str().c_str(), value->c_str()); - value.reset(); - - send_buf.put("ping"); - BOOST_ASSERT( recv_buf.take( value) ); - fprintf( stderr, "ping tasklet %s in thread %s recevied %s\n", fss.str().c_str(), tss.str().c_str(), value->c_str()); - value.reset(); - - send_buf.put("ping"); - BOOST_ASSERT( recv_buf.take( value) ); - fprintf( stderr, "ping tasklet %s in thread %s recevied %s\n", fss.str().c_str(), tss.str().c_str(), value->c_str()); - value.reset(); - - send_buf.deactivate(); - - fprintf( stderr, "end ping tasklet %s in thread %s\n", fss.str().c_str(), tss.str().c_str() ); -} - -inline -void pong( - fifo_t & recv_buf, - fifo_t & send_buf) -{ - std::stringstream tss; - tss << boost::this_thread::get_id(); - std::stringstream fss; - fss << boost::this_tasklet::get_id(); - - fprintf( stderr, "start pong tasklet %s in thread %s\n", fss.str().c_str(), tss.str().c_str() ); - - boost::optional< std::string > value; - - BOOST_ASSERT( recv_buf.take( value) ); - fprintf( stderr, "pong tasklet %s in thread %s recevied %s\n", fss.str().c_str(), tss.str().c_str(), value->c_str()); - value.reset(); - send_buf.put("pong"); - - BOOST_ASSERT( recv_buf.take( value) ); - fprintf( stderr, "pong tasklet %s in thread %s recevied %s\n", fss.str().c_str(), tss.str().c_str(), value->c_str()); - value.reset(); - send_buf.put("pong"); - - BOOST_ASSERT( recv_buf.take( value) ); - fprintf( stderr, "pong tasklet %s in thread %s recevied %s\n", fss.str().c_str(), tss.str().c_str(), value->c_str()); - value.reset(); - send_buf.put("pong"); - - send_buf.deactivate(); - - fprintf( stderr, "end pong tasklet %s in thread %s\n", fss.str().c_str(), tss.str().c_str() ); -} - -void f( - fifo_t & recv_buf, - fifo_t & send_buf) -{ - std::stringstream tss; - tss << boost::this_thread::get_id(); - - fprintf( stderr, "start thread %s\n", tss.str().c_str() ); - - boost::tasklets::scheduler<> sched; - - sched.submit_tasklet( - boost::tasklet( - & ping, boost::ref( recv_buf), boost::ref( send_buf), boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - - for (;;) - { - while ( sched.run() ); - if ( sched.empty() ) break; - } - - fprintf( stderr, "end thread %s\n", tss.str().c_str() ); -} - -void g( - fifo_t & recv_buf, - fifo_t & send_buf) -{ - std::stringstream tss; - tss << boost::this_thread::get_id(); - - fprintf( stderr, "start thread %s\n", tss.str().c_str() ); - - boost::tasklets::scheduler<> sched; - - sched.submit_tasklet( - boost::tasklet( - & pong, boost::ref( recv_buf), boost::ref( send_buf), boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - - for (;;) - { - while ( sched.run() ); - if ( sched.empty() ) break; - } - - fprintf( stderr, "end thread %s\n", tss.str().c_str() ); -} - -int main() -{ - try - { - fifo_t buf1; - fifo_t buf2; - - std::cout << "start" << std::endl; - - boost::thread th1( boost::bind( & f, boost::ref( buf1), boost::ref( buf2) ) ); - boost::thread th2( boost::bind( & g, boost::ref( buf2), boost::ref( buf1) ) ); - - th1.join(); - th2.join(); - - std::cout << "finish" << std::endl; - - return EXIT_SUCCESS; - } - catch ( boost::tasklets::scheduler_error const& e) - { std::cerr << "scheduler_error: " << e.what() << std::endl; } - catch ( std::exception const& e) - { std::cerr << "exception: " << e.what() << std::endl; } - catch (...) - { std::cerr << "unhandled exception" << std::endl; } - return EXIT_FAILURE; -} diff --git a/libs/tasklet/examples/simple.cpp b/libs/tasklet/examples/simple.cpp deleted file mode 100644 index 02ad1c83..00000000 --- a/libs/tasklet/examples/simple.cpp +++ /dev/null @@ -1,50 +0,0 @@ -#include -#include -#include - -#include - -#include - -inline -void fn( std::string const& str, int n) -{ - for ( int i = 0; i < n; ++i) - { - std::cout << i << ": " << str << std::endl; - boost::this_tasklet::yield(); - } -} - -int main() -{ - try - { - boost::tasklets::scheduler<> sched; - - boost::tasklet f( fn, "abc", 5, boost::tasklet::default_stacksize, boost::protected_stack_allocator() ); - sched.submit_tasklet( boost::move( f) ); - sched.submit_tasklet( - boost::tasklet( - & fn, "xyz", 7, boost::tasklet::default_stacksize, boost::protected_stack_allocator() ) ); - - std::cout << "start" << std::endl; - - for (;;) - { - while ( sched.run() ); - if ( sched.empty() ) break; - } - - std::cout << "finish" << std::endl; - - return EXIT_SUCCESS; - } - catch ( boost::tasklets::scheduler_error const& e) - { std::cerr << "scheduler_error: " << e.what() << std::endl; } - catch ( std::exception const& e) - { std::cerr << "exception: " << e.what() << std::endl; } - catch (...) - { std::cerr << "unhandled exception" << std::endl; } - return EXIT_FAILURE; -} diff --git a/libs/tasklet/performance/Jamfile.v2 b/libs/tasklet/performance/Jamfile.v2 deleted file mode 100644 index 7a5496b8..00000000 --- a/libs/tasklet/performance/Jamfile.v2 +++ /dev/null @@ -1,18 +0,0 @@ -# Boost.Tasklet Library Examples Jamfile - -# Copyright Oliver Kowalke 2009. -# Distributed under the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) - -# For more information, see http://www.boost.org/ - -project boost/tasklet/example - : requirements - /boost/program_options//boost_program_options - ../build//boost_tasklet - static - multi - ; - -exe performance : performance.cpp ; diff --git a/libs/tasklet/performance/bind_processor.hpp b/libs/tasklet/performance/bind_processor.hpp deleted file mode 100644 index 2ec3e310..00000000 --- a/libs/tasklet/performance/bind_processor.hpp +++ /dev/null @@ -1,28 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef _BIND_PROCESSOR_H -#define _BIND_PROCESSOR_H - -# if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) -# include "bind_processor_windows.hpp" -# elif defined(linux) || defined(__linux) || defined(__linux__) -# include "bind_processor_linux.hpp" -# elif defined(__IBMCPP__) || defined(_AIX) -# include "bind_processor_aix.hpp" -# elif defined(__hpux) -# include "bind_processor_hpux.hpp" -# elif defined(sun) || defined(__sun) -# include "bind_processor_solaris.hpp" -# elif defined(__FreeBSD__) -#include -# if (__FreeBSD_version ">= 701000") -# include "bind_processor_freebsd.hpp" -# endif -# error "platform not supported" -# endif - -#endif // _BIND_PROCESSOR_H diff --git a/libs/tasklet/performance/bind_processor_aix.hpp b/libs/tasklet/performance/bind_processor_aix.hpp deleted file mode 100644 index 9672b6e0..00000000 --- a/libs/tasklet/performance/bind_processor_aix.hpp +++ /dev/null @@ -1,37 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef _BIND_PROCESSOR_AIX_H -#define _BIND_PROCESSOR_AIX_H - -extern "C" -{ -#include -#include -} - -#include -#include -#include - -#include - -inline -void bind_to_processor( unsigned int n) -{ - BOOST_ASSERT( n >= 0); - BOOST_ASSERT( n < boost::thread::hardware_concurrency() ); - - if ( ::bindprocessor( BINDTHREAD, ::thread_self(), static_cast< cpu_t >( n) ) == -1) - throw boost::system::system_error( - boost::system::error_code( - errno, - boost::system::system_category) ); -} - -#include - -#endif // _BIND_PROCESSOR_AIX_H diff --git a/libs/tasklet/performance/bind_processor_freebsd.hpp b/libs/tasklet/performance/bind_processor_freebsd.hpp deleted file mode 100644 index 11d15b9f..00000000 --- a/libs/tasklet/performance/bind_processor_freebsd.hpp +++ /dev/null @@ -1,41 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef _BIND_PROCESSOR_FREEBSD_H -#define _BIND_PROCESSOR_FREEBSD_H - -extern "C" -{ -#include -#include -} - -#include -#include -#include - -#include - -inline -void bind_to_processor( unsigned int n) -{ - BOOST_ASSERT( n >= 0); - BOOST_ASSERT( n < boost::thread::hardware_concurrency() ); - - cpuset_t cpuset; - CPU_ZERO( & cpuset); - CPU_SET( n, & cpuset); - - if ( ::cpuset_setaffinity( CPU_LEVEL_WHICH, CPU_WHICH_TID, -1, sizeof( cpuset), & cpuset) == -1) - throw boost::system::system_error( - boost::system::error_code( - errno, - boost::system::system_category) ); -} - -#include - -#endif // _BIND_PROCESSOR_FREEBSD_H diff --git a/libs/tasklet/performance/bind_processor_hpux.hpp b/libs/tasklet/performance/bind_processor_hpux.hpp deleted file mode 100644 index ea4389df..00000000 --- a/libs/tasklet/performance/bind_processor_hpux.hpp +++ /dev/null @@ -1,43 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef _BIND_PROCESSOR_HPUX_H -#define _BIND_PROCESSOR_HPUX_H - -extern "C" -{ -#include -} - -#include -#include -#include - -#include - -inline -void bind_to_processor( unsigned int n) -{ - BOOST_ASSERT( n >= 0); - BOOST_ASSERT( n < boost::thread::hardware_concurrency() ); - - ::pthread_spu_t spu; - int errno_( - ::pthread_processor_bind_np( - PTHREAD_BIND_FORCED_NP, - & spu, - static_cast< pthread_spu_t >( n), - PTHREAD_SELFTID_NP) ); - if ( errno_ != 0) - throw boost::system::system_error( - boost::system::error_code( - errno_, - boost::system::system_category) ); -} - -#include - -#endif // _BIND_PROCESSOR_HPUX_H diff --git a/libs/tasklet/performance/bind_processor_linux.hpp b/libs/tasklet/performance/bind_processor_linux.hpp deleted file mode 100644 index f5a3baba..00000000 --- a/libs/tasklet/performance/bind_processor_linux.hpp +++ /dev/null @@ -1,43 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef _BIND_PRCESSOR_LINUX_H -#define _BIND_PRCESSOR_LINUX_H - -extern "C" -{ -#include -#include -} - -#include -#include -#include - -#include - -inline -void bind_to_processor( unsigned int n) -{ - BOOST_ASSERT( n >= 0); - BOOST_ASSERT( n < CPU_SETSIZE); - BOOST_ASSERT( n < boost::thread::hardware_concurrency() ); - - cpu_set_t cpuset; - CPU_ZERO( & cpuset); - CPU_SET( n, & cpuset); - - int errno_( ::pthread_setaffinity_np( ::pthread_self(), sizeof( cpuset), & cpuset) ); - if ( errno_ != 0) - throw boost::system::system_error( - boost::system::error_code( - errno_, - boost::system::system_category) ); -} - -#include - -#endif // _BIND_PRCESSOR_LINUX_H diff --git a/libs/tasklet/performance/bind_processor_solaris.hpp b/libs/tasklet/performance/bind_processor_solaris.hpp deleted file mode 100644 index 25c88b09..00000000 --- a/libs/tasklet/performance/bind_processor_solaris.hpp +++ /dev/null @@ -1,38 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef _BIND_PROCESSOR_SOLARIS_H -#define _BIND_PROCESSOR_SOLARIS_H - -extern "C" -{ -#include -#include -#include -} - -#include -#include -#include - -#include - -inline -void bind_to_processor( unsigned int n) -{ - BOOST_ASSERT( n >= 0); - BOOST_ASSERT( n < boost::thread::hardware_concurrency() ); - - if ( ::processor_bind( P_LWPID, P_MYID, static_cast< processorid_t >( n), 0) == -1) - throw boost::system::system_error( - boost::system::error_code( - errno, - boost::system::system_category) ); -} - -#include - -#endif // _BIND_PROCESSOR_SOLARIS_H diff --git a/libs/tasklet/performance/bind_processor_windows.hpp b/libs/tasklet/performance/bind_processor_windows.hpp deleted file mode 100644 index d50a31ac..00000000 --- a/libs/tasklet/performance/bind_processor_windows.hpp +++ /dev/null @@ -1,36 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef _BIND_PROCESSOR_WINDOWS_H -#define _BIND_PROCESSOR_WINDOWS_H - -extern "C" -{ -#include -} - -#include -#include -#include - -#include - -inline -void bind_to_processor( unsigned int n) -{ - BOOST_ASSERT( n >= 0); - BOOST_ASSERT( n < boost::thread::hardware_concurrency() ); - - if ( ::SetThreadAffinityMask( ::GetCurrentThread(), ( DWORD_PTR)1 << n) == 0) - throw boost::system::system_error( - boost::system::error_code( - ::GetLastError(), - boost::system::system_category) ); -} - -#include - -#endif // _BIND_PROCESSOR_WINDOWS_H diff --git a/libs/tasklet/performance/performance.cpp b/libs/tasklet/performance/performance.cpp deleted file mode 100644 index f2bec7d8..00000000 --- a/libs/tasklet/performance/performance.cpp +++ /dev/null @@ -1,125 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include -#include -#include - -#include -#include - -#include "bind_processor.hpp" -#include "performance.hpp" - -namespace po = boost::program_options; -namespace pt = boost::posix_time; - -volatile int value = 0; - -void fn( int i) -{ value = i; } - -void test_creation( unsigned int iterations) -{ - int value( 3); - long total( 0); - cycle_t overhead( get_overhead() ); - std::cout << "overhead for rdtsc == " << overhead << " cycles" << std::endl; - - boost::tasklets::scheduler<> sched; - - // cache warm-up - sched.make_tasklet( fn, value, boost::tasklet::default_stacksize); - - for ( unsigned int i = 0; i < iterations; ++i) - { - cycle_t start( get_cycles() ); - sched.make_tasklet( fn, value, boost::tasklet::default_stacksize); - cycle_t diff( get_cycles() - start); - diff -= overhead; - BOOST_ASSERT( diff >= 0); - total += diff; - } - std::cout << "average of " << total/iterations << " cycles per creation" << std::endl; -} - -void test_switching( unsigned int iterations) -{ - int value( 3); - - boost::tasklets::scheduler<> sched; - - // cache warm-up - sched.make_tasklet( fn, value, boost::tasklet::default_stacksize); - for (;;) - { - while ( sched.run() ); - if ( sched.empty() ) break; - } - - for ( unsigned int i = 0; i < iterations; ++i) - sched.make_tasklet( fn, value, boost::tasklet::default_stacksize); - - cycle_t overhead( get_overhead() ); - std::cout << "overhead for rdtsc == " << overhead << " cycles" << std::endl; - - cycle_t start( get_cycles() ); - for (;;) - { - while ( sched.run() ); - if ( sched.empty() ) break; - } - cycle_t total( get_cycles() - start); - total -= overhead * iterations; - BOOST_ASSERT( total >= 0); - std::cout << "average of " << total/iterations << " cycles per switch" << std::endl; -} - -int main( int argc, char * argv[]) -{ - try - { - unsigned int iterations( 0); - - po::options_description desc("allowed options"); - desc.add_options() - ("help,h", "help message") - ("creating,c", "test creation") - ("switching,s", "test switching") - ("iterations,i", po::value< unsigned int >( & iterations), "iterations"); - - po::variables_map vm; - po::store( - po::parse_command_line( - argc, - argv, - desc), - vm); - po::notify( vm); - - if ( vm.count("help") ) - { - std::cout << desc << std::endl; - return EXIT_SUCCESS; - } - - if ( 0 == iterations) throw std::invalid_argument("iterations must be greater than zero"); - - bind_to_processor( 0); - - if ( vm.count("creating") ) test_creation( iterations); - - if ( vm.count("switching") ) test_switching( iterations); - - return EXIT_SUCCESS; - } - catch ( std::exception const& e) - { std::cerr << "exception: " << e.what() << std::endl; } - catch (...) - { std::cerr << "unhandled exception" << std::endl; } - return EXIT_FAILURE; -} diff --git a/libs/tasklet/performance/performance.hpp b/libs/tasklet/performance/performance.hpp deleted file mode 100644 index 5f45c955..00000000 --- a/libs/tasklet/performance/performance.hpp +++ /dev/null @@ -1,26 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef PERFORMANCE_H -#define PERFORMANCE_H - -// msvc/icc, i386 -#if defined(_MSC_VER) && defined(_M_IX86) -#include "performance_msvc_i386.hpp" - -// gcc/icc, i386 -#elif defined(__GNUC__) && defined(__i386__) -#include "performance_gcc_i386.hpp" - -// gcc/icc, x86_64 -#elif defined(__GNUC__) && defined(__x86_64__) -#include "performance_gcc_x86-64.hpp" - -#else -#error "this platform is not supported" -#endif - -#endif // PERFORMANCE_H diff --git a/libs/tasklet/performance/performance_gcc_i386.hpp b/libs/tasklet/performance/performance_gcc_i386.hpp deleted file mode 100644 index 495bfa5f..00000000 --- a/libs/tasklet/performance/performance_gcc_i386.hpp +++ /dev/null @@ -1,62 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef PERFORMANCE_GCC_I386_H -#define PERFORMANCE_GCC_I386_H - -#include -#include -#include - -#include -#include -#include - -typedef uint64_t cycle_t; - -inline -cycle_t get_cycles() -{ - uint32_t res[2]; - - __asm__ __volatile__ ( - "xorl %%eax, %%eax\n" - "cpuid\n" - ::: "%eax", "%ebx", "%ecx", "%edx" - ); - __asm__ __volatile__ ("rdtsc" : "=a" (res[0]), "=d" (res[1]) ); - __asm__ __volatile__ ( - "xorl %%eax, %%eax\n" - "cpuid\n" - ::: "%eax", "%ebx", "%ecx", "%edx" - ); - - return * ( cycle_t *)res; -} - -struct measure -{ - cycle_t operator()() - { - cycle_t start( get_cycles() ); - return get_cycles() - start; - } -}; - -inline -cycle_t get_overhead() -{ - std::size_t iterations( 10); - std::vector< cycle_t > overhead( iterations, 0); - for ( std::size_t i( 0); i < iterations; ++i) - std::generate( - overhead.begin(), overhead.end(), - measure() ); - BOOST_ASSERT( overhead.begin() != overhead.end() ); - return * std::min_element( overhead.begin(), overhead.end() ); -} - -#endif // PERFORMANCE_GCC_I386_H diff --git a/libs/tasklet/performance/performance_gcc_x86-64.hpp b/libs/tasklet/performance/performance_gcc_x86-64.hpp deleted file mode 100644 index d68f726b..00000000 --- a/libs/tasklet/performance/performance_gcc_x86-64.hpp +++ /dev/null @@ -1,62 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef PERFORMANCE_GCC_X86_64_H -#define PERFORMANCE_GCC_X86_64_H - -#include -#include -#include - -#include -#include -#include - -typedef uint64_t cycle_t; - -inline -cycle_t get_cycles() -{ - uint32_t res[2]; - - __asm__ __volatile__ ( - "xorl %%eax, %%eax\n" - "cpuid\n" - ::: "%rax", "%rbx", "%rcx", "%rdx" - ); - __asm__ __volatile__ ("rdtsc" : "=a" (res[0]), "=d" (res[1]) ); - __asm__ __volatile__ ( - "xorl %%eax, %%eax\n" - "cpuid\n" - ::: "%rax", "%rbx", "%rcx", "%rdx" - ); - - return * ( cycle_t *)res; -} - -struct measure -{ - cycle_t operator()() - { - cycle_t start( get_cycles() ); - return get_cycles() - start; - } -}; - -inline -cycle_t get_overhead() -{ - std::size_t iterations( 10); - std::vector< cycle_t > overhead( iterations, 0); - for ( std::size_t i( 0); i < iterations; ++i) - std::generate( - overhead.begin(), overhead.end(), - measure() ); - BOOST_ASSERT( overhead.begin() != overhead.end() ); - return * std::min_element( overhead.begin(), overhead.end() ); -} - -#endif // PERFORMANCE_GCC_X86_64_H diff --git a/libs/tasklet/performance/performance_msvc_i386.hpp b/libs/tasklet/performance/performance_msvc_i386.hpp deleted file mode 100644 index cbbec734..00000000 --- a/libs/tasklet/performance/performance_msvc_i386.hpp +++ /dev/null @@ -1,60 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef PERFORMANCE_MSVC_X86_64_H -#define PERFORMANCE_MSVC_X86_64_H - -#include -#include -#include - -#include -#include -#include - -typedef uint64_t cycle_t; - -inline -cycle_t get_cycles() -{ - uint32_t res[2] - - __asm { - xor eax, eax - cpuid - rdtsc - mov dword ptr res[0], eax - mov dword ptr res[1], edx - xor eax, eax - cpuid - }; - - return * ( cycle_t *)res; -} - -struct measure -{ - cycle_t operator()() - { - cycle_t start( get_cycles() ); - return get_cycles() - start; - } -}; - -inline -cycle_t get_overhead() -{ - std::size_t iterations( 10); - std::vector< cycle_t > overhead( iterations, 0); - for ( std::size_t i( 0); i < iterations; ++i) - std::generate( - overhead.begin(), overhead.end(), - measure() ); - BOOST_ASSERT( overhead.begin() != overhead.end() ); - return * std::min_element( overhead.begin(), overhead.end() ); -} - -#endif // PERFORMANCE_MSVC_X86_64_H diff --git a/libs/tasklet/src/auto_reset_event.cpp b/libs/tasklet/src/auto_reset_event.cpp deleted file mode 100644 index 2969fc5c..00000000 --- a/libs/tasklet/src/auto_reset_event.cpp +++ /dev/null @@ -1,47 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#define BOOST_TASKLET_SOURCE - -#include "boost/tasklet/auto_reset_event.hpp" - -#include - -#include - -namespace boost { -namespace tasklets { - -auto_reset_event::auto_reset_event( bool isset) : - state_( isset ? SET : RESET) -{} - -void -auto_reset_event::set() -{ state_.store( SET); } - -void -auto_reset_event::wait() -{ - state expected = SET; - while ( ! state_.compare_exchange_strong( expected, RESET) ) - { - if ( this_tasklet::runs_as_tasklet() ) - this_tasklet::yield(); - else - this_thread::yield(); - expected = SET; - } -} - -bool -auto_reset_event::try_wait() -{ - state expected = SET; - return state_.compare_exchange_strong( expected, RESET); -} - -}} diff --git a/libs/tasklet/src/barrier.cpp b/libs/tasklet/src/barrier.cpp deleted file mode 100644 index a2036ae9..00000000 --- a/libs/tasklet/src/barrier.cpp +++ /dev/null @@ -1,44 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#define BOOST_TASKLET_SOURCE - -#include "boost/tasklet/barrier.hpp" - -#include - -namespace boost { -namespace tasklets { - -barrier::barrier( std::size_t initial) : - initial_( initial), - current_( initial_), - cycle_( true), - mtx_(), - cond_() -{ if ( initial == 0) throw std::invalid_argument("invalid barrier count"); } - -bool -barrier::wait() -{ - mutex::scoped_lock lk( mtx_); - bool cycle( cycle_); - if ( 0 == --current_) - { - cycle_ = ! cycle_; - current_ = initial_; - cond_.notify_all(); - return true; - } - else - { - while ( cycle == cycle_) - cond_.wait( lk); - } - return false; -} - -}} diff --git a/libs/tasklet/src/condition.cpp b/libs/tasklet/src/condition.cpp deleted file mode 100644 index 07248dc8..00000000 --- a/libs/tasklet/src/condition.cpp +++ /dev/null @@ -1,92 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#define BOOST_TASKLET_SOURCE - -#include "boost/tasklet/condition.hpp" - -#include - -namespace boost { -namespace tasklets { - -condition::condition() : - oid_( this), - waiting_tasklets_(), - oidx_( waiting_tasklets_.get< ordered_idx_tag >() ), - sidx_( waiting_tasklets_.get< sequenced_idx_tag >() ), - cmd_( SLEEPING), - waiters_( 0), - enter_mtx_(), - check_mtx_(), - mtx_() -{} - -condition::~condition() -{ - BOOST_ASSERT( waiting_tasklets_.empty() ); - BOOST_ASSERT( 0 == waiters_.load() ); -} - -void -condition::notify_one() -{ - enter_mtx_.lock(); - - if ( 0 == waiters_.load() ) - { - enter_mtx_.unlock(); - return; - } - - command expected = SLEEPING; - while ( ! cmd_.compare_exchange_strong( expected, NOTIFY_ONE) ) - { - if ( this_tasklet::runs_as_tasklet() ) - this_tasklet::yield(); - else - this_thread::yield(); - expected = SLEEPING; - } - - spin_mutex::scoped_lock lk( mtx_); - tasklet f( * sidx_.begin() ); - sidx_.pop_front(); - BOOST_ASSERT( f.impl_->attached_strategy() ); - f.impl_->attached_strategy()->object_notify_one( oid_); -} - -void -condition::notify_all() -{ - enter_mtx_.lock(); - - if ( 0 == waiters_.load() ) - { - enter_mtx_.unlock(); - return; - } - - command expected = SLEEPING; - while ( ! cmd_.compare_exchange_strong( expected, NOTIFY_ALL) ) - { - if ( this_tasklet::runs_as_tasklet() ) - this_tasklet::yield(); - else - this_thread::yield(); - expected = SLEEPING; - } - - spin_mutex::scoped_lock lk( mtx_); - BOOST_FOREACH( tasklet f, sidx_) - { - BOOST_ASSERT( f.impl_->attached_strategy() ); - f.impl_->attached_strategy()->object_notify_all( oid_); - } - waiting_tasklets_.clear(); -} - -}} diff --git a/libs/tasklet/src/count_down_event.cpp b/libs/tasklet/src/count_down_event.cpp deleted file mode 100644 index 816b7405..00000000 --- a/libs/tasklet/src/count_down_event.cpp +++ /dev/null @@ -1,61 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#define BOOST_TASKLET_SOURCE - -#include "boost/tasklet/count_down_event.hpp" - -#include - -#include -#include - -namespace boost { -namespace tasklets { - -count_down_event::count_down_event( std::size_t initial) : - initial_( initial), - current_( initial_) -{} - -std::size_t -count_down_event::initial() const -{ return initial_; } - -std::size_t -count_down_event::current() const -{ return current_.load(); } - -bool -count_down_event::is_set() const -{ return 0 == current_.load(); } - -void -count_down_event::set() -{ - for (;;) - { - if ( 0 == current_.load() ) - return; - std::size_t expected = current_.load(); - if ( current_.compare_exchange_strong( expected, expected - 1) ) - return; - } -} - -void -count_down_event::wait() -{ - while ( 0 != current_.load() ) - { - if ( this_tasklet::runs_as_tasklet() ) - this_tasklet::yield(); - else - this_thread::yield(); - } -} - -}} diff --git a/libs/tasklet/src/detail/tasklet_base.cpp b/libs/tasklet/src/detail/tasklet_base.cpp deleted file mode 100644 index 341faf17..00000000 --- a/libs/tasklet/src/detail/tasklet_base.cpp +++ /dev/null @@ -1,75 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#define BOOST_TASKLET_SOURCE - -#include - -#include - -#include -#include - -#include - -namespace boost { -namespace tasklets { -namespace detail { - -BOOST_TASKLET_DECL void trampoline( void * vp) -{ - BOOST_ASSERT( vp); - detail::tasklet_base * self( static_cast< detail::tasklet_base * >( vp) ); - try - { self->exec(); } - catch ( tasklet_interrupted const&) {} - catch (...) {} - this_tasklet::cancel(); -} - -void -tasklet_base::run() -{ fib_.run(); } - -void -tasklet_base::yield() -{ fib_.yield(); } - -int -tasklet_base::priority() const -{ return priority_; } - -void -tasklet_base::priority( int prio) -{ priority_ = prio; } - -state_type -tasklet_base::state() const -{ return state_; } - -void -tasklet_base::state( state_type st) -{ state_ = st; } - -interrupt_type & -tasklet_base::interrupt() -{ return interrupt_; } - -void -tasklet_base::interrupt( interrupt_type intr) -{ interrupt_ = intr; } - -strategy * -tasklet_base::attached_strategy() -{ return st_; } - -void -tasklet_base::attached_strategy( strategy * st) -{ st_ = st; } - -}}} - -#include diff --git a/libs/tasklet/src/manual_reset_event.cpp b/libs/tasklet/src/manual_reset_event.cpp deleted file mode 100644 index 9da043ca..00000000 --- a/libs/tasklet/src/manual_reset_event.cpp +++ /dev/null @@ -1,83 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#define BOOST_TASKLET_SOURCE - -#include "boost/tasklet/manual_reset_event.hpp" - -#include -#include - -#include - -namespace boost { -namespace tasklets { - -manual_reset_event::manual_reset_event( bool isset) : - state_( isset ? SET : RESET), - waiters_( 0), - enter_mtx_() -{} - -void -manual_reset_event::set() -{ - enter_mtx_.lock(); - - state expected = RESET; - if ( ! state_.compare_exchange_strong( expected, SET) || - 0 == waiters_.load() ) - enter_mtx_.unlock(); -} - -void -manual_reset_event::reset() -{ - mutex::scoped_lock lk( enter_mtx_); - BOOST_ASSERT( lk); - - state_.store( RESET); -} - -void -manual_reset_event::wait() -{ - { - mutex::scoped_lock lk( enter_mtx_); - BOOST_ASSERT( lk); - waiters_.fetch_add( 1); - } - - while ( RESET == state_.load() ) - { - if ( this_tasklet::runs_as_tasklet() ) - this_tasklet::yield(); - else - this_thread::yield(); - } - - if ( 1 == waiters_.fetch_sub( 1) ) - enter_mtx_.unlock(); -} - -bool -manual_reset_event::try_wait() -{ - { - mutex::scoped_lock lk( enter_mtx_); - BOOST_ASSERT( lk); - waiters_.fetch_add( 1); - } - - bool result = SET == state_.load(); - - if ( 1 == waiters_.fetch_sub( 1) ) - enter_mtx_.unlock(); - - return result; -} - -}} diff --git a/libs/tasklet/src/mutex.cpp b/libs/tasklet/src/mutex.cpp deleted file mode 100644 index 6aef604f..00000000 --- a/libs/tasklet/src/mutex.cpp +++ /dev/null @@ -1,83 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#define BOOST_TASKLET_SOURCE - -#include - -#include -#include - -#include - -namespace boost { -namespace tasklets { - -mutex::mutex() : - oid_( this), - state_( UNLOCKED), - mtx_(), - waiting_tasklets_(), - oidx_( waiting_tasklets_.get< ordered_idx_tag >() ), - sidx_( waiting_tasklets_.get< sequenced_idx_tag >() ) -{} - -mutex::~mutex() -{ BOOST_ASSERT( waiting_tasklets_.empty() ); } - -void -mutex::lock() -{ - for (;;) - { - spin_mutex::scoped_lock lk( mtx_); - if ( UNLOCKED == state_) - { - state_ = LOCKED; - // TODO: store identifier of tasklet/thread - lk.unlock(); - break; - } - else if ( this_tasklet::runs_as_tasklet() ) - { - tasklet * f( strategy::active_tasklet); - BOOST_ASSERT( f); - oidx_.insert( * f); - BOOST_ASSERT( f->impl_->attached_strategy() ); - f->impl_->attached_strategy()->wait_for_object( oid_, lk); - } - else - { - lk.unlock(); - this_thread::yield(); - } - } -} - -bool -mutex::try_lock() -{ - spin_mutex::scoped_lock lk( mtx_); - if ( LOCKED == state_) return false; - state_ = LOCKED; - return true; -} - -void -mutex::unlock() -{ - // TODO: only the tasklet/thread locked the mutex - // can call unlock() - spin_mutex::scoped_lock lk( mtx_); - state_ = UNLOCKED; - if ( waiting_tasklets_.empty() ) return; - tasklet f( * sidx_.begin() ); - sidx_.pop_front(); - BOOST_ASSERT( f.impl_->attached_strategy() ); - f.impl_->attached_strategy()->object_notify_one( oid_); -} - -}} diff --git a/libs/tasklet/src/round_robin.cpp b/libs/tasklet/src/round_robin.cpp deleted file mode 100644 index 06f24f75..00000000 --- a/libs/tasklet/src/round_robin.cpp +++ /dev/null @@ -1,478 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#define BOOST_TASKLET_SOURCE - -#include - -#include -#include - -#include -#include -#include - -#include - -#include - -namespace boost { -namespace tasklets { - -round_robin::round_robin() : - mtx_(), - tasklets_(), - objects_(), - runnable_tasklets_(), - terminated_tasklets_() -{} - -void -round_robin::add( tasklet & t) -{ - spin_mutex::scoped_lock lk( mtx_); - - if ( ! t) throw tasklet_moved(); - - BOOST_ASSERT( in_state_not_started( t) ); - - // set state to ready - set_state_ready( t); - - // attach to this scheduler - attach( t); - - // insert tasklet to tasklet-list - std::pair< std::map< tasklet::id, schedulable >::iterator, bool > result( - tasklets_.insert( - std::make_pair( - t.get_id(), - schedulable( t) ) ) ); - - // check result - if ( ! result.second) throw scheduler_error("inserting tasklet failed"); - - // put tasklet to runnable-queue - runnable_tasklets_.push_back( result.first->first); -} - -void -round_robin::join( tasklet & t) -{ - spin_mutex::scoped_lock lk( mtx_); - - BOOST_ASSERT( t); - BOOST_ASSERT( ! in_state_not_started( t) ); - BOOST_ASSERT( active_tasklet); - tasklet_map::iterator i = tasklets_.find( t.get_id() ); - if ( i == tasklets_.end() ) return; - schedulable s( i->second); - - // nothing to do for a terminated tasklet - if ( in_state_terminated( t) ) return; - - // prevent self-join - if ( active_tasklet->get_id() == t.get_id() ) - throw scheduler_error("self-join denied"); - - // register on tasklet to be joined - tasklets_[t.get_id()].joining_tasklets.push_back( active_tasklet->get_id() ); - - // set state waiting - set_state_wait_for_tasklet( * active_tasklet); - - // set tasklet-id waiting-on - tasklets_[active_tasklet->get_id()].waiting_on_tasklet = t.get_id(); - - // switch to master-tasklet - lk.unlock(); - strategy::yield( * active_tasklet); - lk.lock(); - - // tasklet returned - BOOST_ASSERT( in_state_running( * active_tasklet) ); - BOOST_ASSERT( ! tasklets_[active_tasklet->get_id()].waiting_on_tasklet); - - // check if interruption was requested - if ( interruption_enabled( * active_tasklet) ) - throw tasklet_interrupted(); -} - -void -round_robin::interrupt( tasklet & t) -{ - spin_mutex::scoped_lock lk( mtx_); - - BOOST_ASSERT( t); - BOOST_ASSERT( ! in_state_not_started( t) ); - tasklet_map::iterator i = tasklets_.find( t.get_id() ); - if ( i == tasklets_.end() ) return; - schedulable s( i->second); - - // nothing to do for al terminated tasklet - if ( in_state_terminated( t) ) return; - - enable_interruption( t); - - // if tasklet is waiting - if ( in_state_wait_for_tasklet( t) ) - { - // tasklet is waiting (joining) on another tasklet - // remove it from the waiting-queue, reset waiting-on - // and reset the waiting state - BOOST_ASSERT( s.waiting_on_tasklet); - tasklets_[* s.waiting_on_tasklet].joining_tasklets.remove( t.get_id() ); - tasklets_[t.get_id()].waiting_on_tasklet.reset(); - set_state_ready( t); - runnable_tasklets_.push_back( t.get_id() ); - } else if ( in_state_wait_for_object( t) ) { - // tasklet is waiting on an object - // remove it from the waiting-queue, reset waiting-on - // and reset the waiting state - BOOST_ASSERT( s.waiting_on_object); - objects_[* s.waiting_on_object].remove( t.get_id() ); - tasklets_[t.get_id()].waiting_on_object.reset(); - set_state_ready( t); - runnable_tasklets_.push_back( t.get_id()); - } -} - -void -round_robin::reschedule( tasklet & t) -{ - spin_mutex::scoped_lock lk( mtx_); - - BOOST_ASSERT( t); - BOOST_ASSERT( ! in_state_not_started( t) ); - BOOST_ASSERT( ! in_state_terminated( t) ); - tasklet_map::iterator i = tasklets_.find( t.get_id() ); - if ( i == tasklets_.end() ) return; -} - -void -round_robin::cancel( tasklet & t) -{ - spin_mutex::scoped_lock lk( mtx_); - - BOOST_ASSERT( t); - BOOST_ASSERT( ! in_state_not_started( t) ); - BOOST_ASSERT( active_tasklet); - - // nothing to do for al terminated tasklet - if ( in_state_terminated( t) ) return; - - tasklet_map::iterator i( tasklets_.find( t.get_id() ) ); - if ( i == tasklets_.end() ) return; - schedulable s( i->second); - - // invoke each tasklet waiting on this tasklet - BOOST_FOREACH( tasklet::id id__, s.joining_tasklets) - { - schedulable s__( tasklets_[id__]); - tasklet f__( s__.f); - BOOST_ASSERT( s__.waiting_on_tasklet); - BOOST_ASSERT( in_state_wait_for_tasklet( f__) ); - - // clear waiting-on - tasklets_[id__].waiting_on_tasklet.reset(); - - // put tasklet on runnable-queue - set_state_ready( f__); - runnable_tasklets_.push_back( id__); - } - // clear waiting-queue - tasklets_[t.get_id()].joining_tasklets.clear(); - - // if tasklet is ready remove it from the runnable-queue - // and put it to terminated-queue - if ( in_state_ready( t) ) - { - set_state_terminated( t); - runnable_tasklets_.remove( t.get_id() ); - terminated_tasklets_.push( t.get_id() ); - } - // if tasklet is running (== active tasklet) - // reset active tasklet - // put it to terminated-queue and switch - // to master tasklet - else if ( in_state_running( t) ) - { - BOOST_ASSERT( active_tasklet->get_id() == t.get_id() ); - set_state_terminated( t); - terminated_tasklets_.push( t.get_id() ); - lk.unlock(); - strategy::yield( t); - } - // if tasklet is waiting then remove it from the - // waiting-queue and put it to terminated-queue - else if ( in_state_wait_for_tasklet( t) ) - { - BOOST_ASSERT( s.waiting_on_tasklet); - set_state_terminated( t); - tasklets_[* s.waiting_on_tasklet].joining_tasklets.remove( t.get_id() ); - terminated_tasklets_.push( t.get_id() ); - } - else - BOOST_ASSERT( ! "should never reached"); -} - -void -round_robin::yield() -{ - spin_mutex::scoped_lock lk( mtx_); - - BOOST_ASSERT( active_tasklet); - BOOST_ASSERT( in_state_running( * active_tasklet) ); - BOOST_ASSERT( ! tasklets_[active_tasklet->get_id()].waiting_on_tasklet); - - // set state ready - set_state_ready( * active_tasklet); - - // put tasklet to runnable-queue - runnable_tasklets_.push_back( active_tasklet->get_id() ); - - // switch to master-tasklet - lk.unlock(); - strategy::yield( * active_tasklet); -} - -void -round_robin::wait_for_object( object::id const& oid, spin_mutex::scoped_lock & slk) -{ - spin_mutex::scoped_lock lk( mtx_); - - BOOST_ASSERT( active_tasklet); - tasklet::id id = active_tasklet->get_id(); - tasklet_map::iterator i = tasklets_.find( id); - if ( i == tasklets_.end() ) return; - schedulable s( i->second); - tasklet f( s.f); - BOOST_ASSERT( f); - BOOST_ASSERT( active_tasklet->get_id() == id); - BOOST_ASSERT( in_state_running( f) ); - BOOST_ASSERT( ! s.waiting_on_tasklet); - BOOST_ASSERT( ! s.waiting_on_object); - - // register on object to be waiting on - objects_[oid].push_back( id); - - // set state waiting - set_state_wait_for_object( f); - - // set object-id waiting-on - tasklets_[id].waiting_on_object = oid; - - // release lock protecting sync. primitive - slk.unlock(); - - // switch to master-tasklet - lk.unlock(); - strategy::yield( * active_tasklet); - lk.lock(); - - // tasklet returned - BOOST_ASSERT( active_tasklet->get_id() == id); - BOOST_ASSERT( in_state_running( tasklets_[id].f) ); - BOOST_ASSERT( ! tasklets_[id].waiting_on_tasklet); - BOOST_ASSERT( ! tasklets_[id].waiting_on_object); - - // check if interruption was requested - if ( interruption_enabled( f) ) - throw tasklet_interrupted(); -} - -void -round_robin::object_notify_one( object::id const& oid) -{ - spin_mutex::scoped_lock lk( mtx_); - - object_map::iterator oi( objects_.find( oid) ); - BOOST_ASSERT( oi != objects_.end() ); - if ( oi->second.empty() ) return; - tasklet::id id( oi->second.front() ); - oi->second.pop_front(); - - tasklet_map::iterator fi = tasklets_.find( id); - BOOST_ASSERT( fi != tasklets_.end() ); - schedulable s( fi->second); - tasklet f( s.f); - BOOST_ASSERT( f); - BOOST_ASSERT( ! s.waiting_on_tasklet); - BOOST_ASSERT( s.waiting_on_object); - BOOST_ASSERT( * s.waiting_on_object == oid); - - // remove object waiting for - tasklets_[id].waiting_on_object.reset(); - - // set state ready - set_state_ready( f); - - // put tasklet to runnable-queue - runnable_tasklets_.push_back( id); -} - -void -round_robin::object_notify_all( object::id const& oid) -{ - spin_mutex::scoped_lock lk( mtx_); - - object_map::iterator oi( objects_.find( oid) ); - if ( oi == objects_.end() ) - // NOTE: because of previous calls to this function - // all references may be already released - // this can happen by calling condition::notify_all() - return; - tasklet_id_list::iterator fe( oi->second.end() ); - for ( - tasklet_id_list::iterator fi( oi->second.begin() ); - fi != fe; - ++fi) - { - tasklet::id id( * fi); - - tasklet_map::iterator i = tasklets_.find( id); - BOOST_ASSERT( i != tasklets_.end() ); - schedulable s( i->second); - tasklet f( s.f); - BOOST_ASSERT( f); - BOOST_ASSERT( ! s.waiting_on_tasklet); - BOOST_ASSERT( s.waiting_on_object); - BOOST_ASSERT( * s.waiting_on_object == oid); - - // remove object waiting for - tasklets_[id].waiting_on_object.reset(); - - // set state ready - set_state_ready( f); - - // put tasklet to runnable-queue - runnable_tasklets_.push_back( id); - } - objects_.erase( oi); -} - -void -round_robin::release( tasklet & t) -{ - spin_mutex::scoped_lock lk( mtx_); - - BOOST_ASSERT( t); - tasklet_map::iterator fi = tasklets_.find( t.get_id() ); - if ( fi == tasklets_.end() ) - throw scheduler_error("tasklet not managed by scheduler"); - schedulable s( fi->second); - if ( ! in_state_ready( t) || ! s.joining_tasklets.empty() ) - throw tasklet_error("tasklet can not be released"); - BOOST_ASSERT( ! s.waiting_on_tasklet); - BOOST_ASSERT( ! s.waiting_on_object); - - runnable_tasklets_.remove( t.get_id() ); - tasklets_.erase( t.get_id() ); -} - -void -round_robin::migrate( tasklet & t) -{ - spin_mutex::scoped_lock lk( mtx_); - - if ( ! t) throw tasklet_moved(); - - BOOST_ASSERT( in_state_ready( t) ); - - // attach to this scheduler - attach( t); - - // insert tasklet to tasklet-list - std::pair< std::map< tasklet::id, schedulable >::iterator, bool > result( - tasklets_.insert( - std::make_pair( - t.get_id(), - schedulable( t) ) ) ); - - // check result - if ( ! result.second) throw scheduler_error("migrating tasklet failed"); - - // put tasklet to runnable-queue - runnable_tasklets_.push_back( result.first->first); -} - -void -round_robin::detach_all() -{ - spin_mutex::scoped_lock lk( mtx_); - BOOST_FOREACH( tasklet_map::value_type va, tasklets_) - { detach( va.second.f); } -} - -bool -round_robin::run() -{ - spin_mutex::scoped_lock lk( mtx_); - - bool result( false); - if ( ! runnable_tasklets_.empty() ) - { - schedulable s = tasklets_[runnable_tasklets_.front()]; - runnable_tasklets_.pop_front(); - active_tasklet = & s.f; - BOOST_ASSERT( ! s.waiting_on_tasklet); - BOOST_ASSERT( ! s.waiting_on_object); - BOOST_ASSERT( in_state_ready( * active_tasklet) ); - set_state_running( * active_tasklet); - lk.unlock(); - call( * active_tasklet); - lk.lock(); - active_tasklet = 0; - result = true; - } - - while ( ! terminated_tasklets_.empty() ) - { - tasklet_map::iterator i( tasklets_.find( terminated_tasklets_.front() ) ); - BOOST_ASSERT( i != tasklets_.end() ); - schedulable s( i->second); - tasklet f( s.f); - terminated_tasklets_.pop(); - BOOST_ASSERT( s.joining_tasklets.empty() ); - BOOST_ASSERT( ! s.waiting_on_tasklet); - BOOST_ASSERT( ! s.waiting_on_object); - BOOST_ASSERT( in_state_terminated( f) ); - tasklets_.erase( i); - } - return result; -} - -bool -round_robin::empty() const -{ - spin_mutex::scoped_lock lk( mtx_); - return tasklets_.empty(); -} - -std::size_t -round_robin::size() const -{ - spin_mutex::scoped_lock lk( mtx_); - return tasklets_.size(); -} - -std::size_t -round_robin::ready() const -{ - spin_mutex::scoped_lock lk( mtx_); - return runnable_tasklets_.size(); -} - -bool -round_robin::has_ready() const -{ - spin_mutex::scoped_lock lk( mtx_); - return ! runnable_tasklets_.empty(); -} - -}} - -#include diff --git a/libs/tasklet/src/spin_condition.cpp b/libs/tasklet/src/spin_condition.cpp deleted file mode 100644 index 15ad44d3..00000000 --- a/libs/tasklet/src/spin_condition.cpp +++ /dev/null @@ -1,53 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#define BOOST_TASKLET_SOURCE - -#include "boost/tasklet/spin_condition.hpp" - -#include - -namespace boost { -namespace tasklets { - -void -spin_condition::notify_( command cmd) -{ - enter_mtx_.lock(); - - if ( 0 == waiters_.load() ) - { - enter_mtx_.unlock(); - return; - } - - command expected = SLEEPING; - while ( ! cmd_.compare_exchange_strong( expected, cmd) ) - { - if ( this_tasklet::runs_as_tasklet() ) - this_tasklet::yield(); - else - this_thread::yield(); - expected = SLEEPING; - } -} - -spin_condition::spin_condition() : - cmd_( SLEEPING), - waiters_( 0), - enter_mtx_(), - check_mtx_() -{} - -void -spin_condition::notify_one() -{ notify_( NOTIFY_ONE); } - -void -spin_condition::notify_all() -{ notify_( NOTIFY_ALL); } - -}} diff --git a/libs/tasklet/src/spin_mutex.cpp b/libs/tasklet/src/spin_mutex.cpp deleted file mode 100644 index 511b6718..00000000 --- a/libs/tasklet/src/spin_mutex.cpp +++ /dev/null @@ -1,48 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#define BOOST_TASKLET_SOURCE - -#include - -#include - -#include - -namespace boost { -namespace tasklets { - -spin_mutex::spin_mutex() : - state_( UNLOCKED) -{} - -void -spin_mutex::lock() -{ - for (;;) - { - state expected = UNLOCKED; - if ( state_.compare_exchange_strong( expected, LOCKED) ) - break; - if ( this_tasklet::runs_as_tasklet() ) - this_tasklet::yield(); - else - this_thread::yield(); - } -} - -bool -spin_mutex::try_lock() -{ - state expected = UNLOCKED; - return state_.compare_exchange_strong( expected, LOCKED); -} - -void -spin_mutex::unlock() -{ state_.store( UNLOCKED); } - -}} diff --git a/libs/tasklet/src/strategy.cpp b/libs/tasklet/src/strategy.cpp deleted file mode 100644 index 197d6eb9..00000000 --- a/libs/tasklet/src/strategy.cpp +++ /dev/null @@ -1,194 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#define BOOST_TASKLET_SOURCE - -#include - -#include - -#include - -#include -#include -#include -#include - -namespace boost { -namespace tasklets { - -BOOST_TASKLET_TSSDECL tasklet * strategy::active_tasklet = 0; - -bool -strategy::runs_as_tasklet_() -{ return 0 != active_tasklet; } - -tasklet::id -strategy::get_id_() -{ - if ( ! active_tasklet) throw tasklet_error("not a tasklet"); - return active_tasklet->get_id(); -} - -void -strategy::interruption_point_() -{ - if ( ! active_tasklet) throw tasklet_error("not a tasklet"); - if ( detail::INTERRUPTION_ENABLED == active_tasklet->impl_->interrupt() ) - throw tasklet_interrupted(); -} - -bool -strategy::interruption_requested_() -{ - if ( ! active_tasklet) throw tasklet_error("not a tasklet"); - return active_tasklet->interruption_requested(); -} - -detail::interrupt_type & -strategy::interrupt_flags_() -{ - if ( ! active_tasklet) throw tasklet_error("not a tasklet"); - return active_tasklet->impl_->interrupt(); -} - -bool -strategy::interruption_enabled_() -{ - if ( ! active_tasklet) throw tasklet_error("not a tasklet"); - return ( active_tasklet->impl_->interrupt() & detail::INTERRUPTION_ENABLED) != 0; -} - -int -strategy::priority_() -{ - if ( ! active_tasklet) throw tasklet_error("not a tasklet"); - return active_tasklet->priority(); -} - -void -strategy::priority_( int prio) -{ - if ( ! active_tasklet) throw tasklet_error("not a tasklet"); - active_tasklet->priority( prio); -} - -void -strategy::yield_() -{ - if ( ! active_tasklet) throw tasklet_error("not a tasklet"); - if ( ! active_tasklet->impl_->attached_strategy() ) throw scheduler_error("no valid scheduler"); - active_tasklet->impl_->attached_strategy()->yield(); -} - -void -strategy::cancel_() -{ - if ( ! active_tasklet) throw tasklet_error("not a tasklet"); - if ( ! active_tasklet->impl_->attached_strategy() ) throw scheduler_error("no valid scheduler"); - active_tasklet->impl_->attached_strategy()->cancel( * active_tasklet); -} - -void -strategy::submit_tasklet_( tasklet f) -{ - if ( ! active_tasklet) throw tasklet_error("not a tasklet"); - if ( ! active_tasklet->impl_->attached_strategy() ) throw scheduler_error("no valid scheduler"); - active_tasklet->impl_->attached_strategy()->add( f); -} - -strategy::strategy() -{} - -strategy::~strategy() -{} - -void -strategy::call( tasklet & f) -{ - BOOST_ASSERT( f); - BOOST_ASSERT( f.impl_->attached_strategy() ); - BOOST_ASSERT( detail::STATE_RUNNING == f.impl_->state() ); - f.impl_->run(); -} - -void -strategy::yield( tasklet & f) -{ - BOOST_ASSERT( f); - BOOST_ASSERT( f.impl_->attached_strategy() ); - BOOST_ASSERT( detail::STATE_RUNNING == f.impl_->state() || detail::STATE_READY == f.impl_->state() ); - f.impl_->yield(); -} - -void -strategy::attach( tasklet & f) -{ f.impl_->attached_strategy( this); } - -void -strategy::detach( tasklet & f) -{ f.impl_->attached_strategy( 0); } - -void -strategy::enable_interruption( tasklet & f) -{ - detail::interrupt_type intr( f.impl_->interrupt() ); - // remove disabled flag - intr &= ~detail::INTERRUPTION_DISABLED; - // set enabled flag - intr |= detail::INTERRUPTION_ENABLED; - f.impl_->interrupt( intr); -} - -bool -strategy::interruption_enabled( tasklet const& f) -{ return detail::INTERRUPTION_ENABLED == f.impl_->interrupt(); } - -bool -strategy::in_state_not_started( tasklet const& f) -{ return detail::STATE_NOT_STARTED == f.impl_->state(); } - -bool -strategy::in_state_ready( tasklet const& f) -{ return detail::STATE_READY == f.impl_->state(); } - -bool -strategy::in_state_running( tasklet const& f) -{ return detail::STATE_RUNNING == f.impl_->state(); } - -bool -strategy::in_state_wait_for_tasklet( tasklet const& f) -{ return detail::STATE_WAIT_FOR_TASKLET == f.impl_->state(); } - -bool -strategy::in_state_wait_for_object( tasklet const& f) -{ return detail::STATE_WAIT_FOR_OBJECT == f.impl_->state(); } - -bool -strategy::in_state_terminated( tasklet const& f) -{ return detail::STATE_TERMINATED == f.impl_->state(); } - -void -strategy::set_state_ready( tasklet & f) -{ f.impl_->state( detail::STATE_READY); } - -void -strategy::set_state_running( tasklet & f) -{ f.impl_->state( detail::STATE_RUNNING); } - -void -strategy::set_state_wait_for_tasklet( tasklet & f) -{ f.impl_->state( detail::STATE_WAIT_FOR_TASKLET); } - -void -strategy::set_state_wait_for_object( tasklet & f) -{ f.impl_->state( detail::STATE_WAIT_FOR_OBJECT); } - -void -strategy::set_state_terminated( tasklet & f) -{ f.impl_->state( detail::STATE_TERMINATED); } - -}} diff --git a/libs/tasklet/src/tasklet.cpp b/libs/tasklet/src/tasklet.cpp deleted file mode 100644 index 059e8492..00000000 --- a/libs/tasklet/src/tasklet.cpp +++ /dev/null @@ -1,133 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#define BOOST_TASKLET_SOURCE - -#include - -#include - -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace tasklets { - -std::size_t -tasklet::default_stacksize = 65536; - -tasklet::tasklet() : - impl_() -{} - -tasklet::tasklet( tasklet const& other) : - impl_( other.impl_) -{} - -tasklet & -tasklet::operator=( BOOST_COPY_ASSIGN_REF( tasklet) other) -{ - if ( this == & other) return * this; - impl_ = other.impl_; - return * this; -} - -tasklet::tasklet( BOOST_RV_REF( tasklet) other) -{ - impl_ = other.impl_; - other.impl_.reset(); -} - -tasklet & -tasklet::operator=( BOOST_RV_REF( tasklet) other) -{ - tasklet tmp( other); - swap( tmp); - return * this; -} - -tasklet::operator unspecified_bool_type() const -{ return impl_; } - -bool -tasklet::operator!() const -{ return ! impl_; } - -bool -tasklet::operator==( tasklet const& other) const -{ return get_id() == other.get_id(); } - -bool -tasklet::operator!=( tasklet const& other) const -{ return !( get_id() == other.get_id() ); } - -void -tasklet::swap( tasklet & other) -{ impl_.swap( other.impl_); } - -tasklet::id -tasklet::get_id() const -{ return tasklet::id( impl_); } - -bool -tasklet::is_alive() const -{ - if ( ! impl_) throw tasklet_moved(); - return ( impl_->state() & IS_ALIVE_BIT_MASK) != 0; -} - -int -tasklet::priority() const -{ - if ( ! impl_) throw tasklet_moved(); - return impl_->priority(); -} - -void -tasklet::priority( int prio) -{ - if ( ! impl_) throw tasklet_moved(); - impl_->priority( prio); - if ( is_alive() ) - impl_->attached_strategy()->reschedule( * this); -} - -void -tasklet::interrupt() -{ - if ( ! impl_) throw tasklet_moved(); - impl_->attached_strategy()->interrupt( * this); -} - -bool -tasklet::interruption_requested() const -{ - if ( ! impl_) throw tasklet_moved(); - return ( impl_->interrupt() & detail::INTERRUPTION_ENABLED) != 0; -} - -void -tasklet::cancel() -{ - if ( ! impl_) throw tasklet_moved(); - impl_->attached_strategy()->cancel( * this); -} - -void -tasklet::join() -{ - if ( ! impl_) throw tasklet_moved(); - impl_->attached_strategy()->join( * this); -} - -}} - -#include diff --git a/libs/tasklet/test/Jamfile.v2 b/libs/tasklet/test/Jamfile.v2 deleted file mode 100644 index 9a2df04c..00000000 --- a/libs/tasklet/test/Jamfile.v2 +++ /dev/null @@ -1,44 +0,0 @@ -# Boost.tasklet Library Tests Jamfile - -# Copyright Oliver Kowalke 2009. -# Distributed under the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) - -import testing ; - -project boost/tasklet/test - : requirements - ../../test/build//boost_unit_test_framework - /boost/fiber//boost_fiber - /boost/tasklet//boost_tasklet - /boost/thread//boost_thread - static - multi - ; - -rule tasklet-test ( source ) -{ - return - [ run $(source).cpp ] - ; -} - -test-suite tasklet : - [ tasklet-test test_spin_mutex ] - [ tasklet-test test_spin_condition ] - [ tasklet-test test_tasklet ] - [ tasklet-test test_scheduler ] - [ tasklet-test test_utility ] - [ tasklet-test test_cancel ] - [ tasklet-test test_priority ] - [ tasklet-test test_join ] - [ tasklet-test test_interrupt ] - [ tasklet-test test_mutex ] - [ tasklet-test test_lock ] - [ tasklet-test test_condition ] - [ tasklet-test test_barrier ] - [ tasklet-test test_auto_reset_event ] - [ tasklet-test test_manual_reset_event ] - [ tasklet-test test_count_down_event ] - ; diff --git a/libs/tasklet/test/condition_test_common.hpp b/libs/tasklet/test/condition_test_common.hpp deleted file mode 100644 index 51ffa045..00000000 --- a/libs/tasklet/test/condition_test_common.hpp +++ /dev/null @@ -1,63 +0,0 @@ -#ifndef TASK_CONDITION_TEST_COMMON_HPP -#define TASK_CONDITION_TEST_COMMON_HPP -// Copyright (C) 2007 Anthony Williams -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -#include - -#include - -unsigned const timeout_seconds=5; - -struct wait_for_flag : private boost::noncopyable -{ - boost::tasklet::mutex mutex; - boost::tasklet::condition cond_var; - bool flag; - unsigned woken; - - wait_for_flag(): - flag(false),woken(0) - {} - - struct check_flag - { - bool const& flag; - - check_flag(bool const& flag_): - flag(flag_) - {} - - bool operator()() const - { - return flag; - } - private: - void operator=(check_flag&); - }; - - - void wait_without_predicate() - { - boost::tasklet::mutex::scoped_lock lock(mutex); - while(!flag) - { - cond_var.wait(lock); - } - ++woken; - } - - void wait_with_predicate() - { - boost::tasklet::mutex::scoped_lock lock(mutex); - cond_var.wait(lock,check_flag(flag)); - if(flag) - { - ++woken; - } - } -}; - -#endif diff --git a/libs/tasklet/test/test_auto_reset_event.cpp b/libs/tasklet/test/test_auto_reset_event.cpp deleted file mode 100644 index ca087d5b..00000000 --- a/libs/tasklet/test/test_auto_reset_event.cpp +++ /dev/null @@ -1,132 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include - -int value = 0; - -void wait_fn( boost::tasklets::auto_reset_event & ev) -{ - ev.wait(); - ++value; -} - -// check wait -void test_case_1() -{ - value = 0; - boost::tasklets::scheduler<> sched; - boost::tasklets::auto_reset_event ev; - - sched.submit_tasklet( - boost::tasklet( - wait_fn, - boost::ref( ev), - boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - - sched.submit_tasklet( - boost::tasklet( - wait_fn, - boost::ref( ev), - boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - - BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() ); - BOOST_CHECK_EQUAL( 0, value); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() ); - BOOST_CHECK_EQUAL( 0, value); - - ev.set(); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() ); - BOOST_CHECK_EQUAL( 1, value); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() ); - BOOST_CHECK_EQUAL( 1, value); - - ev.set(); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 0), sched.size() ); - BOOST_CHECK_EQUAL( 2, value); -} - -void test_case_2() -{ - value = 0; - boost::tasklets::scheduler<> sched; - boost::tasklets::auto_reset_event ev( true); - - sched.submit_tasklet( - boost::tasklet( - wait_fn, - boost::ref( ev), - boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - - sched.submit_tasklet( - boost::tasklet( - wait_fn, - boost::ref( ev), - boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - - BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() ); - BOOST_CHECK_EQUAL( 0, value); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() ); - BOOST_CHECK_EQUAL( 1, value); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() ); - BOOST_CHECK_EQUAL( 1, value); - - ev.set(); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 0), sched.size() ); - BOOST_CHECK_EQUAL( 2, value); -} - -void test_case_3() -{ - boost::tasklets::scheduler<> sched; - boost::tasklets::auto_reset_event ev; - - BOOST_CHECK_EQUAL( false, ev.try_wait() ); - - ev.set(); - - BOOST_CHECK_EQUAL( true, ev.try_wait() ); - BOOST_CHECK_EQUAL( false, ev.try_wait() ); -} - -boost::unit_test::test_suite * init_unit_test_suite( int, char* []) -{ - boost::unit_test::test_suite * test = - BOOST_TEST_SUITE("Boost.Tasklet: auto-reset-event test suite"); - - test->add( BOOST_TEST_CASE( & test_case_1) ); - test->add( BOOST_TEST_CASE( & test_case_2) ); - test->add( BOOST_TEST_CASE( & test_case_3) ); - - return test; -} diff --git a/libs/tasklet/test/test_barrier.cpp b/libs/tasklet/test/test_barrier.cpp deleted file mode 100644 index 89dbbe10..00000000 --- a/libs/tasklet/test/test_barrier.cpp +++ /dev/null @@ -1,149 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include - -#include -#include - -#include - -int value1 = 0; -int value2 = 0; - -void fn_1( boost::tasklets::barrier & b) -{ - ++value1; - boost::this_tasklet::yield(); - - b.wait(); - - ++value1; - boost::this_tasklet::yield(); - ++value1; - boost::this_tasklet::yield(); - ++value1; - boost::this_tasklet::yield(); - ++value1; -} - -void fn_2( boost::tasklets::barrier & b) -{ - ++value2; - boost::this_tasklet::yield(); - ++value2; - boost::this_tasklet::yield(); - ++value2; - boost::this_tasklet::yield(); - - b.wait(); - - ++value2; - boost::this_tasklet::yield(); - ++value2; -} - -void test_case_1() -{ - value1 = 0; - value2 = 0; - - boost::tasklets::scheduler<> sched; - - boost::tasklets::barrier b( 2); - sched.submit_tasklet( - boost::tasklet( - fn_1, boost::ref( b), boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - sched.submit_tasklet( - boost::tasklet( - fn_2, boost::ref( b), boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - - BOOST_CHECK_EQUAL( 0, value1); - BOOST_CHECK_EQUAL( 0, value2); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( ! sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() ); - BOOST_CHECK_EQUAL( 1, value1); - BOOST_CHECK_EQUAL( 0, value2); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( ! sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() ); - BOOST_CHECK_EQUAL( 1, value1); - BOOST_CHECK_EQUAL( 1, value2); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( ! sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() ); - BOOST_CHECK_EQUAL( 1, value1); - BOOST_CHECK_EQUAL( 1, value2); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( ! sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() ); - BOOST_CHECK_EQUAL( 1, value1); - BOOST_CHECK_EQUAL( 2, value2); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( ! sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() ); - BOOST_CHECK_EQUAL( 1, value1); - BOOST_CHECK_EQUAL( 3, value2); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( ! sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() ); - BOOST_CHECK_EQUAL( 1, value1); - BOOST_CHECK_EQUAL( 4, value2); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( ! sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() ); - BOOST_CHECK_EQUAL( 2, value1); - BOOST_CHECK_EQUAL( 4, value2); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( ! sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() ); - BOOST_CHECK_EQUAL( 2, value1); - BOOST_CHECK_EQUAL( 5, value2); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( ! sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() ); - BOOST_CHECK_EQUAL( 3, value1); - BOOST_CHECK_EQUAL( 5, value2); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( ! sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() ); - BOOST_CHECK_EQUAL( 4, value1); - BOOST_CHECK_EQUAL( 5, value2); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 0), sched.size() ); - BOOST_CHECK_EQUAL( 5, value1); - BOOST_CHECK_EQUAL( 5, value2); - - BOOST_CHECK( ! sched.run() ); - BOOST_CHECK( sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 0), sched.size() ); - BOOST_CHECK_EQUAL( 5, value1); - BOOST_CHECK_EQUAL( 5, value2); -} - -boost::unit_test::test_suite * init_unit_test_suite( int, char* []) -{ - boost::unit_test::test_suite * test = - BOOST_TEST_SUITE("Boost.Tasklet: barrier test suite"); - - test->add( BOOST_TEST_CASE( & test_case_1) ); - - return test; -} diff --git a/libs/tasklet/test/test_cancel.cpp b/libs/tasklet/test/test_cancel.cpp deleted file mode 100644 index 85a48fa5..00000000 --- a/libs/tasklet/test/test_cancel.cpp +++ /dev/null @@ -1,183 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include - -#include -#include - -#include - -int value1 = 0; -int value2 = 0; -int value3 = 0; - -void fn_1() -{ - for ( int i = 0; i < 3; ++i) - { - ++value1; - boost::this_tasklet::yield(); - if ( i == 1) - boost::this_tasklet::cancel(); - } -} - -void fn_2() -{ - for ( int i = 0; i < 3; ++i) - { - ++value2; - boost::this_tasklet::yield(); - } -} - -void fn_3( boost::tasklet f) -{ - for ( int i = 0; i < 3; ++i) - { - ++value3; - if ( i == 1) f.cancel(); - boost::this_tasklet::yield(); - } -} - -void test_case_1() -{ - value1 = 0; - value2 = 0; - - boost::tasklets::scheduler<> sched; - - sched.submit_tasklet( - boost::tasklet( - fn_1, boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - sched.submit_tasklet( - boost::tasklet( - fn_2, boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - - BOOST_CHECK_EQUAL( 0, value1); - BOOST_CHECK_EQUAL( 0, value2); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( ! sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() ); - BOOST_CHECK_EQUAL( 1, value1); - BOOST_CHECK_EQUAL( 0, value2); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( ! sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() ); - BOOST_CHECK_EQUAL( 1, value1); - BOOST_CHECK_EQUAL( 1, value2); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( ! sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() ); - BOOST_CHECK_EQUAL( 2, value1); - BOOST_CHECK_EQUAL( 1, value2); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( ! sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() ); - BOOST_CHECK_EQUAL( 2, value1); - BOOST_CHECK_EQUAL( 2, value2); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( ! sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() ); - BOOST_CHECK_EQUAL( 2, value1); - BOOST_CHECK_EQUAL( 2, value2); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( ! sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() ); - BOOST_CHECK_EQUAL( 2, value1); - BOOST_CHECK_EQUAL( 3, value2); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 0), sched.size() ); - BOOST_CHECK_EQUAL( 2, value1); - BOOST_CHECK_EQUAL( 3, value2); - - BOOST_CHECK( ! sched.run() ); - BOOST_CHECK( sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 0), sched.size() ); - BOOST_CHECK_EQUAL( 2, value1); - BOOST_CHECK_EQUAL( 3, value2); -} - -void test_case_2() -{ - value2 = 0; - value3 = 0; - - boost::tasklets::scheduler<> sched; - - boost::tasklet f( fn_2, boost::tasklet::default_stacksize, boost::protected_stack_allocator()); - sched.submit_tasklet( f); - sched.submit_tasklet( - boost::tasklet( - fn_3, f, boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - - BOOST_CHECK_EQUAL( 0, value2); - BOOST_CHECK_EQUAL( 0, value3); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( ! sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() ); - BOOST_CHECK_EQUAL( 1, value2); - BOOST_CHECK_EQUAL( 0, value3); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( ! sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() ); - BOOST_CHECK_EQUAL( 1, value2); - BOOST_CHECK_EQUAL( 1, value3); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( ! sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() ); - BOOST_CHECK_EQUAL( 2, value2); - BOOST_CHECK_EQUAL( 1, value3); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( ! sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() ); - BOOST_CHECK_EQUAL( 2, value2); - BOOST_CHECK_EQUAL( 2, value3); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( ! sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() ); - BOOST_CHECK_EQUAL( 2, value2); - BOOST_CHECK_EQUAL( 3, value3); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 0), sched.size() ); - BOOST_CHECK_EQUAL( 2, value2); - BOOST_CHECK_EQUAL( 3, value3); - - BOOST_CHECK( ! sched.run() ); - BOOST_CHECK( sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 0), sched.size() ); - BOOST_CHECK_EQUAL( 2, value2); - BOOST_CHECK_EQUAL( 3, value3); -} - -boost::unit_test::test_suite * init_unit_test_suite( int, char* []) -{ - boost::unit_test::test_suite * test = - BOOST_TEST_SUITE("Boost.Tasklet: cancel test suite"); - - test->add( BOOST_TEST_CASE( & test_case_1) ); - test->add( BOOST_TEST_CASE( & test_case_2) ); - - return test; -} diff --git a/libs/tasklet/test/test_condition.cpp b/libs/tasklet/test/test_condition.cpp deleted file mode 100644 index b6f7f38e..00000000 --- a/libs/tasklet/test/test_condition.cpp +++ /dev/null @@ -1,261 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include - -int value = 0; - -void notify_one_fn( boost::tasklets::condition & cond) -{ - cond.notify_one(); -} - -void notify_all_fn( boost::tasklets::condition & cond) -{ - cond.notify_all(); -} - -void wait_fn( - boost::tasklets::mutex & mtx, - boost::tasklets::condition & cond) -{ - boost::tasklets::mutex::scoped_lock lk( mtx); - cond.wait( lk); - ++value; -} - -void test_case_1() -{ - value = 0; - boost::tasklets::scheduler<> sched; - boost::tasklets::mutex mtx; - boost::tasklets::condition cond; - - sched.submit_tasklet( - boost::tasklet( - wait_fn, - boost::ref( mtx), - boost::ref( cond), - boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() ); - BOOST_CHECK_EQUAL( 0, value); - - BOOST_CHECK( ! sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() ); - BOOST_CHECK_EQUAL( 0, value); - - BOOST_CHECK( ! sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() ); - BOOST_CHECK_EQUAL( 0, value); - - sched.submit_tasklet( - boost::tasklet( - notify_one_fn, - boost::ref( cond), - boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - - BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() ); - BOOST_CHECK_EQUAL( 0, value); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() ); - BOOST_CHECK_EQUAL( 0, value); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 0), sched.size() ); - BOOST_CHECK_EQUAL( 1, value); - - BOOST_CHECK( ! sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 0), sched.size() ); - BOOST_CHECK_EQUAL( 1, value); -} - -void test_case_2() -{ - value = 0; - boost::tasklets::scheduler<> sched; - boost::tasklets::mutex mtx; - boost::tasklets::condition cond; - - sched.submit_tasklet( - boost::tasklet( - wait_fn, - boost::ref( mtx), - boost::ref( cond), - boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - - sched.submit_tasklet( - boost::tasklet( - wait_fn, - boost::ref( mtx), - boost::ref( cond), - boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() ); - BOOST_CHECK_EQUAL( 0, value); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() ); - BOOST_CHECK_EQUAL( 0, value); - - BOOST_CHECK( ! sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() ); - BOOST_CHECK_EQUAL( 0, value); - - sched.submit_tasklet( - boost::tasklet( - notify_one_fn, - boost::ref( cond), - boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - - BOOST_CHECK_EQUAL( std::size_t( 3), sched.size() ); - BOOST_CHECK_EQUAL( 0, value); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() ); - BOOST_CHECK_EQUAL( 1, value); - - BOOST_CHECK( ! sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() ); - BOOST_CHECK_EQUAL( 1, value); - - sched.submit_tasklet( - boost::tasklet( - notify_one_fn, - boost::ref( cond), - boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() ); - BOOST_CHECK_EQUAL( 1, value); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 0), sched.size() ); - BOOST_CHECK_EQUAL( 2, value); - - BOOST_CHECK( ! sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 0), sched.size() ); - BOOST_CHECK_EQUAL( 2, value); -} - -void test_case_3() -{ - value = 0; - boost::tasklets::scheduler<> sched; - boost::tasklets::mutex mtx; - boost::tasklets::condition cond; - - sched.submit_tasklet( - boost::tasklet( - wait_fn, - boost::ref( mtx), - boost::ref( cond), - boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - - sched.submit_tasklet( - boost::tasklet( - wait_fn, - boost::ref( mtx), - boost::ref( cond), - boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() ); - BOOST_CHECK_EQUAL( 0, value); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() ); - BOOST_CHECK_EQUAL( 0, value); - - BOOST_CHECK( ! sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() ); - BOOST_CHECK_EQUAL( 0, value); - - sched.submit_tasklet( - boost::tasklet( - notify_all_fn, - boost::ref( cond), - boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - - BOOST_CHECK_EQUAL( std::size_t( 3), sched.size() ); - BOOST_CHECK_EQUAL( 0, value); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() ); - BOOST_CHECK_EQUAL( 1, value); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 0), sched.size() ); - BOOST_CHECK_EQUAL( 2, value); - - BOOST_CHECK( ! sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 0), sched.size() ); - BOOST_CHECK_EQUAL( 2, value); - - sched.submit_tasklet( - boost::tasklet( - wait_fn, - boost::ref( mtx), - boost::ref( cond), - boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() ); - BOOST_CHECK_EQUAL( 2, value); - - BOOST_CHECK( ! sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() ); - BOOST_CHECK_EQUAL( 2, value); - - BOOST_CHECK( ! sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() ); - BOOST_CHECK_EQUAL( 2, value); - - sched.submit_tasklet( - boost::tasklet( - notify_all_fn, - boost::ref( cond), - boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 0), sched.size() ); - BOOST_CHECK_EQUAL( 3, value); - - BOOST_CHECK( ! sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 0), sched.size() ); - BOOST_CHECK_EQUAL( 3, value); -} - -boost::unit_test::test_suite * init_unit_test_suite( int, char* []) -{ - boost::unit_test::test_suite * test = - BOOST_TEST_SUITE("Boost.Tasklet: condition test suite"); - - test->add( BOOST_TEST_CASE( & test_case_1) ); - test->add( BOOST_TEST_CASE( & test_case_2) ); - test->add( BOOST_TEST_CASE( & test_case_3) ); - - return test; -} diff --git a/libs/tasklet/test/test_count_down_event.cpp b/libs/tasklet/test/test_count_down_event.cpp deleted file mode 100644 index 5c679b84..00000000 --- a/libs/tasklet/test/test_count_down_event.cpp +++ /dev/null @@ -1,96 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include - -int value = 0; - -void wait_fn( boost::tasklets::count_down_event & ev) -{ - ev.wait(); - ++value; -} - -void test_case_1() -{ - unsigned int n = 3; - boost::tasklets::scheduler<> sched; - boost::tasklets::count_down_event ev( n); - - BOOST_CHECK_EQUAL( ev.initial(), n); - BOOST_CHECK_EQUAL( ev.current(), n); - - ev.set(); - BOOST_CHECK_EQUAL( ev.initial(), n); - BOOST_CHECK_EQUAL( ev.current(), 2); - - ev.set(); - BOOST_CHECK_EQUAL( ev.initial(), n); - BOOST_CHECK_EQUAL( ev.current(), 1); - - ev.set(); - BOOST_CHECK_EQUAL( ev.initial(), n); - BOOST_CHECK_EQUAL( ev.current(), 0); - - ev.set(); - BOOST_CHECK_EQUAL( ev.initial(), n); - BOOST_CHECK_EQUAL( ev.current(), 0); -} - -void test_case_2() -{ - value = 0; - unsigned int n = 3; - boost::tasklets::scheduler<> sched; - boost::tasklets::count_down_event ev( n); - - BOOST_CHECK_EQUAL( ev.initial(), n); - BOOST_CHECK_EQUAL( ev.current(), n); - - sched.submit_tasklet( - boost::tasklet( - wait_fn, - boost::ref( ev), - boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - - ev.set(); - BOOST_CHECK( sched.run() ); - BOOST_CHECK( value != 1); - - ev.set(); - BOOST_CHECK( sched.run() ); - BOOST_CHECK( value != 1); - - ev.set(); - BOOST_CHECK( sched.run() ); - BOOST_CHECK_EQUAL( ev.initial(), n); - BOOST_CHECK_EQUAL( ev.current(), 0); - BOOST_CHECK_EQUAL( 1, value); -} - -boost::unit_test::test_suite * init_unit_test_suite( int, char* []) -{ - boost::unit_test::test_suite * test = - BOOST_TEST_SUITE("Boost.Task: spin-count-down-event test suite"); - - test->add( BOOST_TEST_CASE( & test_case_1) ); - test->add( BOOST_TEST_CASE( & test_case_2) ); - - return test; -} diff --git a/libs/tasklet/test/test_generic_locks.cpp b/libs/tasklet/test/test_generic_locks.cpp deleted file mode 100644 index b75b0e13..00000000 --- a/libs/tasklet/test/test_generic_locks.cpp +++ /dev/null @@ -1,384 +0,0 @@ -// (C) Copyright 2008 Anthony Williams -// Distributed under the Boost Software License, Version 1.0. (See -// accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include - -#include - -namespace tsk = boost::task; - -void test_lock_two_uncontended() -{ - boost::tasklets::mutex m1,m2; - - boost::tasklets::mutex::scoped_lock l1(m1,boost::defer_lock), - l2(m2,boost::defer_lock); - - BOOST_CHECK(!l1.owns_lock()); - BOOST_CHECK(!l2.owns_lock()); - - boost::lock(l1,l2); - - BOOST_CHECK(l1.owns_lock()); - BOOST_CHECK(l2.owns_lock()); -} - -struct wait_data -{ - boost::tasklets::mutex m; - bool flag; - boost::tasklets::condition cond; - - wait_data(): - flag(false) - {} - - void wait() - { - boost::tasklets::mutex::scoped_lock l(m); - while(!flag) - { - cond.wait(l); - } - } - - void signal() - { - boost::tasklets::mutex::scoped_lock l(m); - flag=true; - cond.notify_all(); - } -}; - -void lock_pair(boost::tasklets::mutex* m1,boost::tasklets::mutex* m2) -{ - boost::lock(*m1,*m2); - boost::tasklets::mutex::scoped_lock l1(*m1,boost::adopt_lock), - l2(*m2,boost::adopt_lock); -} - -void test_lock_five_uncontended() -{ - boost::tasklets::mutex m1,m2,m3,m4,m5; - - boost::tasklets::mutex::scoped_lock l1(m1,boost::defer_lock), - l2(m2,boost::defer_lock), - l3(m3,boost::defer_lock), - l4(m4,boost::defer_lock), - l5(m5,boost::defer_lock); - - BOOST_CHECK(!l1.owns_lock()); - BOOST_CHECK(!l2.owns_lock()); - BOOST_CHECK(!l3.owns_lock()); - BOOST_CHECK(!l4.owns_lock()); - BOOST_CHECK(!l5.owns_lock()); - - boost::lock(l1,l2,l3,l4,l5); - - BOOST_CHECK(l1.owns_lock()); - BOOST_CHECK(l2.owns_lock()); - BOOST_CHECK(l3.owns_lock()); - BOOST_CHECK(l4.owns_lock()); - BOOST_CHECK(l5.owns_lock()); -} - -void lock_five(boost::tasklets::mutex* m1,boost::tasklets::mutex* m2,boost::tasklets::mutex* m3,boost::tasklets::mutex* m4,boost::tasklets::mutex* m5) -{ - boost::lock(*m1,*m2,*m3,*m4,*m5); - m1->unlock(); - m2->unlock(); - m3->unlock(); - m4->unlock(); - m5->unlock(); -} - -void lock_n(boost::tasklets::mutex* mutexes,unsigned count) -{ - boost::lock(mutexes,mutexes+count); - for(unsigned i=0;i - struct is_mutex_type - { - BOOST_STATIC_CONSTANT(bool, value = true); - }; -} - - - -void test_lock_five_in_range() -{ - unsigned const num_mutexes=5; - dummy_mutex mutexes[num_mutexes]; - - boost::lock(mutexes,mutexes+num_mutexes); - - for(unsigned i=0;i l1(m1,boost::defer_lock), - l2(m2,boost::defer_lock); - - int const res=boost::try_lock(l1,l2); - - BOOST_CHECK(res==0); - BOOST_CHECK(m1.is_locked); - BOOST_CHECK(!m2.is_locked); - BOOST_CHECK(!l1.owns_lock()); - BOOST_CHECK(!l2.owns_lock()); -} -void test_try_lock_two_second_locked() -{ - dummy_mutex m1,m2; - m2.lock(); - - boost::unique_lock l1(m1,boost::defer_lock), - l2(m2,boost::defer_lock); - - int const res=boost::try_lock(l1,l2); - - BOOST_CHECK(res==1); - BOOST_CHECK(!m1.is_locked); - BOOST_CHECK(m2.is_locked); - BOOST_CHECK(!l1.owns_lock()); - BOOST_CHECK(!l2.owns_lock()); -} - -void test_try_lock_three() -{ - int const num_mutexes=3; - - for(int i=-1;i=0) - { - mutexes[i].lock(); - } - boost::unique_lock l1(mutexes[0],boost::defer_lock), - l2(mutexes[1],boost::defer_lock), - l3(mutexes[2],boost::defer_lock); - - int const res=boost::try_lock(l1,l2,l3); - - BOOST_CHECK(res==i); - for(int j=0;j=0) - { - mutexes[i].lock(); - } - boost::unique_lock l1(mutexes[0],boost::defer_lock), - l2(mutexes[1],boost::defer_lock), - l3(mutexes[2],boost::defer_lock), - l4(mutexes[3],boost::defer_lock); - - int const res=boost::try_lock(l1,l2,l3,l4); - - BOOST_CHECK(res==i); - for(int j=0;j=0) - { - mutexes[i].lock(); - } - boost::unique_lock l1(mutexes[0],boost::defer_lock), - l2(mutexes[1],boost::defer_lock), - l3(mutexes[2],boost::defer_lock), - l4(mutexes[3],boost::defer_lock), - l5(mutexes[4],boost::defer_lock); - - int const res=boost::try_lock(l1,l2,l3,l4,l5); - - BOOST_CHECK(res==i); - for(int j=0;jadd(BOOST_TEST_CASE(&test_lock_two_uncontended)); - test->add(BOOST_TEST_CASE(&test_lock_two_other_thread_locks_in_order)); - test->add(BOOST_TEST_CASE(&test_lock_two_other_thread_locks_in_opposite_order)); - test->add(BOOST_TEST_CASE(&test_lock_five_uncontended)); - test->add(BOOST_TEST_CASE(&test_lock_five_other_thread_locks_in_order)); - test->add(BOOST_TEST_CASE(&test_lock_five_other_thread_locks_in_different_order)); - test->add(BOOST_TEST_CASE(&test_lock_five_in_range)); - test->add(BOOST_TEST_CASE(&test_lock_ten_in_range)); - test->add(BOOST_TEST_CASE(&test_lock_ten_other_thread_locks_in_different_order)); - test->add(BOOST_TEST_CASE(&test_try_lock_two_uncontended)); - test->add(BOOST_TEST_CASE(&test_try_lock_two_first_locked)); - test->add(BOOST_TEST_CASE(&test_try_lock_two_second_locked)); - test->add(BOOST_TEST_CASE(&test_try_lock_three)); - test->add(BOOST_TEST_CASE(&test_try_lock_four)); - test->add(BOOST_TEST_CASE(&test_try_lock_five)); - - return test; -} diff --git a/libs/tasklet/test/test_interrupt.cpp b/libs/tasklet/test/test_interrupt.cpp deleted file mode 100644 index 228deed7..00000000 --- a/libs/tasklet/test/test_interrupt.cpp +++ /dev/null @@ -1,248 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include -#include - -#include -#include - -#include - -int value1 = 0; -int value2 = 0; -bool interrupted = false; - -void fn_1() -{ - try - { - for ( int i = 0; i < 5; ++i) - { - ++value1; - boost::this_tasklet::interruption_point(); - boost::this_tasklet::yield(); - } - } - catch ( boost::tasklets::tasklet_interrupted const&) - { interrupted = true; } -} - -void fn_2() -{ - boost::this_tasklet::disable_interruption disabler; - if ( boost::this_tasklet::interruption_enabled() ) - throw std::logic_error("interruption enabled"); - for ( int i = 0; i < 5; ++i) - { - ++value1; - boost::this_tasklet::interruption_point(); - boost::this_tasklet::yield(); - } -} - -void fn_3() -{ - try - { - boost::this_tasklet::disable_interruption disabler; - if ( boost::this_tasklet::interruption_enabled() ) - throw std::logic_error("interruption enabled"); - for ( int i = 0; i < 5; ++i) - { - ++value1; - boost::this_tasklet::restore_interruption restorer( disabler); - boost::this_tasklet::interruption_point(); - boost::this_tasklet::yield(); - } - } - catch ( boost::tasklets::tasklet_interrupted const&) - { interrupted = true; } -} - -void fn_5( boost::tasklet f) -{ - for ( int i = 0; i < 5; ++i) - { - ++value2; - if ( i == 1) f.interrupt(); - if ( i >= 1) - { - if ( ! f.interruption_requested() ) - throw std::logic_error(""); - } - boost::this_tasklet::yield(); - } -} - -void test_case_1() -{ - value1 = 0; - value2 = 0; - interrupted = false; - - boost::tasklets::scheduler<> sched; - - boost::tasklet f( fn_1, boost::tasklet::default_stacksize, boost::protected_stack_allocator()); - sched.submit_tasklet( f); - sched.submit_tasklet( - boost::tasklet( - fn_5, f, boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - - BOOST_CHECK_EQUAL( 0, value1); - BOOST_CHECK_EQUAL( 0, value2); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( ! sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() ); - BOOST_CHECK_EQUAL( false, interrupted); - BOOST_CHECK_EQUAL( 1, value1); - BOOST_CHECK_EQUAL( 0, value2); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( ! sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() ); - BOOST_CHECK_EQUAL( false, interrupted); - BOOST_CHECK_EQUAL( 1, value1); - BOOST_CHECK_EQUAL( 1, value2); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( ! sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() ); - BOOST_CHECK_EQUAL( false, interrupted); - BOOST_CHECK_EQUAL( 2, value1); - BOOST_CHECK_EQUAL( 1, value2); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( ! sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() ); - BOOST_CHECK_EQUAL( false, interrupted); - BOOST_CHECK_EQUAL( 2, value1); - BOOST_CHECK_EQUAL( 2, value2); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( ! sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() ); - BOOST_CHECK_EQUAL( true, interrupted); - BOOST_CHECK_EQUAL( 3, value1); - BOOST_CHECK_EQUAL( 2, value2); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( ! sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() ); - BOOST_CHECK_EQUAL( true, interrupted); - BOOST_CHECK_EQUAL( 3, value1); - BOOST_CHECK_EQUAL( 3, value2); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( ! sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() ); - BOOST_CHECK_EQUAL( true, interrupted); - BOOST_CHECK_EQUAL( 3, value1); - BOOST_CHECK_EQUAL( 4, value2); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( ! sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() ); - BOOST_CHECK_EQUAL( true, interrupted); - BOOST_CHECK_EQUAL( 3, value1); - BOOST_CHECK_EQUAL( 5, value2); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 0), sched.size() ); - BOOST_CHECK_EQUAL( true, interrupted); - BOOST_CHECK_EQUAL( 3, value1); - BOOST_CHECK_EQUAL( 5, value2); - - BOOST_CHECK( ! sched.run() ); - BOOST_CHECK( sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 0), sched.size() ); - BOOST_CHECK_EQUAL( true, interrupted); - BOOST_CHECK_EQUAL( 3, value1); - BOOST_CHECK_EQUAL( 5, value2); -} - -void test_case_2() -{ - value1 = 0; - value2 = 0; - interrupted = false; - - boost::tasklets::scheduler<> sched; - - boost::tasklet f( fn_2, boost::tasklet::default_stacksize, boost::protected_stack_allocator()); - sched.submit_tasklet( f); - sched.submit_tasklet( - boost::tasklet( - fn_5, f, boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - - BOOST_CHECK_EQUAL( 0, value1); - BOOST_CHECK_EQUAL( 0, value2); - BOOST_CHECK_EQUAL( false, interrupted); - BOOST_CHECK( ! sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() ); - - for (;;) - { - while ( sched.run() ); - if ( sched.empty() ) break; - } - - BOOST_CHECK( ! sched.run() ); - BOOST_CHECK( sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 0), sched.size() ); - BOOST_CHECK_EQUAL( 5, value1); - BOOST_CHECK_EQUAL( 5, value2); - BOOST_CHECK_EQUAL( false, interrupted); -} - -void test_case_3() -{ - value1 = 0; - value2 = 0; - interrupted = false; - - boost::tasklets::scheduler<> sched; - - boost::tasklet f( fn_3, boost::tasklet::default_stacksize, boost::protected_stack_allocator()); - sched.submit_tasklet( f); - sched.submit_tasklet( - boost::tasklet( - fn_5, f, boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - - BOOST_CHECK_EQUAL( 0, value1); - BOOST_CHECK_EQUAL( 0, value2); - BOOST_CHECK_EQUAL( false, interrupted); - BOOST_CHECK( ! sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() ); - - for (;;) - { - while ( sched.run() ); - if ( sched.empty() ) break; - } - - BOOST_CHECK( ! sched.run() ); - BOOST_CHECK( sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 0), sched.size() ); - BOOST_CHECK_EQUAL( 3, value1); - BOOST_CHECK_EQUAL( 5, value2); - BOOST_CHECK_EQUAL( true, interrupted); -} - -boost::unit_test::test_suite * init_unit_test_suite( int, char* []) -{ - boost::unit_test::test_suite * test = - BOOST_TEST_SUITE("Boost.Tasklet: interrupt test suite"); - - test->add( BOOST_TEST_CASE( & test_case_1) ); - test->add( BOOST_TEST_CASE( & test_case_2) ); - test->add( BOOST_TEST_CASE( & test_case_3) ); - - return test; -} diff --git a/libs/tasklet/test/test_join.cpp b/libs/tasklet/test/test_join.cpp deleted file mode 100644 index 8d7ae1c4..00000000 --- a/libs/tasklet/test/test_join.cpp +++ /dev/null @@ -1,362 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include - -#include -#include - -#include - -int value1 = 0; -int value2 = 0; -int value3 = 0; -bool interrupted = false; - -void fn_1() -{ - for ( int i = 0; i < 5; ++i) - { - ++value1; - boost::this_tasklet::yield(); - } -} - -void fn_2( boost::tasklet f) -{ - try - { - for ( int i = 0; i < 5; ++i) - { - ++value2; - if ( i == 1) f.join(); - boost::this_tasklet::yield(); - } - } - catch ( boost::tasklets::tasklet_interrupted const&) - { interrupted = true; } -} - -void fn_3( boost::tasklet f) -{ - for ( int i = 0; i < 5; ++i) - { - ++value3; - if ( i == 3) f.cancel(); - boost::this_tasklet::yield(); - } -} - -void fn_4( boost::tasklet f) -{ - for ( int i = 0; i < 5; ++i) - { - ++value3; - if ( i == 3) f.interrupt(); - boost::this_tasklet::yield(); - } -} - -void test_case_1() -{ - value1 = 0; - value2 = 0; - - boost::tasklets::scheduler<> sched; - - boost::tasklet f( fn_1, boost::tasklet::default_stacksize, boost::protected_stack_allocator()); - sched.submit_tasklet( f); - sched.submit_tasklet( - boost::tasklet( - fn_2, f, boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - - BOOST_CHECK_EQUAL( 0, value1); - BOOST_CHECK_EQUAL( 0, value2); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( ! sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() ); - BOOST_CHECK_EQUAL( 1, value1); - BOOST_CHECK_EQUAL( 0, value2); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( ! sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() ); - BOOST_CHECK_EQUAL( 1, value1); - BOOST_CHECK_EQUAL( 1, value2); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( ! sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() ); - BOOST_CHECK_EQUAL( 2, value1); - BOOST_CHECK_EQUAL( 1, value2); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( ! sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() ); - BOOST_CHECK_EQUAL( 2, value1); - BOOST_CHECK_EQUAL( 2, value2); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( ! sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() ); - BOOST_CHECK_EQUAL( 3, value1); - BOOST_CHECK_EQUAL( 2, value2); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( ! sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() ); - BOOST_CHECK_EQUAL( 4, value1); - BOOST_CHECK_EQUAL( 2, value2); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( ! sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() ); - BOOST_CHECK_EQUAL( 5, value1); - BOOST_CHECK_EQUAL( 2, value2); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( ! sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() ); - BOOST_CHECK_EQUAL( 5, value1); - BOOST_CHECK_EQUAL( 2, value2); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( ! sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() ); - BOOST_CHECK_EQUAL( 5, value1); - BOOST_CHECK_EQUAL( 2, value2); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( ! sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() ); - BOOST_CHECK_EQUAL( 5, value1); - BOOST_CHECK_EQUAL( 3, value2); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( ! sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() ); - BOOST_CHECK_EQUAL( 5, value1); - BOOST_CHECK_EQUAL( 4, value2); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( ! sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() ); - BOOST_CHECK_EQUAL( 5, value1); - BOOST_CHECK_EQUAL( 5, value2); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 0), sched.size() ); - BOOST_CHECK_EQUAL( 5, value1); - BOOST_CHECK_EQUAL( 5, value2); - - BOOST_CHECK( ! sched.run() ); - BOOST_CHECK( sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 0), sched.size() ); - BOOST_CHECK_EQUAL( 5, value1); - BOOST_CHECK_EQUAL( 5, value2); -} - -void test_case_2() -{ - value1 = 0; - value2 = 0; - value3 = 0; - - boost::tasklets::scheduler<> sched; - - boost::tasklet f( fn_1, boost::tasklet::default_stacksize, boost::protected_stack_allocator()); - sched.submit_tasklet( f); - sched.submit_tasklet( - boost::tasklet( - fn_2, f, boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - sched.submit_tasklet( - boost::tasklet( - fn_3, f, boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - - BOOST_CHECK_EQUAL( 0, value1); - BOOST_CHECK_EQUAL( 0, value2); - BOOST_CHECK_EQUAL( 0, value3); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( ! sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 3), sched.size() ); - BOOST_CHECK_EQUAL( 1, value1); - BOOST_CHECK_EQUAL( 0, value2); - BOOST_CHECK_EQUAL( 0, value3); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( ! sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 3), sched.size() ); - BOOST_CHECK_EQUAL( 1, value1); - BOOST_CHECK_EQUAL( 1, value2); - BOOST_CHECK_EQUAL( 0, value3); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( ! sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 3), sched.size() ); - BOOST_CHECK_EQUAL( 1, value1); - BOOST_CHECK_EQUAL( 1, value2); - BOOST_CHECK_EQUAL( 1, value3); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( ! sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 3), sched.size() ); - BOOST_CHECK_EQUAL( 2, value1); - BOOST_CHECK_EQUAL( 1, value2); - BOOST_CHECK_EQUAL( 1, value3); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( ! sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 3), sched.size() ); - BOOST_CHECK_EQUAL( 2, value1); - BOOST_CHECK_EQUAL( 2, value2); - BOOST_CHECK_EQUAL( 1, value3); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( ! sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 3), sched.size() ); - BOOST_CHECK_EQUAL( 2, value1); - BOOST_CHECK_EQUAL( 2, value2); - BOOST_CHECK_EQUAL( 2, value3); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( ! sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 3), sched.size() ); - BOOST_CHECK_EQUAL( 3, value1); - BOOST_CHECK_EQUAL( 2, value2); - BOOST_CHECK_EQUAL( 2, value3); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( ! sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 3), sched.size() ); - BOOST_CHECK_EQUAL( 3, value1); - BOOST_CHECK_EQUAL( 2, value2); - BOOST_CHECK_EQUAL( 3, value3); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( ! sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 3), sched.size() ); - BOOST_CHECK_EQUAL( 4, value1); - BOOST_CHECK_EQUAL( 2, value2); - BOOST_CHECK_EQUAL( 3, value3); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( ! sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() ); - BOOST_CHECK_EQUAL( 4, value1); - BOOST_CHECK_EQUAL( 2, value2); - BOOST_CHECK_EQUAL( 4, value3); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( ! sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() ); - BOOST_CHECK_EQUAL( 4, value1); - BOOST_CHECK_EQUAL( 2, value2); - BOOST_CHECK_EQUAL( 4, value3); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( ! sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() ); - BOOST_CHECK_EQUAL( 4, value1); - BOOST_CHECK_EQUAL( 2, value2); - BOOST_CHECK_EQUAL( 5, value3); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( ! sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() ); - BOOST_CHECK_EQUAL( 4, value1); - BOOST_CHECK_EQUAL( 3, value2); - BOOST_CHECK_EQUAL( 5, value3); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( ! sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() ); - BOOST_CHECK_EQUAL( 4, value1); - BOOST_CHECK_EQUAL( 3, value2); - BOOST_CHECK_EQUAL( 5, value3); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( ! sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() ); - BOOST_CHECK_EQUAL( 4, value1); - BOOST_CHECK_EQUAL( 4, value2); - BOOST_CHECK_EQUAL( 5, value3); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( ! sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() ); - BOOST_CHECK_EQUAL( 4, value1); - BOOST_CHECK_EQUAL( 5, value2); - BOOST_CHECK_EQUAL( 5, value3); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 0), sched.size() ); - BOOST_CHECK_EQUAL( 4, value1); - BOOST_CHECK_EQUAL( 5, value2); - BOOST_CHECK_EQUAL( 5, value3); - - BOOST_CHECK( ! sched.run() ); - BOOST_CHECK( sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 0), sched.size() ); - BOOST_CHECK_EQUAL( 4, value1); - BOOST_CHECK_EQUAL( 5, value2); - BOOST_CHECK_EQUAL( 5, value3); -} - -void test_case_3() -{ - value1 = 0; - value2 = 0; - value3 = 0; - - boost::tasklets::scheduler<> sched; - - boost::tasklet f1( fn_1, boost::tasklet::default_stacksize, boost::protected_stack_allocator()); - sched.submit_tasklet( f1); - boost::tasklet f2( fn_2, f1, boost::tasklet::default_stacksize, boost::protected_stack_allocator()); - sched.submit_tasklet( f2); - sched.submit_tasklet( - boost::tasklet( - fn_4, f2, boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - - BOOST_CHECK( ! sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 3), sched.size() ); - - BOOST_CHECK_EQUAL( 0, value1); - BOOST_CHECK_EQUAL( 0, value2); - BOOST_CHECK_EQUAL( 0, value3); - BOOST_CHECK_EQUAL( false, interrupted); - - for (;;) - { - while ( sched.run() ); - if ( sched.empty() ) break; - } - - BOOST_CHECK( ! sched.run() ); - BOOST_CHECK( sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 0), sched.size() ); - BOOST_CHECK_EQUAL( 5, value1); - BOOST_CHECK_EQUAL( 2, value2); - BOOST_CHECK_EQUAL( 5, value3); - BOOST_CHECK_EQUAL( true, interrupted); -} - -boost::unit_test::test_suite * init_unit_test_suite( int, char* []) -{ - boost::unit_test::test_suite * test = - BOOST_TEST_SUITE("Boost.Tasklet: join test suite"); - - test->add( BOOST_TEST_CASE( & test_case_1) ); - test->add( BOOST_TEST_CASE( & test_case_2) ); - test->add( BOOST_TEST_CASE( & test_case_3) ); - - return test; -} diff --git a/libs/tasklet/test/test_lock.cpp b/libs/tasklet/test/test_lock.cpp deleted file mode 100644 index 60c4aa2f..00000000 --- a/libs/tasklet/test/test_lock.cpp +++ /dev/null @@ -1,209 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) -// -// This test is based on the tests of Boost.Thread - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include - -struct dummy_mutex -{ - bool is_locked; - - dummy_mutex() : - is_locked( false) - {} - - void lock() - { is_locked = true; } - - bool try_lock() - { - if ( is_locked) - return false; - is_locked = true; - return true; - } - - void unlock() - { is_locked = false; } -}; - -void test_lock() -{ - boost::tasklets::scheduler<> sched; - boost::tasklets::mutex mtx; - boost::unique_lock< boost::tasklets::mutex > lk( mtx); - - BOOST_CHECK( lk); - BOOST_CHECK( lk.owns_lock() ); - - lk.unlock(); - - BOOST_CHECK( ! lk); - BOOST_CHECK( ! lk.owns_lock() ); -} - -void test_defer_lock() -{ - boost::tasklets::scheduler<> sched; - boost::tasklets::mutex mtx; - boost::unique_lock< boost::tasklets::mutex > lk( mtx, boost::defer_lock); - - BOOST_CHECK( ! lk); - BOOST_CHECK( ! lk.owns_lock() ); - - lk.lock(); - - BOOST_CHECK( lk); - BOOST_CHECK( lk.owns_lock() ); -} - -void test_adopt_lock() -{ - boost::tasklets::scheduler<> sched; - boost::tasklets::mutex mtx; - mtx.lock(); - boost::unique_lock< boost::tasklets::mutex > lk( mtx, boost::adopt_lock); - - BOOST_CHECK( lk); - BOOST_CHECK( lk.owns_lock() ); -} - -void test_try_lock() -{ - boost::tasklets::scheduler<> sched; - boost::tasklets::mutex mtx; - boost::unique_lock< boost::tasklets::mutex > lk( mtx, boost::defer_lock); - - BOOST_CHECK( ! lk); - BOOST_CHECK( ! lk.owns_lock() ); - - lk.try_lock(); - - BOOST_CHECK( lk); - BOOST_CHECK( lk.owns_lock() ); -} - -void test_lock_twice() -{ - boost::tasklets::scheduler<> sched; - boost::tasklets::mutex mtx; - boost::unique_lock< boost::tasklets::mutex > lk( mtx); - - BOOST_CHECK_THROW( lk.lock(), boost::lock_error); -} - -void test_try_lock_twice() -{ - boost::tasklets::scheduler<> sched; - boost::tasklets::mutex mtx; - boost::unique_lock< boost::tasklets::mutex > lk( mtx); - - BOOST_CHECK_THROW( lk.try_lock(), boost::lock_error); -} - -void test_unlock_twice() -{ - boost::tasklets::scheduler<> sched; - boost::tasklets::mutex mtx; - boost::unique_lock< boost::tasklets::mutex > lk( mtx); - lk.unlock(); - - BOOST_CHECK_THROW( lk.unlock(), boost::lock_error); -} - -void test_default_ctor() -{ - boost::unique_lock< boost::tasklets::mutex > lk; - - BOOST_CHECK( ! lk); - BOOST_CHECK( ! lk.owns_lock() ); -} - -void test_lock_concept() -{ - boost::tasklets::scheduler<> sched; - boost::tasklets::mutex mtx1, mtx2, mtx3; - - boost::tasklets::mutex::scoped_lock lk1( mtx1, boost::defer_lock), - lk2( mtx2, boost::defer_lock), - lk3( mtx3, boost::defer_lock); - - BOOST_CHECK( ! lk1.owns_lock() ); - BOOST_CHECK( ! lk2.owns_lock() ); - BOOST_CHECK( ! lk3.owns_lock() ); - - boost::lock( lk1, lk2, lk3); - - BOOST_CHECK( lk1.owns_lock() ); - BOOST_CHECK( lk2.owns_lock() ); - BOOST_CHECK( lk3.owns_lock() ); -} - -void test_try_lock_concept() -{ - dummy_mutex mtx1, mtx2; - mtx2.lock(); - - boost::unique_lock< dummy_mutex > lk1( mtx1, boost::defer_lock), - lk2( mtx2, boost::defer_lock); - - int res = boost::try_lock( lk1, lk2); - - BOOST_CHECK( res == 1); - BOOST_CHECK( ! mtx1.is_locked); - BOOST_CHECK( mtx2.is_locked); - BOOST_CHECK( ! lk1.owns_lock() ); - BOOST_CHECK( ! lk2.owns_lock() ); -} - -void test_swap() -{ - boost::tasklets::scheduler<> sched; - boost::tasklets::mutex mtx1, mtx2; - - boost::unique_lock< boost::tasklets::mutex > lk1( mtx1), lk2( mtx2); - - BOOST_CHECK_EQUAL( lk1.mutex(), & mtx1); - BOOST_CHECK_EQUAL( lk2.mutex(), & mtx2); - - lk1.swap( lk2); - - BOOST_CHECK_EQUAL( lk1.mutex(), & mtx2); - BOOST_CHECK_EQUAL( lk2.mutex(), & mtx1); -} - -boost::unit_test::test_suite * init_unit_test_suite( int, char* []) -{ - boost::unit_test_framework::test_suite * test = - BOOST_TEST_SUITE("Boost.Tasklet: lock test suite"); - - test->add( BOOST_TEST_CASE( & test_lock) ); - test->add( BOOST_TEST_CASE( & test_defer_lock) ); - test->add( BOOST_TEST_CASE( & test_adopt_lock) ); - test->add( BOOST_TEST_CASE( & test_try_lock) ); - test->add( BOOST_TEST_CASE( & test_lock_twice) ); - test->add( BOOST_TEST_CASE( & test_try_lock_twice) ); - test->add( BOOST_TEST_CASE( & test_unlock_twice) ); - test->add( BOOST_TEST_CASE( & test_default_ctor) ); - test->add( BOOST_TEST_CASE( & test_lock_concept) ); - test->add( BOOST_TEST_CASE( & test_try_lock_concept) ); - test->add( BOOST_TEST_CASE( & test_swap) ); - - return test; -} diff --git a/libs/tasklet/test/test_manual_reset_event.cpp b/libs/tasklet/test/test_manual_reset_event.cpp deleted file mode 100644 index 071c219f..00000000 --- a/libs/tasklet/test/test_manual_reset_event.cpp +++ /dev/null @@ -1,170 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include - -int value = 0; - -void wait_fn( boost::tasklets::manual_reset_event & ev) -{ - ev.wait(); - ++value; -} - -void test_case_1() -{ - value = 0; - boost::tasklets::scheduler<> sched; - boost::tasklets::manual_reset_event ev; - - sched.submit_tasklet( - boost::tasklet( - wait_fn, - boost::ref( ev), - boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - - sched.submit_tasklet( - boost::tasklet( - wait_fn, - boost::ref( ev), - boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - - BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() ); - BOOST_CHECK_EQUAL( 0, value); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() ); - BOOST_CHECK_EQUAL( 0, value); - - ev.set(); - - while ( sched.run() ); - - BOOST_CHECK( ! sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 0), sched.size() ); - BOOST_CHECK_EQUAL( 2, value); -} - -void test_case_2() -{ - value = 0; - boost::tasklets::scheduler<> sched; - boost::tasklets::manual_reset_event ev; - - sched.submit_tasklet( - boost::tasklet( - wait_fn, - boost::ref( ev), - boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - - sched.submit_tasklet( - boost::tasklet( - wait_fn, - boost::ref( ev), - boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - - BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() ); - BOOST_CHECK_EQUAL( 0, value); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() ); - BOOST_CHECK_EQUAL( 0, value); - - ev.set(); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() ); - BOOST_CHECK_EQUAL( 1, value); - - ev.reset(); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() ); - BOOST_CHECK_EQUAL( 1, value); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() ); - BOOST_CHECK_EQUAL( 1, value); - - ev.set(); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( ! sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 0), sched.size() ); - BOOST_CHECK_EQUAL( 2, value); -} - -void test_case_3() -{ - value = 0; - boost::tasklets::scheduler<> sched; - boost::tasklets::manual_reset_event ev( true); - - sched.submit_tasklet( - boost::tasklet( - wait_fn, - boost::ref( ev), - boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - - sched.submit_tasklet( - boost::tasklet( - wait_fn, - boost::ref( ev), - boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - - BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() ); - BOOST_CHECK_EQUAL( 0, value); - - while ( sched.run() ); - - BOOST_CHECK( ! sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 0), sched.size() ); - BOOST_CHECK_EQUAL( 2, value); -} - -void test_case_4() -{ - boost::tasklets::scheduler<> sched; - boost::tasklets::manual_reset_event ev; - - BOOST_CHECK_EQUAL( false, ev.try_wait() ); - - ev.set(); - - BOOST_CHECK_EQUAL( true, ev.try_wait() ); - BOOST_CHECK_EQUAL( true, ev.try_wait() ); - - ev.reset(); - - BOOST_CHECK_EQUAL( false, ev.try_wait() ); -} - -boost::unit_test::test_suite * init_unit_test_suite( int, char* []) -{ - boost::unit_test::test_suite * test = - BOOST_TEST_SUITE("Boost.Tasklet: manual-reset-event test suite"); - - test->add( BOOST_TEST_CASE( & test_case_1) ); - test->add( BOOST_TEST_CASE( & test_case_2) ); - test->add( BOOST_TEST_CASE( & test_case_3) ); - test->add( BOOST_TEST_CASE( & test_case_4) ); - - return test; -} diff --git a/libs/tasklet/test/test_mutex.cpp b/libs/tasklet/test/test_mutex.cpp deleted file mode 100644 index 75c5f626..00000000 --- a/libs/tasklet/test/test_mutex.cpp +++ /dev/null @@ -1,132 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) -// -// This test is based on the tests of Boost.Thread - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include - -template< typename M > -struct test_lock -{ - typedef M mutex_type; - typedef typename M::scoped_lock lock_type; - - void operator()( boost::tasklets::scheduler<> & sched) - { - mutex_type mtx; - - // Test the lock's constructors. - { - lock_type lk(mtx, boost::defer_lock); - BOOST_CHECK(!lk); - } - lock_type lk(mtx); - BOOST_CHECK(lk ? true : false); - - // Test the lock and unlock methods. - lk.unlock(); - BOOST_CHECK(!lk); - lk.lock(); - BOOST_CHECK(lk ? true : false); - } -}; - -void do_test_mutex( boost::tasklets::scheduler<> & sched) -{ - test_lock< boost::tasklets::mutex >()( sched); -} - -void test_case1() -{ - boost::tasklets::scheduler<> sched; - sched.submit_tasklet( - boost::tasklet( - & do_test_mutex, boost::ref( sched), boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - sched.run(); -} - -int value1 = 0; -int value2 = 0; - -void test_fn1( boost::tasklets::mutex & mtx) -{ - boost::tasklets::mutex::scoped_lock lk( mtx); - ++value1; - for ( int i = 0; i < 3; ++i) - boost::this_tasklet::yield(); -} - -void test_fn2( boost::tasklets::mutex & mtx) -{ - ++value2; - boost::tasklets::mutex::scoped_lock lk( mtx); - ++value2; -} - -void test_case2() -{ - boost::tasklets::scheduler<> sched; - boost::tasklets::mutex mtx; - sched.submit_tasklet( - boost::tasklet( - & test_fn1, boost::ref( mtx), boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - sched.submit_tasklet( - boost::tasklet( - & test_fn2, boost::ref( mtx), boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - - BOOST_CHECK_EQUAL( 0, value1); - BOOST_CHECK_EQUAL( 0, value2); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() ); - BOOST_CHECK_EQUAL( 1, value1); - BOOST_CHECK_EQUAL( 0, value2); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() ); - BOOST_CHECK_EQUAL( 1, value1); - BOOST_CHECK_EQUAL( 1, value2); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( sched.run() ); - BOOST_CHECK( sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() ); - BOOST_CHECK_EQUAL( 1, value1); - BOOST_CHECK_EQUAL( 1, value2); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 0), sched.size() ); - BOOST_CHECK_EQUAL( 1, value1); - BOOST_CHECK_EQUAL( 2, value2); - - BOOST_CHECK( ! sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 0), sched.size() ); - BOOST_CHECK_EQUAL( 1, value1); - BOOST_CHECK_EQUAL( 2, value2); -} - -boost::unit_test::test_suite * init_unit_test_suite( int, char* []) -{ - boost::unit_test_framework::test_suite * test = - BOOST_TEST_SUITE("Boost.Tasklet: mutex test suite"); - - test->add(BOOST_TEST_CASE(&test_case1)); - test->add(BOOST_TEST_CASE(&test_case2)); - - return test; -} diff --git a/libs/tasklet/test/test_priority.cpp b/libs/tasklet/test/test_priority.cpp deleted file mode 100644 index 913bb657..00000000 --- a/libs/tasklet/test/test_priority.cpp +++ /dev/null @@ -1,39 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include - -#include -#include - -#include - - -void zero_args_fn() -{} - -void test_case_1() -{ - boost::tasklet f( zero_args_fn, boost::tasklet::default_stacksize, boost::protected_stack_allocator()); - BOOST_CHECK_EQUAL( 0, f.priority() ); - - f.priority( 5); - BOOST_CHECK_EQUAL( 5, f.priority() ); - - f.priority( -5); - BOOST_CHECK_EQUAL( -5, f.priority() ); -} - -boost::unit_test::test_suite * init_unit_test_suite( int, char* []) -{ - boost::unit_test::test_suite * test = - BOOST_TEST_SUITE("Boost.Tasklet: priority test suite"); - - test->add( BOOST_TEST_CASE( & test_case_1) ); - - return test; -} diff --git a/libs/tasklet/test/test_scheduler.cpp b/libs/tasklet/test/test_scheduler.cpp deleted file mode 100644 index 9b239720..00000000 --- a/libs/tasklet/test/test_scheduler.cpp +++ /dev/null @@ -1,262 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include - -#include -#include -#include - -#include - -int value1 = 0; -int value2 = 0; -int value3 = 0; - -void zero_args_fn() {} -void one_args_fn( int) {} - -void value1_fn() -{ value1 = 1; } - -void value2_fn() -{ value2 = 1; } - -void value3_fn() -{ value3 = 1; } - -void yield1_fn() -{ - for ( int i = 0; i < 5; ++i) - { - ++value1; - boost::this_tasklet::yield(); - } -} - -void yield2_fn() -{ - for ( int i = 0; i < 5; ++i) - { - ++value2; - boost::this_tasklet::yield(); - } -} - -void test_case_1() -{ - value1 = 0; - value2 = 0; - - boost::tasklets::scheduler<> sched; - - BOOST_CHECK( sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 0), sched.size() ); - BOOST_CHECK( ! sched.run() ); - - boost::tasklet f( boost::tasklet( zero_args_fn, boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - BOOST_CHECK( ! f.is_alive() ); - sched.submit_tasklet( f); - BOOST_CHECK( f.is_alive() ); - BOOST_CHECK( ! sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() ); - - sched.submit_tasklet( - boost::tasklet( zero_args_fn, boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - BOOST_CHECK( ! sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() ); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( ! sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() ); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 0), sched.size() ); - - BOOST_CHECK( ! f.is_alive() ); -} - -void test_case_2() -{ - value1 = 0; - value2 = 0; - - boost::tasklets::scheduler<> sched; - - sched.submit_tasklet( - boost::tasklet( - value1_fn, boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - sched.submit_tasklet( - boost::tasklet( - value2_fn, boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - BOOST_CHECK( ! sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() ); - BOOST_CHECK_EQUAL( 0, value1); - BOOST_CHECK_EQUAL( 0, value2); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( ! sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() ); - BOOST_CHECK_EQUAL( 1, value1); - BOOST_CHECK_EQUAL( 0, value2); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 0), sched.size() ); - BOOST_CHECK_EQUAL( 1, value1); - BOOST_CHECK_EQUAL( 1, value2); - - BOOST_CHECK( ! sched.run() ); - BOOST_CHECK( sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 0), sched.size() ); - BOOST_CHECK_EQUAL( 1, value1); - BOOST_CHECK_EQUAL( 1, value2); -} - -void test_case_3() -{ - value1 = 0; - value2 = 0; - - boost::tasklets::scheduler<> sched1, sched2; - - boost::tasklet f( & yield1_fn, boost::tasklet::default_stacksize, boost::protected_stack_allocator()); - boost::tasklet::id id = f.get_id(); - sched1.submit_tasklet( f); - sched2.submit_tasklet( - boost::tasklet( - & yield2_fn, boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - - BOOST_CHECK( ! sched1.empty() ); - BOOST_CHECK( ! sched2.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 1), sched1.size() ); - BOOST_CHECK_EQUAL( std::size_t( 1), sched2.size() ); - BOOST_CHECK_EQUAL( 0, value1); - BOOST_CHECK_EQUAL( 0, value2); - - BOOST_CHECK( sched1.run() ); - BOOST_CHECK( ! sched1.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 1), sched1.size() ); - BOOST_CHECK_EQUAL( 1, value1); - BOOST_CHECK_EQUAL( 0, value2); - - BOOST_CHECK( sched2.run() ); - BOOST_CHECK( ! sched2.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 1), sched2.size() ); - BOOST_CHECK_EQUAL( 1, value1); - BOOST_CHECK_EQUAL( 1, value2); - - BOOST_CHECK( sched1.run() ); - BOOST_CHECK( ! sched1.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 1), sched1.size() ); - BOOST_CHECK_EQUAL( 2, value1); - BOOST_CHECK_EQUAL( 1, value2); - - BOOST_CHECK( sched2.run() ); - BOOST_CHECK( ! sched2.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 1), sched2.size() ); - BOOST_CHECK_EQUAL( 2, value1); - BOOST_CHECK_EQUAL( 2, value2); - - sched2.migrate_tasklet( f); - BOOST_CHECK_EQUAL( std::size_t( 0), sched1.size() ); - BOOST_CHECK_EQUAL( std::size_t( 2), sched2.size() ); - - BOOST_CHECK( ! sched1.run() ); - BOOST_CHECK( sched1.empty() ); - - BOOST_CHECK( sched2.run() ); - BOOST_CHECK( ! sched2.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 2), sched2.size() ); - BOOST_CHECK_EQUAL( 2, value1); - BOOST_CHECK_EQUAL( 3, value2); - - BOOST_CHECK( sched2.run() ); - BOOST_CHECK( ! sched2.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 2), sched2.size() ); - BOOST_CHECK_EQUAL( 3, value1); - BOOST_CHECK_EQUAL( 3, value2); -} - -void test_case_4() -{ - value1 = 0; - value2 = 0; - - boost::tasklets::scheduler<> sched1, sched2; - - boost::tasklet f( & yield1_fn, boost::tasklet::default_stacksize, boost::protected_stack_allocator()); - boost::tasklet::id id = f.get_id(); - sched1.submit_tasklet( f); - sched2.submit_tasklet( - boost::tasklet( - & yield2_fn, boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - - BOOST_CHECK( ! sched1.empty() ); - BOOST_CHECK( ! sched2.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 1), sched1.size() ); - BOOST_CHECK_EQUAL( std::size_t( 1), sched2.size() ); - BOOST_CHECK_EQUAL( 0, value1); - BOOST_CHECK_EQUAL( 0, value2); - - BOOST_CHECK( sched1.run() ); - BOOST_CHECK( ! sched1.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 1), sched1.size() ); - BOOST_CHECK_EQUAL( 1, value1); - BOOST_CHECK_EQUAL( 0, value2); - - BOOST_CHECK( sched2.run() ); - BOOST_CHECK( ! sched2.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 1), sched2.size() ); - BOOST_CHECK_EQUAL( 1, value1); - BOOST_CHECK_EQUAL( 1, value2); - - BOOST_CHECK( sched1.run() ); - BOOST_CHECK( ! sched1.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 1), sched1.size() ); - BOOST_CHECK_EQUAL( 2, value1); - BOOST_CHECK_EQUAL( 1, value2); - - BOOST_CHECK( sched2.run() ); - BOOST_CHECK( ! sched2.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 1), sched2.size() ); - BOOST_CHECK_EQUAL( 2, value1); - BOOST_CHECK_EQUAL( 2, value2); - - sched2.migrate_tasklet( f); - BOOST_CHECK_EQUAL( std::size_t( 0), sched1.size() ); - BOOST_CHECK_EQUAL( std::size_t( 2), sched2.size() ); - - BOOST_CHECK( ! sched1.run() ); - BOOST_CHECK( sched1.empty() ); - - BOOST_CHECK( sched2.run() ); - BOOST_CHECK( ! sched2.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 2), sched2.size() ); - BOOST_CHECK_EQUAL( 2, value1); - BOOST_CHECK_EQUAL( 3, value2); - - BOOST_CHECK( sched2.run() ); - BOOST_CHECK( ! sched2.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 2), sched2.size() ); - BOOST_CHECK_EQUAL( 3, value1); - BOOST_CHECK_EQUAL( 3, value2); -} - -boost::unit_test::test_suite * init_unit_test_suite( int, char* []) -{ - boost::unit_test::test_suite * test = - BOOST_TEST_SUITE("Boost.Tasklet: scheduler test suite"); - - test->add( BOOST_TEST_CASE( & test_case_1) ); - test->add( BOOST_TEST_CASE( & test_case_2) ); - test->add( BOOST_TEST_CASE( & test_case_3) ); - test->add( BOOST_TEST_CASE( & test_case_4) ); - - return test; -} diff --git a/libs/tasklet/test/test_spin_condition.cpp b/libs/tasklet/test/test_spin_condition.cpp deleted file mode 100644 index 44d0c83d..00000000 --- a/libs/tasklet/test/test_spin_condition.cpp +++ /dev/null @@ -1,248 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include - -int value = 0; - -void notify_one_fn( boost::tasklets::spin_condition & cond) -{ - cond.notify_one(); -} - -void notify_all_fn( boost::tasklets::spin_condition & cond) -{ - cond.notify_all(); -} - -void wait_fn( - boost::tasklets::spin_mutex & mtx, - boost::tasklets::spin_condition & cond) -{ - boost::tasklets::spin_mutex::scoped_lock lk( mtx); - cond.wait( lk); - ++value; -} - -void test_case_1() -{ - value = 0; - boost::tasklets::spin_mutex mtx; - boost::tasklets::spin_condition cond; - boost::tasklets::scheduler<> sched; - - sched.submit_tasklet( - boost::tasklet( - wait_fn, - boost::ref( mtx), - boost::ref( cond), - boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() ); - BOOST_CHECK_EQUAL( 0, value); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() ); - BOOST_CHECK_EQUAL( 0, value); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() ); - BOOST_CHECK_EQUAL( 0, value); - - sched.submit_tasklet( - boost::tasklet( - notify_one_fn, - boost::ref( cond), - boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - - BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() ); - BOOST_CHECK_EQUAL( 0, value); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() ); - BOOST_CHECK_EQUAL( 0, value); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 0), sched.size() ); - BOOST_CHECK_EQUAL( 1, value); -} - -void test_case_2() -{ - value = 0; - boost::tasklets::spin_mutex mtx; - boost::tasklets::spin_condition cond; - boost::tasklets::scheduler<> sched; - - sched.submit_tasklet( - boost::tasklet( - wait_fn, - boost::ref( mtx), - boost::ref( cond), - boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - - sched.submit_tasklet( - boost::tasklet( - wait_fn, - boost::ref( mtx), - boost::ref( cond), - boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() ); - BOOST_CHECK_EQUAL( 0, value); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() ); - BOOST_CHECK_EQUAL( 0, value); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() ); - BOOST_CHECK_EQUAL( 0, value); - - sched.submit_tasklet( - boost::tasklet( - notify_one_fn, - boost::ref( cond), - boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - - BOOST_CHECK_EQUAL( std::size_t( 3), sched.size() ); - BOOST_CHECK_EQUAL( 0, value); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 3), sched.size() ); - BOOST_CHECK_EQUAL( 0, value); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() ); - BOOST_CHECK_EQUAL( 0, value); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() ); - BOOST_CHECK_EQUAL( 1, value); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() ); - BOOST_CHECK_EQUAL( 1, value); -} - -void test_case_3() -{ - value = 0; - boost::tasklets::spin_mutex mtx; - boost::tasklets::spin_condition cond; - boost::tasklets::scheduler<> sched; - - sched.submit_tasklet( - boost::tasklet( - wait_fn, - boost::ref( mtx), - boost::ref( cond), - boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - - sched.submit_tasklet( - boost::tasklet( - wait_fn, - boost::ref( mtx), - boost::ref( cond), - boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() ); - BOOST_CHECK_EQUAL( 0, value); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() ); - BOOST_CHECK_EQUAL( 0, value); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() ); - BOOST_CHECK_EQUAL( 0, value); - - sched.submit_tasklet( - boost::tasklet( - notify_all_fn, - boost::ref( cond), - boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - - BOOST_CHECK_EQUAL( std::size_t( 3), sched.size() ); - BOOST_CHECK_EQUAL( 0, value); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 3), sched.size() ); - BOOST_CHECK_EQUAL( 0, value); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() ); - BOOST_CHECK_EQUAL( 0, value); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() ); - BOOST_CHECK_EQUAL( 1, value); - - sched.submit_tasklet( - boost::tasklet( - wait_fn, - boost::ref( mtx), - boost::ref( cond), - boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() ); - BOOST_CHECK_EQUAL( 2, value); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() ); - BOOST_CHECK_EQUAL( 2, value); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() ); - BOOST_CHECK_EQUAL( 2, value); - - sched.submit_tasklet( - boost::tasklet( - notify_all_fn, - boost::ref( cond), - boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() ); - BOOST_CHECK_EQUAL( 2, value); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 0), sched.size() ); - BOOST_CHECK_EQUAL( 3, value); -} - -boost::unit_test::test_suite * init_unit_test_suite( int, char* []) -{ - boost::unit_test::test_suite * test = - BOOST_TEST_SUITE("Boost.Tasklet: spin-condition test suite"); - - test->add( BOOST_TEST_CASE( & test_case_1) ); - test->add( BOOST_TEST_CASE( & test_case_2) ); - test->add( BOOST_TEST_CASE( & test_case_3) ); - - return test; -} diff --git a/libs/tasklet/test/test_spin_mutex.cpp b/libs/tasklet/test/test_spin_mutex.cpp deleted file mode 100644 index 4c6c8c9c..00000000 --- a/libs/tasklet/test/test_spin_mutex.cpp +++ /dev/null @@ -1,131 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) -// -// This test is based on the tests of Boost.Thread - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include - -template< typename M > -struct test_lock -{ - typedef M spin_mutex_type; - typedef typename M::scoped_lock lock_type; - - void operator()() - { - spin_mutex_type spin_mutex; - boost::tasklets::spin_condition condition; - - // Test the lock's constructors. - { - lock_type lock(spin_mutex, boost::defer_lock); - BOOST_CHECK(!lock); - } - lock_type lock(spin_mutex); - BOOST_CHECK(lock ? true : false); - - // Test the lock and unlock methods. - lock.unlock(); - BOOST_CHECK(!lock); - lock.lock(); - BOOST_CHECK(lock ? true : false); - } -}; - -void do_test_spin_mutex() -{ - test_lock< boost::tasklets::spin_mutex >()(); -} - -void test_case1() -{ - boost::tasklets::scheduler<> sched; - sched.submit_tasklet( boost::tasklet( & do_test_spin_mutex, boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - sched.run(); -} - -int value1 = 0; -int value2 = 0; - -void test_fn1( boost::tasklets::spin_mutex & mtx) -{ - boost::tasklets::spin_mutex::scoped_lock lk( mtx); - ++value1; - for ( int i = 0; i < 3; ++i) - boost::this_tasklet::yield(); -} - -void test_fn2( boost::tasklets::spin_mutex & mtx) -{ - boost::tasklets::spin_mutex::scoped_lock lk( mtx); - ++value2; -} - -void test_case2() -{ - boost::tasklets::spin_mutex mtx; - boost::tasklets::scheduler<> sched; - sched.submit_tasklet( boost::tasklet( & test_fn1, boost::ref( mtx), boost::tasklet::default_stacksize, boost::protected_stack_allocator())); - sched.submit_tasklet( boost::tasklet( & test_fn2, boost::ref( mtx), boost::tasklet::default_stacksize, boost::protected_stack_allocator())); - - BOOST_CHECK_EQUAL( 0, value1); - BOOST_CHECK_EQUAL( 0, value2); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() ); - BOOST_CHECK_EQUAL( 1, value1); - BOOST_CHECK_EQUAL( 0, value2); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() ); - BOOST_CHECK_EQUAL( 1, value1); - BOOST_CHECK_EQUAL( 0, value2); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( sched.run() ); - BOOST_CHECK( sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() ); - BOOST_CHECK_EQUAL( 1, value1); - BOOST_CHECK_EQUAL( 0, value2); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() ); - BOOST_CHECK_EQUAL( 1, value1); - BOOST_CHECK_EQUAL( 0, value2); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() ); - BOOST_CHECK_EQUAL( 1, value1); - BOOST_CHECK_EQUAL( 0, value2); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK_EQUAL( std::size_t( 0), sched.size() ); - BOOST_CHECK_EQUAL( 1, value1); - BOOST_CHECK_EQUAL( 1, value2); -} - -boost::unit_test::test_suite * init_unit_test_suite( int, char* []) -{ - boost::unit_test_framework::test_suite * test = - BOOST_TEST_SUITE("Boost.Tasklet: spin-mutex test suite"); - - test->add(BOOST_TEST_CASE(&test_case1)); - test->add(BOOST_TEST_CASE(&test_case2)); - - return test; -} diff --git a/libs/tasklet/test/test_tasklet.cpp b/libs/tasklet/test/test_tasklet.cpp deleted file mode 100644 index bfe26a52..00000000 --- a/libs/tasklet/test/test_tasklet.cpp +++ /dev/null @@ -1,121 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include - -#include -#include -#include - -#include - -void zero_args_fn() -{ BOOST_ASSERT( boost::this_tasklet::runs_as_tasklet() ); } - -void one_args_fn( int) -{ BOOST_ASSERT( boost::this_tasklet::runs_as_tasklet() ); } - -void two_args_fn( int, std::string const&) -{ BOOST_ASSERT( boost::this_tasklet::runs_as_tasklet() ); } - -void test_case_1() -{ - boost::tasklet f1( one_args_fn, 10, boost::tasklet::default_stacksize, boost::protected_stack_allocator()); - boost::tasklet f2; - BOOST_CHECK( f1); - BOOST_CHECK( ! f2); - BOOST_CHECK( ! f1.is_alive() ); -} - -void test_case_2() -{ - boost::tasklet f1; - f1 = boost::tasklet( zero_args_fn, boost::tasklet::default_stacksize, boost::protected_stack_allocator()); - boost::tasklet f2( one_args_fn, 1, boost::tasklet::default_stacksize, boost::protected_stack_allocator()); - boost::tasklet f3; - f3 = boost::tasklet( two_args_fn, 1, "abc", boost::tasklet::default_stacksize, boost::protected_stack_allocator()); -} - -void test_case_3() -{ - boost::tasklet f1( & zero_args_fn, boost::tasklet::default_stacksize, boost::protected_stack_allocator()); - f1 = boost::tasklet( zero_args_fn, boost::tasklet::default_stacksize, boost::protected_stack_allocator()); - boost::tasklet f2( one_args_fn, 1, boost::tasklet::default_stacksize, boost::protected_stack_allocator()); - f2 = boost::tasklet( one_args_fn, 1, boost::tasklet::default_stacksize, boost::protected_stack_allocator()); -} - -void test_case_4() -{ - boost::tasklet f1( one_args_fn, 10, boost::tasklet::default_stacksize, boost::protected_stack_allocator()); - BOOST_CHECK( f1); - boost::tasklet f2( boost::move( f1) ); - BOOST_CHECK( ! f1); - BOOST_CHECK( f2); - boost::tasklet f3; - BOOST_CHECK( ! f3); - f3 = f2; - BOOST_CHECK( f3); - BOOST_CHECK_EQUAL( f2, f3); -} - -void test_case_5() -{ - boost::tasklet f1( zero_args_fn, boost::tasklet::default_stacksize, boost::protected_stack_allocator()); - boost::tasklet f2( zero_args_fn, boost::tasklet::default_stacksize, boost::protected_stack_allocator()); - boost::tasklet f3; - BOOST_CHECK( f1); - BOOST_CHECK( f2); - BOOST_CHECK( ! f3); - - BOOST_CHECK( f1 != f2); - BOOST_CHECK( f1 != f3); - BOOST_CHECK( f2 != f3); - - std::ostringstream os1; - os1 << f1.get_id(); - std::ostringstream os2; - os2 << f2.get_id(); - std::ostringstream os3; - os3 << f3.get_id(); - - std::string not_a_tasklet("{not-a-tasklet}"); - BOOST_CHECK( os1.str() != os2.str() ); - BOOST_CHECK( os1.str() != os3.str() ); - BOOST_CHECK( os2.str() != os3.str() ); - BOOST_CHECK( os1.str() != not_a_tasklet); - BOOST_CHECK( os2.str() != not_a_tasklet); - BOOST_CHECK( os3.str() == not_a_tasklet); -} - -void test_case_6() -{ - boost::tasklet f1( zero_args_fn, boost::tasklet::default_stacksize, boost::protected_stack_allocator()); - boost::tasklet f2( zero_args_fn, boost::tasklet::default_stacksize, boost::protected_stack_allocator()); - - boost::tasklet::id id1 = f1.get_id(); - boost::tasklet::id id2 = f2.get_id(); - - f1.swap( f2); - - BOOST_CHECK_EQUAL( f1.get_id(), id2); - BOOST_CHECK_EQUAL( f2.get_id(), id1); -} - -boost::unit_test::test_suite * init_unit_test_suite( int, char* []) -{ - boost::unit_test::test_suite * test = - BOOST_TEST_SUITE("Boost.Tasklet: tasklet test suite"); - - test->add( BOOST_TEST_CASE( & test_case_1) ); - test->add( BOOST_TEST_CASE( & test_case_2) ); - test->add( BOOST_TEST_CASE( & test_case_3) ); - test->add( BOOST_TEST_CASE( & test_case_4) ); - test->add( BOOST_TEST_CASE( & test_case_5) ); - test->add( BOOST_TEST_CASE( & test_case_6) ); - - return test; -} diff --git a/libs/tasklet/test/test_unique_lock.cpp b/libs/tasklet/test/test_unique_lock.cpp deleted file mode 100644 index ce102b97..00000000 --- a/libs/tasklet/test/test_unique_lock.cpp +++ /dev/null @@ -1,200 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) -// -// This test is based on the tests of Boost.Thread - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include - -struct dummy_mutex -{ - bool is_locked; - - dummy_mutex() : - is_locked( false) - {} - - void lock() - { is_locked = true; } - - bool try_lock() - { - if ( is_locked) - return false; - is_locked = true; - return true; - } - - void unlock() - { is_locked = false; } -}; - -void test_lock() -{ - boost::tasklets::mutex mtx; - boost::unique_lock< boost::tasklets::mutex > lk( mtx); - - BOOST_CHECK( lk); - BOOST_CHECK( lk.owns_lock() ); - - lk.unlock(); - - BOOST_CHECK( ! lk); - BOOST_CHECK( ! lk.owns_lock() ); -} - -void test_defer_lock() -{ - boost::tasklets::mutex mtx; - boost::unique_lock< boost::tasklets::mutex > lk( mtx, boost::defer_lock); - - BOOST_CHECK( ! lk); - BOOST_CHECK( ! lk.owns_lock() ); - - lk.lock(); - - BOOST_CHECK( lk); - BOOST_CHECK( lk.owns_lock() ); -} - -void test_adopt_lock() -{ - boost::tasklets::mutex mtx; - mtx.lock(); - boost::unique_lock< boost::tasklets::mutex > lk( mtx, boost::adopt_lock); - - BOOST_CHECK( lk); - BOOST_CHECK( lk.owns_lock() ); -} - -void test_try_lock() -{ - boost::tasklets::mutex mtx; - boost::unique_lock< boost::tasklets::mutex > lk( mtx, boost::defer_lock); - - BOOST_CHECK( ! lk); - BOOST_CHECK( ! lk.owns_lock() ); - - lk.try_lock(); - - BOOST_CHECK( lk); - BOOST_CHECK( lk.owns_lock() ); -} - -void test_lock_twice() -{ - boost::tasklets::mutex mtx; - boost::unique_lock< boost::tasklets::mutex > lk( mtx); - - BOOST_CHECK_THROW( lk.lock(), boost::lock_error); -} - -void test_try_lock_twice() -{ - boost::tasklets::mutex mtx; - boost::unique_lock< boost::tasklets::mutex > lk( mtx); - - BOOST_CHECK_THROW( lk.try_lock(), boost::lock_error); -} - -void test_unlock_twice() -{ - boost::tasklets::mutex mtx; - boost::unique_lock< boost::tasklets::mutex > lk( mtx); - lk.unlock(); - - BOOST_CHECK_THROW( lk.unlock(), boost::lock_error); -} - -void test_default_ctor() -{ - boost::unique_lock< boost::tasklets::mutex > lk; - - BOOST_CHECK( ! lk); - BOOST_CHECK( ! lk.owns_lock() ); -} - -void test_lock_concept() -{ - boost::tasklets::mutex mtx1, mtx2, mtx3; - - boost::tasklets::mutex::scoped_lock lk1( mtx1, boost::defer_lock), - lk2( mtx2, boost::defer_lock), - lk3( mtx3, boost::defer_lock); - - BOOST_CHECK( ! lk1.owns_lock() ); - BOOST_CHECK( ! lk2.owns_lock() ); - BOOST_CHECK( ! lk3.owns_lock() ); - - boost::lock( lk1, lk2, lk3); - - BOOST_CHECK( lk1.owns_lock() ); - BOOST_CHECK( lk2.owns_lock() ); - BOOST_CHECK( lk3.owns_lock() ); -} - -void test_try_lock_concept() -{ - dummy_mutex mtx1, mtx2; - mtx2.lock(); - - boost::unique_lock< dummy_mutex > lk1( mtx1, boost::defer_lock), - lk2( mtx2, boost::defer_lock); - - int res = boost::try_lock( lk1, lk2); - - BOOST_CHECK( res == 1); - BOOST_CHECK( ! mtx1.is_locked); - BOOST_CHECK( mtx2.is_locked); - BOOST_CHECK( ! lk1.owns_lock() ); - BOOST_CHECK( ! lk2.owns_lock() ); -} - -void test_swap() -{ - boost::tasklets::mutex mtx1, mtx2; - - boost::unique_lock< boost::tasklets::mutex > lk1( mtx1), lk2( mtx2); - - BOOST_CHECK_EQUAL( lk1.mutex(), & mtx1); - BOOST_CHECK_EQUAL( lk2.mutex(), & mtx2); - - lk1.swap( lk2); - - BOOST_CHECK_EQUAL( lk1.mutex(), & mtx2); - BOOST_CHECK_EQUAL( lk2.mutex(), & mtx1); -} - -boost::unit_test::test_suite * init_unit_test_suite( int, char* []) -{ - boost::unit_test_framework::test_suite * test = - BOOST_TEST_SUITE("Boost.Tasklet: lock test suite"); - - test->add( BOOST_TEST_CASE( & test_lock) ); - test->add( BOOST_TEST_CASE( & test_defer_lock) ); - test->add( BOOST_TEST_CASE( & test_adopt_lock) ); - test->add( BOOST_TEST_CASE( & test_try_lock) ); - test->add( BOOST_TEST_CASE( & test_lock_twice) ); - test->add( BOOST_TEST_CASE( & test_try_lock_twice) ); - test->add( BOOST_TEST_CASE( & test_unlock_twice) ); - test->add( BOOST_TEST_CASE( & test_default_ctor) ); - test->add( BOOST_TEST_CASE( & test_lock_concept) ); - test->add( BOOST_TEST_CASE( & test_try_lock_concept) ); - test->add( BOOST_TEST_CASE( & test_swap) ); - - return test; -} diff --git a/libs/tasklet/test/test_utility.cpp b/libs/tasklet/test/test_utility.cpp deleted file mode 100644 index 72184b57..00000000 --- a/libs/tasklet/test/test_utility.cpp +++ /dev/null @@ -1,158 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include -#include - -#include -#include - -#include - -bool runs_as_tasklet = false; -std::string id; -int value = 0; - -void runs_as_fn() -{ runs_as_tasklet = boost::this_tasklet::runs_as_tasklet(); } - -void get_id_fn() -{ - std::ostringstream os; - os << boost::this_tasklet::get_id(); - id = os.str(); -} - -void yield_fn( int n) -{ - for ( int i = 0; i < n; ++i) - { - ++value; - boost::this_tasklet::yield(); - } -} - -void cancel_fn( int n) -{ - if ( n < 3) throw std::invalid_argument("must be greater than 3"); - for ( int i = 0; i < n; ++i) - { - if ( i == 2) boost::this_tasklet::cancel(); - ++value; - boost::this_tasklet::yield(); - } -} - -void submit_fn( int n) -{ - boost::this_tasklet::submit_tasklet( - boost::tasklet( - & yield_fn, n, boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); -} - -void test_case_1() -{ - boost::tasklets::scheduler<> sched; - sched.submit_tasklet( - boost::tasklet( - runs_as_fn, boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - - BOOST_CHECK( sched.run() ); - - BOOST_CHECK( runs_as_tasklet); -} - -void test_case_2() -{ - boost::tasklets::scheduler<> sched; - sched.submit_tasklet( - boost::tasklet( - get_id_fn, boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - - BOOST_CHECK( sched.run() ); - - BOOST_CHECK( ! id.empty() ); - BOOST_CHECK( std::string("{not-a-tasklet}") != id); -} - -void test_case_3() -{ - value = 0; - boost::tasklets::scheduler<> sched; - sched.submit_tasklet( - boost::tasklet( - yield_fn, 3, boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - BOOST_CHECK_EQUAL( 0, value); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK_EQUAL( 1, value); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK_EQUAL( 2, value); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK_EQUAL( 3, value); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK_EQUAL( 3, value); - - BOOST_CHECK( ! sched.run() ); - BOOST_CHECK_EQUAL( 3, value); -} - -void test_case_4() -{ - value = 0; - boost::tasklets::scheduler<> sched; - sched.submit_tasklet( - boost::tasklet( - cancel_fn, 5, boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - BOOST_CHECK_EQUAL( 0, value); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK_EQUAL( 1, value); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK_EQUAL( 2, value); - - BOOST_CHECK( sched.run() ); - BOOST_CHECK( sched.empty() ); - BOOST_CHECK_EQUAL( std::size_t( 0), sched.size() ); - BOOST_CHECK( ! sched.run() ); - BOOST_CHECK_EQUAL( 2, value); -} - -void test_case_5() -{ - value = 0; - boost::tasklets::scheduler<> sched; - sched.submit_tasklet( - boost::tasklet( - submit_fn, 5, boost::tasklet::default_stacksize, boost::protected_stack_allocator()) ); - BOOST_CHECK_EQUAL( 0, value); - - for (;;) - { - while ( sched.run() ); - if ( sched.empty() ) break; - } - BOOST_CHECK_EQUAL( 5, value); -} - -boost::unit_test::test_suite * init_unit_test_suite( int, char* []) -{ - boost::unit_test::test_suite * test = - BOOST_TEST_SUITE("Boost.Tasklet: utility test suite"); - - test->add( BOOST_TEST_CASE( & test_case_1) ); - test->add( BOOST_TEST_CASE( & test_case_2) ); - test->add( BOOST_TEST_CASE( & test_case_3) ); - test->add( BOOST_TEST_CASE( & test_case_4) ); - test->add( BOOST_TEST_CASE( & test_case_5) ); - - return test; -}