Lockless Task Scheduler  v1.0a
A lockless task scheduler
guarded.h
1 // ***********************************************************************
2 // <copyright file="guarded.h" >
3 // Copyright (c) viknash. All rights reserved.
4 // </copyright>
5 // <summary></summary>
6 // ***********************************************************************
7 #pragma once
8 
9 namespace task_scheduler {
10 
11  template < typename T, class TDataStructure, class TMemInterface > class guarded : private TDataStructure
12  {
13  typedef TDataStructure super;
14 
15  public:
16  guarded(size_t _fixed_size);
17  T &operator[](size_t _index);
18  T &at(size_t _index);
19  T &front();
20  T &back();
21  void push_back(const T &_new_item);
22  void clear();
23  typename TDataStructure::size_type size() const _NOEXCEPT;
24 
25  bool is_locked();
26 
27  template < typename T, class TDataType, class TMemInterface > friend class lock_free_batch_dispatcher;
28 
29  private:
30  std::atomic_bool read_locked;
31 
32  void lock(T *&_locked_data);
33  void unlock(T *&_unlocked_data);
34  void _Reallocate(typename TDataStructure::size_type _Count);
35  };
36 
37  template < typename T, class TDataStructure, class TMemInterface >
39  : TDataStructure(_fixed_size)
40  , read_locked(false)
41  {
42 
43  }
44 
45  template < typename T, class TDataStructure, class TMemInterface >
47  {
48  bool previous_value = read_locked.exchange(true);
49  ts_assert(!previous_value); // Array has already been locked before
50  _locked_data = super::data();
51  }
52 
53  template < typename T, class TDataStructure, class TMemInterface >
55  {
56  //Array could have been resized, reserve a larger amount of elements
57  ts_assert(super::data() == _unlocked_data);
58  _unlocked_data = nullptr;
59  bool previous_value = read_locked.exchange(false);
60  ts_assert(previous_value); // Array not been locked before
61  }
62 
63  template < typename T, class TDataStructure, class TMemInterface >
65  {
66  return read_locked;
67  }
68 
69  template < typename T, class TDataStructure, class TMemInterface >
71  {
72  ts_assert(!is_locked()); // Array has been locked for reading
73  if (!is_locked())
74  {
75  super::push_back(_new_item);
76  }
77  }
78 
79  template < typename T, class TDataStructure, class TMemInterface >
81  {
82  ts_assert(!is_locked()); // Array has been locked for reading
83  if (!is_locked())
84  {
85  super::clear();
86  }
87  }
88 
89  template < typename T, class TDataStructure, class TMemInterface >
91  {
92  return at(_index);
93  }
94 
95  template < typename T, class TDataStructure, class TMemInterface >
97  {
98  ts_assert(_index < super::size()); // Index out of bounds
99  return super::data() + _index;
100  }
101 
102  template < typename T, class TDataStructure, class TMemInterface >
104  {
105  return at(0);
106  }
107 
108  template < typename T, class TDataStructure, class TMemInterface >
110  {
111  ts_assert(super::size() > 0);
112  return at(super::size() - 1);
113  }
114 
115  template < typename T, class TDataStructure, class TMemInterface >
116  void guarded< T, TDataStructure, TMemInterface >::_Reallocate(typename TDataStructure::size_type _Count)
117  {
118  ts_assert(!is_locked()); //Data structure is being resized, the lock is no longer valid
119  //Increase the initial size of the data structure
120  super::_Reallocate(_Count);
121  }
122 
123  template < typename T, class TDataStructure, class TMemInterface >
124  typename TDataStructure::size_type guarded< T, TDataStructure, TMemInterface >::size() const _NOEXCEPT
125  {
126  return super::size();
127  }
128 
129  template < typename T, class TMemInterface >
131 }
Definition: guarded.h:11
Class stl_allocator.
Definition: allocator.h:16
Class lock_free_batch_dispatcher.
Definition: lockfreebatchdispenser.h:17