medfall

A super great game engine
Log | Files | Refs

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