medfall

A super great game engine
Log | Files | Refs

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