Choco OS  V.0.16.9.0
Join to the chocolate world
oc_semaphore.c
Go to the documentation of this file.
1 
27 #include <oc_null.h>
28 #include <oc_object.h>
29 #include <oc_semaphore.h>
30 #include <oc_threadman.h>
31 #include <oc_stdlib.h>
32 #include <oc_intman.h>
33 
39 #define _________________________________________TYPES_SECTION______________________________________________________________________________
40 
42 {
43  oC_ObjectControl_t ObjectControl;
44  oC_Semaphore_Type_t Type;
45  uint32_t Value;
46 };
47 
48 #undef _________________________________________TYPES_SECTION______________________________________________________________________________
49 
55 #define _________________________________________PROTOTYPES_SECTION_________________________________________________________________________
56 
57 #undef _________________________________________PROTOTYPES_SECTION_________________________________________________________________________
58 
64 #define _________________________________________INTERFACE_FUNCTIONS_SECTION________________________________________________________________
65 
68 //==========================================================================================================================================
69 //==========================================================================================================================================
70 oC_Semaphore_t oC_Semaphore_New( oC_Semaphore_Type_t Type , oC_Semaphore_InitialValue_t InitialValue , Allocator_t Allocator , AllocationFlags_t Flags )
71 {
72  oC_Semaphore_t semaphore = ksmartalloc( sizeof(struct Semaphore_t) , Allocator , Flags );
73 
74  if(semaphore)
75  {
76  semaphore->Type = Type;
77  semaphore->Value = InitialValue;
78  semaphore->ObjectControl = oC_CountObjectControl(semaphore,oC_ObjectId_Semaphore);
79  }
80 
81  return semaphore;
82 }
83 
84 //==========================================================================================================================================
85 //==========================================================================================================================================
86 bool oC_Semaphore_Delete( oC_Semaphore_t * Semaphore , AllocationFlags_t Flags )
87 {
88  bool deleted = false;
89 
90  if(oC_Semaphore_IsCorrect(*Semaphore))
91  {
92  oC_IntMan_EnterCriticalSection();
93  (*Semaphore)->ObjectControl = 0;
94  oC_ThreadMan_UnblockAllBlockedBy(&(*Semaphore)->Value,false);
95 
96  if(!ksmartfree(*Semaphore,sizeof(struct Semaphore_t),Flags))
97  {
98  oC_SaveError("Semaphore" , oC_ErrorCode_ReleaseError);
99  }
100  else
101  {
102  *Semaphore = NULL;
103  deleted = true;
104  }
105  oC_IntMan_ExitCriticalSection();
106  }
107 
108  return deleted;
109 }
110 
111 //==========================================================================================================================================
112 //==========================================================================================================================================
113 bool oC_Semaphore_IsCorrect( oC_Semaphore_t Semaphore )
114 {
115  return oC_MemMan_IsRamAddress(Semaphore) && oC_CheckObjectControl(Semaphore,oC_ObjectId_Semaphore , Semaphore->ObjectControl);
116 }
117 
118 //==========================================================================================================================================
119 //==========================================================================================================================================
120 bool oC_Semaphore_Give( oC_Semaphore_t Semaphore )
121 {
122  bool given = false;
123 
124  if(oC_Semaphore_IsCorrect(Semaphore))
125  {
126  oC_IntMan_EnterCriticalSection();
127 
128  if(Semaphore->Value < Semaphore->Type)
129  {
130  Semaphore->Value++;
131  }
132  oC_IntMan_ExitCriticalSection();
133  given = true;
134  }
135 
136  return given;
137 }
138 
139 //==========================================================================================================================================
140 //==========================================================================================================================================
141 bool oC_Semaphore_GiveCounting( oC_Semaphore_t Semaphore , uint32_t Count )
142 {
143  bool given = false;
144 
145  if(oC_Semaphore_IsCorrect(Semaphore))
146  {
147  oC_IntMan_EnterCriticalSection();
148  Semaphore->Value += Count;
149 
150  if(Semaphore->Value > Semaphore->Type)
151  {
152  Semaphore->Value = Semaphore->Type;
153  }
154 
155  oC_IntMan_ExitCriticalSection();
156  given = true;
157  }
158 
159  return given;
160 }
161 
162 //==========================================================================================================================================
163 //==========================================================================================================================================
164 bool oC_Semaphore_Take( oC_Semaphore_t Semaphore , oC_Time_t Timeout )
165 {
166  bool taken = false;
167 
168  if(oC_Semaphore_IsCorrect(Semaphore))
169  {
170  if(Semaphore->Value == 0)
171  {
172  oC_Thread_t thread = oC_ThreadMan_GetCurrentThread();
173 
174  if(oC_Thread_SetBlocked(thread,&Semaphore->Value,oC_Thread_Unblock_WhenGreaterOrEqual,1,oC_Thread_UnblockMask_All,Timeout))
175  {
176  while(oC_Thread_IsBlocked(thread));
177 
178  oC_Thread_SetUnblocked(thread);
179 
180  oC_IntMan_EnterCriticalSection();
181  if(oC_Semaphore_IsCorrect(Semaphore) && (Semaphore->Value >= 1))
182  {
183  Semaphore->Value = 0;
184  taken = true;
185  }
186  oC_IntMan_ExitCriticalSection();
187  }
188  }
189  else
190  {
191  oC_IntMan_EnterCriticalSection();
192  Semaphore->Value = 0;
193  taken = true;
194  oC_IntMan_ExitCriticalSection();
195  }
196  }
197 
198  return taken;
199 }
200 
201 
202 //==========================================================================================================================================
203 //==========================================================================================================================================
204 bool oC_Semaphore_TakeCounting( oC_Semaphore_t Semaphore , uint32_t Count , oC_Time_t Timeout )
205 {
206  bool taken = false;
207 
208  if(oC_Semaphore_IsCorrect(Semaphore) && Count <= Semaphore->Type)
209  {
210  oC_IntMan_EnterCriticalSection();
211  if(Semaphore->Value < Count)
212  {
213  oC_IntMan_ExitCriticalSection();
214  oC_Thread_t thread = oC_ThreadMan_GetCurrentThread();
215 
216  if(oC_Thread_SetBlocked(thread,&Semaphore->Value, oC_Thread_Unblock_WhenGreaterOrEqual , Count , oC_Thread_UnblockMask_All , Timeout))
217  {
218  while(oC_Thread_IsBlocked(thread));
219 
220  oC_Thread_SetUnblocked(thread);
221 
222  oC_IntMan_EnterCriticalSection();
223  if(oC_Semaphore_IsCorrect(Semaphore) && (Semaphore->Value >= Count))
224  {
225  Semaphore->Value -= Count;
226  taken = true;
227  }
228  oC_IntMan_ExitCriticalSection();
229  }
230  }
231  else
232  {
233  Semaphore->Value -= Count;
234  taken = true;
235  oC_IntMan_ExitCriticalSection();
236  }
237  }
238 
239  return taken;
240 }
241 
242 
243 
244 #undef _________________________________________INTERFACE_FUNCTIONS_SECTION________________________________________________________________
245 
252 #define _________________________________________LOCAL_SECTION______________________________________________________________________________
253 
254 
255 #undef _________________________________________LOCAL_SECTION______________________________________________________________________________
256 
257 
bool oC_MemMan_IsRamAddress(const void *Address)
checks if address is in ram section
Definition: oc_memman.c:1542
identifier for allocations
Definition: oc_stdlib.h:159
The file with helper macros for managing objects.
uint32_t oC_ObjectControl_t
stores object control value
Definition: oc_object.h:141
The file with interface for interrupt manager.
static oC_ObjectControl_t oC_CountObjectControl(void *ObjectPointer, oC_ObjectId_t ObjectId)
counts object control for object
Definition: oc_object.h:168
static bool oC_CheckObjectControl(void *ObjectPointer, oC_ObjectId_t ObjectId, oC_ObjectControl_t ObjectControl)
checks if object control is correct
Definition: oc_object.h:203
Definition of the null pointer.
static const oC_Allocator_t Allocator
Definition: oc_eth.c:152
The file with interface for semaphores.
The file with interface for Thread Manager.
#define NULL
pointer to a zero
Definition: oc_null.h:37