scc  2022.4.0
SystemC components library
ordered_semaphore.cpp
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 #include "ordered_semaphore.h"
18 #include "report.h"
19 #include "sysc/communication/sc_communication_ids.h"
20 #include "sysc/kernel/sc_wait.h"
21 #include <util/strprintf.h>
22 
23 namespace scc {
24 
25 using namespace sc_core;
26 
27 // ----------------------------------------------------------------------------
28 // CLASS : sc_semaphore
29 //
30 // The sc_semaphore primitive channel class.
31 // ----------------------------------------------------------------------------
32 
33 // error reporting
34 namespace {
35 auto gen_unique_event_name(const char* modifier) -> std::string {
36  auto str = std::string("$$$$kernel_event$$$$_") + "_" + modifier;
37  return std::string(sc_core::sc_gen_unique_name(str.c_str(), false));
38 }
39 } // namespace
40 
42  if(typeid(*this) == typeid(ordered_semaphore)) {
43  auto diff = static_cast<int>(capacity) - static_cast<int>(c);
44  capacity = c;
45  value -= diff;
46  if(value > 0)
47  free_evt.notify(sc_core::SC_ZERO_TIME);
48  } else {
49  SCCWARN(SCMOD) << "cannot resize fixed size ordered semaphore";
50  }
51 }
52 
53 void ordered_semaphore::trace(sc_core::sc_trace_file* tf) const { sc_core::sc_trace(tf, value, name()); }
54 
55 void ordered_semaphore::report_error(const char* id, const char* add_msg) const {
56  auto msg = add_msg ? util::strprintf("semaphore '%s'", name()) : util::strprintf("%s: semaphore '%s'", add_msg, name());
57  SC_REPORT_ERROR(id, msg.c_str());
58 }
59 
60 // constructors
61 
63 : sc_core::sc_object(sc_core::sc_gen_unique_name("semaphore"))
64 , free_evt(gen_unique_event_name("free_event").c_str())
65 , value(init_value_)
66 , capacity(init_value_) {
67  if(value < 0) {
68  report_error(sc_core::SC_ID_INVALID_SEMAPHORE_VALUE_);
69  }
70 }
71 
72 ordered_semaphore::ordered_semaphore(const char* name_, unsigned init_value_, bool value_traceable)
73 : sc_object(name_)
74 , free_evt(gen_unique_event_name("free_event").c_str())
75 , value(init_value_)
76 , capacity(init_value_)
77 , value_traceable(value_traceable) {}
78 
79 // interface methods
80 
81 // lock (take) the semaphore, block if not available
82 auto ordered_semaphore::wait(unsigned priority) -> int {
83  queue.at(priority).push_back(sc_core::sc_get_current_process_handle());
84  while(in_use()) {
85  sc_core::wait(free_evt);
86  }
87  --value;
88  return value;
89 }
90 
91 // lock (take) the semaphore, return -1 if not available
92 
94  if(in_use()) {
95  return -1;
96  }
97  --value;
98  return value;
99 }
100 
101 // unlock (give) the semaphore
102 
103 auto ordered_semaphore::post() -> int {
104  if(capacity && value == capacity) {
105  SCCWARN(SCMOD) << "post() called on entirely free semaphore!";
106  } else
107  ++value;
108  if(value > 0)
109  free_evt.notify(sc_core::SC_ZERO_TIME);
110  return value;
111 }
112 
113 } // namespace scc
The ordered_semaphore primitive channel class.
void trace(sc_core::sc_trace_file *tf) const override
adds internal variables to trace
int post() override
unlock (give) the semaphore
int wait() override
lock (take) the semaphore, block if not available
void set_capacity(unsigned capacity)
change the capacity
ordered_semaphore(unsigned init_value=1)
constructor of an un-named semaphore
int trywait() override
lock (take) the semaphore, return -1 if not available
SCC SystemC utilities.
SCC common utilities.
Definition: bit_field.h:30
std::string strprintf(const std::string format,...)
allocate and print to a string buffer
Definition: strprintf.h:35