source: azure_iot_hub/trunk/asp3_dcre/kernel/semaphore.c@ 388

Last change on this file since 388 was 388, checked in by coas-nagasima, 5 years ago

Azure IoT Hub Device C SDK を使ったサンプルの追加

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-csrc
File size: 11.2 KB
Line 
1/*
2 * TOPPERS/ASP Kernel
3 * Toyohashi Open Platform for Embedded Real-Time Systems/
4 * Advanced Standard Profile Kernel
5 *
6 * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
7 * Toyohashi Univ. of Technology, JAPAN
8 * Copyright (C) 2005-2016 by Embedded and Real-Time Systems Laboratory
9 * Graduate School of Information Science, Nagoya Univ., JAPAN
10 *
11 * 上記著作権者
12は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
13 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
14 * 変・再é…
15å¸ƒï¼ˆä»¥ä¸‹ï¼Œåˆ©ç”¨ã¨å‘¼ã¶ï¼‰ã™ã‚‹ã“とを無償で許諾する.
16 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
17 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
18 * スコード中に含まれていること.
19 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
20 * 用できる形で再é…
21å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œå†é…
22å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨
23 * 者
24マニュアルなど)に,上記の著作権表示,この利用条件および下記
25 * の無保証規定を掲載すること.
26 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
27 * 用できない形で再é…
28å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œæ¬¡ã®ã„ずれかの条件を満たすこ
29 * と.
30 * (a) 再é…
31å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨è€…
32マニュアルなど)に,上記の著
33 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
34 * (b) 再é…
35å¸ƒã®å½¢æ…
36‹ã‚’,別に定める方法によって,TOPPERSプロジェクトに
37 * 報告すること.
38 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
39 * 害からも,上記著作権者
40およびTOPPERSプロジェクトをå…
41è²¬ã™ã‚‹ã“と.
42 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
43 * 由に基づく請求からも,上記著作権者
44およびTOPPERSプロジェクトを
45 * å…
46è²¬ã™ã‚‹ã“と.
47 *
48 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者
49お
50 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
51 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
52 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
53 * の責任を負わない.
54 *
55 * $Id: semaphore.c 388 2019-05-22 11:25:18Z coas-nagasima $
56 */
57
58/*
59 * セマフォ機能
60 */
61
62#include "kernel_impl.h"
63#include "check.h"
64#include "task.h"
65#include "wait.h"
66#include "semaphore.h"
67
68/*
69 * トレースログマクロのデフォルト定義
70 */
71#ifndef LOG_ACRE_SEM_ENTER
72#define LOG_ACRE_SEM_ENTER(pk_csem)
73#endif /* LOG_ACRE_SEM_ENTER */
74
75#ifndef LOG_ACRE_SEM_LEAVE
76#define LOG_ACRE_SEM_LEAVE(ercd)
77#endif /* LOG_ACRE_SEM_LEAVE */
78
79#ifndef LOG_DEL_SEM_ENTER
80#define LOG_DEL_SEM_ENTER(semid)
81#endif /* LOG_DEL_SEM_ENTER */
82
83#ifndef LOG_DEL_SEM_LEAVE
84#define LOG_DEL_SEM_LEAVE(ercd)
85#endif /* LOG_DEL_SEM_LEAVE */
86
87#ifndef LOG_SIG_SEM_ENTER
88#define LOG_SIG_SEM_ENTER(semid)
89#endif /* LOG_SIG_SEM_ENTER */
90
91#ifndef LOG_SIG_SEM_LEAVE
92#define LOG_SIG_SEM_LEAVE(ercd)
93#endif /* LOG_SIG_SEM_LEAVE */
94
95#ifndef LOG_WAI_SEM_ENTER
96#define LOG_WAI_SEM_ENTER(semid)
97#endif /* LOG_WAI_SEM_ENTER */
98
99#ifndef LOG_WAI_SEM_LEAVE
100#define LOG_WAI_SEM_LEAVE(ercd)
101#endif /* LOG_WAI_SEM_LEAVE */
102
103#ifndef LOG_POL_SEM_ENTER
104#define LOG_POL_SEM_ENTER(semid)
105#endif /* LOG_POL_SEM_ENTER */
106
107#ifndef LOG_POL_SEM_LEAVE
108#define LOG_POL_SEM_LEAVE(ercd)
109#endif /* LOG_POL_SEM_LEAVE */
110
111#ifndef LOG_TWAI_SEM_ENTER
112#define LOG_TWAI_SEM_ENTER(semid, tmout)
113#endif /* LOG_TWAI_SEM_ENTER */
114
115#ifndef LOG_TWAI_SEM_LEAVE
116#define LOG_TWAI_SEM_LEAVE(ercd)
117#endif /* LOG_TWAI_SEM_LEAVE */
118
119#ifndef LOG_INI_SEM_ENTER
120#define LOG_INI_SEM_ENTER(semid)
121#endif /* LOG_INI_SEM_ENTER */
122
123#ifndef LOG_INI_SEM_LEAVE
124#define LOG_INI_SEM_LEAVE(ercd)
125#endif /* LOG_INI_SEM_LEAVE */
126
127#ifndef LOG_REF_SEM_ENTER
128#define LOG_REF_SEM_ENTER(semid, pk_rsem)
129#endif /* LOG_REF_SEM_ENTER */
130
131#ifndef LOG_REF_SEM_LEAVE
132#define LOG_REF_SEM_LEAVE(ercd, pk_rsem)
133#endif /* LOG_REF_SEM_LEAVE */
134
135/*
136 * セマフォの数
137 */
138#define tnum_sem ((uint_t)(tmax_semid - TMIN_SEMID + 1))
139#define tnum_ssem ((uint_t)(tmax_ssemid - TMIN_SEMID + 1))
140
141/*
142 * セマフォIDからセマフォ管理ブロックを取り出すためのマクロ
143 */
144#define INDEX_SEM(semid) ((uint_t)((semid) - TMIN_SEMID))
145#define get_semcb(semid) (&(semcb_table[INDEX_SEM(semid)]))
146
147#ifdef TOPPERS_semini
148
149/*
150 * 使用していないセマフォ管理ブロックのリスト
151 */
152QUEUE free_semcb;
153
154/*
155 * セマフォ機能の初期化
156 */
157void
158initialize_semaphore(void)
159{
160 uint_t i, j;
161 SEMCB *p_semcb;
162 SEMINIB *p_seminib;
163
164 for (i = 0; i < tnum_ssem; i++) {
165 p_semcb = &(semcb_table[i]);
166 queue_initialize(&(p_semcb->wait_queue));
167 p_semcb->p_seminib = &(seminib_table[i]);
168 p_semcb->semcnt = p_semcb->p_seminib->isemcnt;
169 }
170 queue_initialize(&free_semcb);
171 for (j = 0; i < tnum_sem; i++, j++) {
172 p_semcb = &(semcb_table[i]);
173 p_seminib = &(aseminib_table[j]);
174 p_seminib->sematr = TA_NOEXS;
175 p_semcb->p_seminib = ((const SEMINIB *) p_seminib);
176 queue_insert_prev(&free_semcb, &(p_semcb->wait_queue));
177 }
178}
179
180#endif /* TOPPERS_semini */
181
182/*
183 * セマフォの生成
184 */
185#ifdef TOPPERS_acre_sem
186
187ER_UINT
188acre_sem(const T_CSEM *pk_csem)
189{
190 SEMCB *p_semcb;
191 SEMINIB *p_seminib;
192 ATR sematr;
193 uint_t isemcnt, maxsem;
194 ER ercd;
195
196 LOG_ACRE_SEM_ENTER(pk_csem);
197 CHECK_TSKCTX_UNL();
198
199 sematr = pk_csem->sematr;
200 isemcnt = pk_csem->isemcnt;
201 maxsem = pk_csem->maxsem;
202
203 CHECK_RSATR(sematr, TA_TPRI);
204 CHECK_PAR(0 <= isemcnt && isemcnt <= maxsem);
205 CHECK_PAR(1 <= maxsem && maxsem <= TMAX_MAXSEM);
206
207 lock_cpu();
208 if (tnum_sem == 0 || queue_empty(&free_semcb)) {
209 ercd = E_NOID;
210 }
211 else {
212 p_semcb = ((SEMCB *) queue_delete_next(&free_semcb));
213 p_seminib = (SEMINIB *)(p_semcb->p_seminib);
214 p_seminib->sematr = sematr;
215 p_seminib->isemcnt = isemcnt;
216 p_seminib->maxsem = maxsem;
217
218 queue_initialize(&(p_semcb->wait_queue));
219 p_semcb->semcnt = p_semcb->p_seminib->isemcnt;
220 ercd = SEMID(p_semcb);
221 }
222 unlock_cpu();
223
224 error_exit:
225 LOG_ACRE_SEM_LEAVE(ercd);
226 return(ercd);
227}
228
229#endif /* TOPPERS_acre_sem */
230
231/*
232 * セマフォの削除
233 */
234#ifdef TOPPERS_del_sem
235
236ER
237del_sem(ID semid)
238{
239 SEMCB *p_semcb;
240 SEMINIB *p_seminib;
241 ER ercd;
242
243 LOG_DEL_SEM_ENTER(semid);
244 CHECK_TSKCTX_UNL();
245 CHECK_ID(VALID_SEMID(semid));
246 p_semcb = get_semcb(semid);
247
248 lock_cpu();
249 if (p_semcb->p_seminib->sematr == TA_NOEXS) {
250 ercd = E_NOEXS;
251 }
252 else if (semid <= tmax_ssemid) {
253 ercd = E_OBJ;
254 }
255 else {
256 init_wait_queue(&(p_semcb->wait_queue));
257 p_seminib = (SEMINIB *)(p_semcb->p_seminib);
258 p_seminib->sematr = TA_NOEXS;
259 queue_insert_prev(&free_semcb, &(p_semcb->wait_queue));
260 if (p_runtsk != p_schedtsk) {
261 dispatch();
262 }
263 ercd = E_OK;
264 }
265 unlock_cpu();
266
267 error_exit:
268 LOG_DEL_SEM_LEAVE(ercd);
269 return(ercd);
270}
271
272#endif /* TOPPERS_del_sem */
273
274/*
275 * セマフォ資源の返却
276 */
277#ifdef TOPPERS_sig_sem
278
279ER
280sig_sem(ID semid)
281{
282 SEMCB *p_semcb;
283 TCB *p_tcb;
284 ER ercd;
285
286 LOG_SIG_SEM_ENTER(semid);
287 CHECK_UNL();
288 CHECK_ID(VALID_SEMID(semid));
289 p_semcb = get_semcb(semid);
290
291 lock_cpu();
292 if (p_semcb->p_seminib->sematr == TA_NOEXS) {
293 ercd = E_NOEXS;
294 }
295 else if (!queue_empty(&(p_semcb->wait_queue))) {
296 p_tcb = (TCB *) queue_delete_next(&(p_semcb->wait_queue));
297 wait_complete(p_tcb);
298 if (p_runtsk != p_schedtsk) {
299 if (!sense_context()) {
300 dispatch();
301 }
302 else {
303 request_dispatch();
304 }
305 }
306 ercd = E_OK;
307 }
308 else if (p_semcb->semcnt < p_semcb->p_seminib->maxsem) {
309 p_semcb->semcnt += 1;
310 ercd = E_OK;
311 }
312 else {
313 ercd = E_QOVR;
314 }
315 unlock_cpu();
316
317 error_exit:
318 LOG_SIG_SEM_LEAVE(ercd);
319 return(ercd);
320}
321
322#endif /* TOPPERS_sig_sem */
323
324/*
325 * セマフォ資源の獲得
326 */
327#ifdef TOPPERS_wai_sem
328
329ER
330wai_sem(ID semid)
331{
332 SEMCB *p_semcb;
333 WINFO_SEM winfo_sem;
334 ER ercd;
335
336 LOG_WAI_SEM_ENTER(semid);
337 CHECK_DISPATCH();
338 CHECK_ID(VALID_SEMID(semid));
339 p_semcb = get_semcb(semid);
340
341 lock_cpu_dsp();
342 if (p_semcb->p_seminib->sematr == TA_NOEXS) {
343 ercd = E_NOEXS;
344 }
345 else if (p_runtsk->raster) {
346 ercd = E_RASTER;
347 }
348 else if (p_semcb->semcnt >= 1) {
349 p_semcb->semcnt -= 1;
350 ercd = E_OK;
351 }
352 else {
353 p_runtsk->tstat = TS_WAITING_SEM;
354 wobj_make_wait((WOBJCB *) p_semcb, (WINFO_WOBJ *) &winfo_sem);
355 dispatch();
356 ercd = winfo_sem.winfo.wercd;
357 }
358 unlock_cpu_dsp();
359
360 error_exit:
361 LOG_WAI_SEM_LEAVE(ercd);
362 return(ercd);
363}
364
365#endif /* TOPPERS_wai_sem */
366
367/*
368 * セマフォ資源の獲得(ポーリング)
369 */
370#ifdef TOPPERS_pol_sem
371
372ER
373pol_sem(ID semid)
374{
375 SEMCB *p_semcb;
376 ER ercd;
377
378 LOG_POL_SEM_ENTER(semid);
379 CHECK_TSKCTX_UNL();
380 CHECK_ID(VALID_SEMID(semid));
381 p_semcb = get_semcb(semid);
382
383 lock_cpu();
384 if (p_semcb->p_seminib->sematr == TA_NOEXS) {
385 ercd = E_NOEXS;
386 }
387 else if (p_semcb->semcnt >= 1) {
388 p_semcb->semcnt -= 1;
389 ercd = E_OK;
390 }
391 else {
392 ercd = E_TMOUT;
393 }
394 unlock_cpu();
395
396 error_exit:
397 LOG_POL_SEM_LEAVE(ercd);
398 return(ercd);
399}
400
401#endif /* TOPPERS_pol_sem */
402
403/*
404 * セマフォ資源の獲得(タイムアウトあり)
405 */
406#ifdef TOPPERS_twai_sem
407
408ER
409twai_sem(ID semid, TMO tmout)
410{
411 SEMCB *p_semcb;
412 WINFO_SEM winfo_sem;
413 TMEVTB tmevtb;
414 ER ercd;
415
416 LOG_TWAI_SEM_ENTER(semid, tmout);
417 CHECK_DISPATCH();
418 CHECK_ID(VALID_SEMID(semid));
419 CHECK_PAR(VALID_TMOUT(tmout));
420 p_semcb = get_semcb(semid);
421
422 lock_cpu_dsp();
423 if (p_semcb->p_seminib->sematr == TA_NOEXS) {
424 ercd = E_NOEXS;
425 }
426 else if (p_runtsk->raster) {
427 ercd = E_RASTER;
428 }
429 else if (p_semcb->semcnt >= 1) {
430 p_semcb->semcnt -= 1;
431 ercd = E_OK;
432 }
433 else if (tmout == TMO_POL) {
434 ercd = E_TMOUT;
435 }
436 else {
437 p_runtsk->tstat = TS_WAITING_SEM;
438 wobj_make_wait_tmout((WOBJCB *) p_semcb, (WINFO_WOBJ *) &winfo_sem,
439 &tmevtb, tmout);
440 dispatch();
441 ercd = winfo_sem.winfo.wercd;
442 }
443 unlock_cpu_dsp();
444
445 error_exit:
446 LOG_TWAI_SEM_LEAVE(ercd);
447 return(ercd);
448}
449
450#endif /* TOPPERS_twai_sem */
451
452/*
453 * セマフォの再初期化
454 */
455#ifdef TOPPERS_ini_sem
456
457ER
458ini_sem(ID semid)
459{
460 SEMCB *p_semcb;
461 ER ercd;
462
463 LOG_INI_SEM_ENTER(semid);
464 CHECK_TSKCTX_UNL();
465 CHECK_ID(VALID_SEMID(semid));
466 p_semcb = get_semcb(semid);
467
468 lock_cpu();
469 if (p_semcb->p_seminib->sematr == TA_NOEXS) {
470 ercd = E_NOEXS;
471 }
472 else {
473 init_wait_queue(&(p_semcb->wait_queue));
474 p_semcb->semcnt = p_semcb->p_seminib->isemcnt;
475 if (p_runtsk != p_schedtsk) {
476 dispatch();
477 }
478 ercd = E_OK;
479 }
480 unlock_cpu();
481
482 error_exit:
483 LOG_INI_SEM_LEAVE(ercd);
484 return(ercd);
485}
486
487#endif /* TOPPERS_ini_sem */
488
489/*
490 * セマフォの状æ…
491‹å‚ç…
492§
493 */
494#ifdef TOPPERS_ref_sem
495
496ER
497ref_sem(ID semid, T_RSEM *pk_rsem)
498{
499 SEMCB *p_semcb;
500 ER ercd;
501
502 LOG_REF_SEM_ENTER(semid, pk_rsem);
503 CHECK_TSKCTX_UNL();
504 CHECK_ID(VALID_SEMID(semid));
505 p_semcb = get_semcb(semid);
506
507 lock_cpu();
508 if (p_semcb->p_seminib->sematr == TA_NOEXS) {
509 ercd = E_NOEXS;
510 }
511 else {
512 pk_rsem->wtskid = wait_tskid(&(p_semcb->wait_queue));
513 pk_rsem->semcnt = p_semcb->semcnt;
514 ercd = E_OK;
515 }
516 unlock_cpu();
517
518 error_exit:
519 LOG_REF_SEM_LEAVE(ercd, pk_rsem);
520 return(ercd);
521}
522
523#endif /* TOPPERS_ref_sem */
Note: See TracBrowser for help on using the repository browser.