dyn_thread_ctx.hpp (2951B)
1 /* Relacy Race Detector 2 * Copyright (c) 2008-2013, Dmitry S. Vyukov 3 * All rights reserved. 4 * This software is provided AS-IS with no warranty, either express or implied. 5 * This software is distributed under a license and may not be copied, 6 * modified or distributed except as expressly authorized under the 7 * terms of the license contained in the file LICENSE in this distribution. 8 */ 9 10 #ifndef RL_DYN_THREAD_CTX_HPP 11 #define RL_DYN_THREAD_CTX_HPP 12 #ifdef _MSC_VER 13 # pragma once 14 #endif 15 16 17 #include "base.hpp" 18 #include "waitset.hpp" 19 #include "sync_var.hpp" 20 #include "stdlib/semaphore.hpp" 21 22 23 namespace rl 24 { 25 26 27 template<thread_id_t thread_count> 28 class thread_sync_object : public win_waitable_object 29 { 30 public: 31 thread_sync_object() 32 { 33 } 34 35 void iteration_begin() 36 { 37 finished_ = false; 38 sync_.iteration_begin(); 39 RL_VERIFY(!ws_); 40 } 41 42 void on_create() 43 { 44 sync_.release(ctx().threadx_); 45 } 46 47 void on_start() 48 { 49 RL_VERIFY(finished_ == false); 50 context& c = ctx(); 51 sync_.acquire(c.threadx_); 52 } 53 54 void on_finish() 55 { 56 RL_VERIFY(finished_ == false); 57 context& c = ctx(); 58 finished_ = true; 59 sync_.release(c.threadx_); 60 ws_.unpark_all(c, $); 61 } 62 63 private: 64 bool finished_; 65 waitset<thread_count> ws_; 66 sync_var<thread_count> sync_; 67 68 virtual void deinit(debug_info_param info) 69 { 70 (void)info; 71 } 72 73 virtual sema_wakeup_reason wait(bool try_wait, bool is_timed, debug_info_param info) 74 { 75 context& c = ctx(); 76 if (finished_) 77 { 78 sync_.acquire(c.threadx_); 79 return sema_wakeup_reason_success; 80 } 81 else if (try_wait) 82 { 83 sync_.acquire(c.threadx_); 84 return sema_wakeup_reason_failed; 85 } 86 else 87 { 88 unpark_reason reason = ws_.park_current(c, is_timed, false, false, info); 89 sync_.acquire(c.threadx_); 90 if (reason == unpark_reason_normal) 91 return sema_wakeup_reason_success; 92 else if (reason == unpark_reason_timeout) 93 return sema_wakeup_reason_timeout; 94 RL_VERIFY(false); 95 return sema_wakeup_reason_failed; 96 } 97 } 98 99 virtual bool signal(debug_info_param info) 100 { 101 RL_ASSERT_IMPL(false, test_result_thread_signal, "trying to signal a thread", info); 102 return false; 103 } 104 105 virtual bool is_signaled(debug_info_param info) 106 { 107 (void)info; 108 return finished_; 109 } 110 111 virtual void memory_acquire(debug_info_param info) 112 { 113 (void)info; 114 sync_.acquire(ctx().threadx_); 115 } 116 117 virtual void* prepare_wait(debug_info_param info) 118 { 119 (void)info; 120 return &ws_; 121 } 122 }; 123 124 125 } 126 127 #endif