thread_local_ctx.hpp (3329B)
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_THREAD_LOCAL_CTX_HPP 11 #define RL_THREAD_LOCAL_CTX_HPP 12 #ifdef _MSC_VER 13 # pragma once 14 #endif 15 16 #include "base.hpp" 17 #include "test_params.hpp" 18 19 20 namespace rl 21 { 22 23 24 struct thread_local_context_iface 25 { 26 virtual int thread_local_alloc (void (*dtor)(intptr_t)) = 0; 27 virtual void thread_local_free (int index) = 0; 28 virtual void thread_local_set (int index, intptr_t value) = 0; 29 virtual intptr_t thread_local_get (int index) = 0; 30 virtual ~thread_local_context_iface () {} // to calm down g++ 31 }; 32 33 34 35 36 template<typename base_t, thread_id_t thread_count> 37 class thread_local_contxt_impl : protected base_t 38 { 39 public: 40 thread_local_contxt_impl(thread_id_t thread_count_param, test_params& params) 41 : base_t(thread_count_param, params) 42 { 43 } 44 45 void iteration_begin() 46 { 47 base_t::iteration_begin(); 48 49 for (size_t ent = 0; ent != entries_.size(); ent += 1) 50 { 51 for (size_t th = 0; th != thread_count; th += 1) 52 { 53 entries_[ent].value_[th] = 0; 54 } 55 } 56 } 57 58 private: 59 struct entry 60 { 61 bool alive_; 62 intptr_t value_ [thread_count]; 63 void (*dtor_) (intptr_t); 64 }; 65 66 typename vector<entry>::type entries_; 67 using base_t::current_thread; 68 69 virtual int thread_local_alloc (void (*dtor)(intptr_t)) 70 { 71 int index = (int)entries_.size(); 72 entries_.resize(index + 1); 73 entry& ent = entries_[index]; 74 ent.alive_ = true; 75 ent.dtor_ = dtor; 76 for (size_t i = 0; i != thread_count; ++i) 77 { 78 ent.value_[i] = 0; 79 } 80 return index; 81 } 82 83 virtual void thread_local_free (int index) 84 { 85 RL_VERIFY(index >= 0 && (size_t)index < entries_.size()); 86 entry& ent = entries_[index]; 87 RL_VERIFY(ent.alive_); 88 ent.alive_ = false; 89 if (ent.dtor_) 90 { 91 for (size_t i = 0; i != thread_count; ++i) 92 { 93 if (ent.value_[i]) 94 { 95 ent.dtor_(ent.value_[i]); 96 } 97 } 98 } 99 } 100 101 virtual void thread_local_set (int index, intptr_t value) 102 { 103 RL_VERIFY(index >= 0 && (size_t)index < entries_.size()); 104 entry& ent = entries_[index]; 105 RL_VERIFY(ent.alive_); 106 ent.value_[current_thread()] = value; 107 } 108 109 virtual intptr_t thread_local_get (int index) 110 { 111 RL_VERIFY(index >= 0 && (size_t)index < entries_.size()); 112 entry& ent = entries_[index]; 113 RL_VERIFY(ent.alive_); 114 return ent.value_[current_thread()]; 115 } 116 }; 117 118 119 120 } 121 122 #endif