scc  2024.06
SystemC components library
ordered_semaphore.h
1 /*******************************************************************************
2  * Copyright 2019 MINRES Technologies GmbH
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *******************************************************************************/
16 
17 #pragma once
18 
19 #include "sc_variable.h"
20 #include "traceable.h"
21 #include <array>
22 #include <deque>
23 #include <sysc/communication/sc_semaphore_if.h>
24 #include <sysc/kernel/sc_event.h>
25 #include <sysc/kernel/sc_object.h>
26 #include <sysc/kernel/sc_process_handle.h>
27 
28 #ifndef SC_API
29 #define SC_API
30 #endif
31 
37 namespace scc {
45 class SC_API ordered_semaphore : public sc_core::sc_semaphore_if, public sc_core::sc_object, public scc::traceable {
46 public:
55  explicit ordered_semaphore(unsigned init_value = 1);
64  ordered_semaphore(const char* name, unsigned init_value = 1, bool value_traceable = false);
65 
66  ordered_semaphore(const ordered_semaphore&) = delete;
67 
68  ordered_semaphore& operator=(const ordered_semaphore&) = delete;
75  int wait() override { return wait(0); }
82  int wait(unsigned priority);
89  int trywait() override;
96  int post() override;
102  unsigned get_capacity() { return capacity; }
109  void set_capacity(unsigned capacity);
116  int get_value() const override { return value; }
123  const char* kind() const override { return "sc_semaphore_ordered"; }
130  void trace(sc_core::sc_trace_file* tf) const override;
137  bool is_trace_enabled() const override { return value_traceable; }
145  struct lock {
153  : sem(sem) {
154  sem.wait();
155  }
156  lock(scc::ordered_semaphore& sem, unsigned prio)
157  : sem(sem) {
158  sem.wait(prio);
159  }
165  ~lock() { release(); }
171  void release() {
172  if(owned)
173  sem.post();
174  owned = false;
175  }
176 
177  private:
179  bool owned{true};
180  };
181 
182 protected:
183  // support methods
184  bool in_use() {
185  if(value > 0) {
186  if(queue[1].size()) {
187  if(queue[1].front() == sc_core::sc_get_current_process_handle()) {
188  queue[1].pop_front();
189  return false;
190  }
191  } else {
192  if(queue[0].front() == sc_core::sc_get_current_process_handle()) {
193  queue[0].pop_front();
194  return false;
195  }
196  }
197  }
198  return true;
199  }
200 
201  // error reporting
202  void report_error(const char* id, const char* add_msg = 0) const;
203 
204 protected:
205  sc_core::sc_event free_evt; // event to block on when m_value is negative
206  int value; // current value of the semaphore
207  unsigned capacity;
208  bool value_traceable = false;
209  std::unique_ptr<scc::sc_ref_variable<int>> value_ref;
210  std::array<std::deque<sc_core::sc_process_handle>, 2> queue;
211 };
212 
213 template <unsigned CAPACITY> struct ordered_semaphore_t : public ordered_semaphore {
214  explicit ordered_semaphore_t()
215  : ordered_semaphore(CAPACITY) {}
216  ordered_semaphore_t(const char* name_)
217  : ordered_semaphore(name_, CAPACITY) {}
218 };
219 
220 } // namespace scc // end of scc-sysc
The ordered_semaphore primitive channel class.
int get_value() const override
get the value of the semaphore
unsigned get_capacity()
retrieve the initial capacity of the semaphore
int post() override
unlock (give) the semaphore
const char * kind() const override
kind of this SastemC object
bool is_trace_enabled() const override
returns of this component shall be traced
int wait() override
lock (take) the semaphore, block if not available
ordered_semaphore(unsigned init_value=1)
constructor of an un-named semaphore
interface defining a traceable component
Definition: traceable.h:32
SCC TLM utilities.
a lock for the semaphore
~lock()
destructor, unlock the semaphore if still locked
void release()
unlock the semaphore
lock(scc::ordered_semaphore &sem)
lock the given semahore, wait if not free