source: azure_iot_hub_f767zi/trunk/asp_baseplatform/kernel/mutex.c@ 457

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

ファイルを追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 17.9 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) 2005-2014 by Embedded and Real-Time Systems Laboratory
7 * Graduate School of Information Science, Nagoya Univ., JAPAN
8 *
9 * 上記著作権者は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
10 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
11 * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
12 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
13 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
14 * スコード中に含まれていること.
15 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
16 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
17 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
18 * の無保証規定を掲載すること.
19 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
20 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
21 * と.
22 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
23 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
24 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
25 * 報告すること.
26 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
27 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
28 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
29 * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
30 * 免責すること.
31 *
32 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
33 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
34 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
35 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
36 * の責任を負わない.
37 *
38 * $Id$
39 */
40
41/*
42 * ミューテックス機能
43 */
44
45#include "kernel_impl.h"
46#include "check.h"
47#include "task.h"
48#include "wait.h"
49#include "mutex.h"
50
51/*
52 * トレースログマクロのデフォルト定義
53 */
54#ifndef LOG_ACRE_MTX_ENTER
55#define LOG_ACRE_MTX_ENTER(mtxid)
56#endif /* LOG_ACRE_MTX_ENTER */
57
58#ifndef LOG_ACRE_MTX_LEAVE
59#define LOG_ACRE_MTX_LEAVE(ercd)
60#endif /* LOG_ACRE_MTX_LEAVE */
61
62#ifndef LOG_DEL_MTX_ENTER
63#define LOG_DEL_MTX_ENTER(mtxid)
64#endif /* LOG_DEL_MTX_ENTER */
65
66#ifndef LOG_DEL_MTX_LEAVE
67#define LOG_DEL_MTX_LEAVE(ercd)
68#endif /* LOG_DEL_MTX_LEAVE */
69
70#ifndef LOG_LOC_MTX_ENTER
71#define LOG_LOC_MTX_ENTER(mtxid)
72#endif /* LOG_LOC_MTX_ENTER */
73
74#ifndef LOG_LOC_MTX_LEAVE
75#define LOG_LOC_MTX_LEAVE(ercd)
76#endif /* LOG_LOC_MTX_LEAVE */
77
78#ifndef LOG_PLOC_MTX_ENTER
79#define LOG_PLOC_MTX_ENTER(mtxid)
80#endif /* LOG_PLOC_MTX_ENTER */
81
82#ifndef LOG_PLOC_MTX_LEAVE
83#define LOG_PLOC_MTX_LEAVE(ercd)
84#endif /* LOG_PLOC_MTX_LEAVE */
85
86#ifndef LOG_TLOC_MTX_ENTER
87#define LOG_TLOC_MTX_ENTER(mtxid, tmout)
88#endif /* LOG_TLOC_MTX_ENTER */
89
90#ifndef LOG_TLOC_MTX_LEAVE
91#define LOG_TLOC_MTX_LEAVE(ercd)
92#endif /* LOG_TLOC_MTX_LEAVE */
93
94#ifndef LOG_UNL_MTX_ENTER
95#define LOG_UNL_MTX_ENTER(mtxid)
96#endif /* LOG_UNL_MTX_ENTER */
97
98#ifndef LOG_UNL_MTX_LEAVE
99#define LOG_UNL_MTX_LEAVE(ercd)
100#endif /* LOG_UNL_MTX_LEAVE */
101
102#ifndef LOG_INI_MTX_ENTER
103#define LOG_INI_MTX_ENTER(mtxid)
104#endif /* LOG_INI_MTX_ENTER */
105
106#ifndef LOG_INI_MTX_LEAVE
107#define LOG_INI_MTX_LEAVE(ercd)
108#endif /* LOG_INI_MTX_LEAVE */
109
110#ifndef LOG_REF_MTX_ENTER
111#define LOG_REF_MTX_ENTER(mtxid, pk_rmtx)
112#endif /* LOG_REF_MTX_ENTER */
113
114#ifndef LOG_REF_MTX_LEAVE
115#define LOG_REF_MTX_LEAVE(ercd, pk_rmtx)
116#endif /* LOG_REF_MTX_LEAVE */
117
118/*
119 * ミューテックスの数
120 */
121#define tnum_mtx ((uint_t)(tmax_mtxid - TMIN_MTXID + 1))
122#define tnum_smtx ((uint_t)(tmax_smtxid - TMIN_MTXID + 1))
123
124/*
125 * ミューテックスIDからミューテックス管理ブロックを取り出すためのマクロ
126 */
127#define INDEX_MTX(mtxid) ((uint_t)((mtxid) - TMIN_MTXID))
128#define get_mtxcb(mtxid) (&(mtxcb_table[INDEX_MTX(mtxid)]))
129
130/*
131 * ミューテックス管理ブロック中のmutex_queueへのポインタから,ミューテッ
132 * クス管理ブロックへのポインタを取り出すためのマクロ
133 */
134#define MTXCB_QUEUE(p_queue) \
135 ((MTXCB *)(((char *) p_queue) - offsetof(MTXCB, mutex_queue)))
136
137/*
138 * ミューテックスのプロトコルを判断するマクロ
139 */
140#define MTXPROTO_MASK 0x03U
141#define MTXPROTO(p_mtxcb) ((p_mtxcb)->p_mtxinib->mtxatr & MTXPROTO_MASK)
142#define MTX_CEILING(p_mtxcb) (MTXPROTO(p_mtxcb) == TA_CEILING)
143
144/*
145 * フックルーチン呼出し用の変数
146 */
147#ifdef TOPPERS_mtxhook
148
149bool_t (*mtxhook_check_ceilpri)(TCB *p_tcb, uint_t bpriority) = NULL;
150bool_t (*mtxhook_scan_ceilmtx)(TCB *p_tcb) = NULL;
151bool_t (*mtxhook_release_all)(TCB *p_tcb) = NULL;
152
153#endif /* TOPPERS_mtxhook */
154
155/*
156 * 使用していないミューテックス管理ブロックのリスト
157 */
158QUEUE free_mtxcb;
159
160/*
161 * ミューテックス機能の初期化
162 */
163#ifdef TOPPERS_mtxini
164
165void
166initialize_mutex(void)
167{
168 uint_t i, j;
169 MTXCB *p_mtxcb;
170 MTXINIB *p_mtxinib;
171
172 mtxhook_check_ceilpri = mutex_check_ceilpri;
173 mtxhook_scan_ceilmtx = mutex_scan_ceilmtx;
174 mtxhook_release_all = mutex_release_all;
175
176 for (i = 0; i < tnum_smtx; i++) {
177 p_mtxcb = &(mtxcb_table[i]);
178 queue_initialize(&(p_mtxcb->wait_queue));
179 p_mtxcb->p_mtxinib = &(mtxinib_table[i]);
180 p_mtxcb->p_loctsk = NULL;
181 }
182 queue_initialize(&free_mtxcb);
183 for (j = 0; i < tnum_mtx; i++, j++) {
184 p_mtxcb = &(mtxcb_table[i]);
185 p_mtxinib = &(amtxinib_table[j]);
186 p_mtxinib->mtxatr = TA_NOEXS;
187 p_mtxcb->p_mtxinib = ((const MTXINIB *) p_mtxinib);
188 queue_insert_prev(&free_mtxcb, &(p_mtxcb->wait_queue));
189 }
190}
191
192#endif /* TOPPERS_mtxini */
193
194/*
195 * 上限優先度違反のチェック
196 */
197#ifdef TOPPERS_mtxchk
198
199bool_t
200mutex_check_ceilpri(TCB *p_tcb, uint_t bpriority)
201{
202 QUEUE *p_queue;
203 MTXCB *p_mtxcb;
204
205 /*
206 * タスクがロックしている優先度上限ミューテックスの中で,上限優先
207 * 度がbpriorityよりも低いものがあれば,falseを返す.
208 */
209 p_queue = p_tcb->mutex_queue.p_next;
210 while (p_queue != &(p_tcb->mutex_queue)) {
211 p_mtxcb = MTXCB_QUEUE(p_queue);
212 if (MTX_CEILING(p_mtxcb) && bpriority < p_mtxcb->p_mtxinib->ceilpri) {
213 return(false);
214 }
215 p_queue = p_queue->p_next;
216 }
217
218 /*
219 * タスクが優先度上限ミューテックスのロックを待っている場合に,そ
220 * の上限優先度がbpriorityよりも低くければ,falseを返す.
221 */
222 if (TSTAT_WAIT_MTX(p_tcb->tstat)) {
223 p_mtxcb = ((WINFO_MTX *)(p_tcb->p_winfo))->p_mtxcb;
224 if (MTX_CEILING(p_mtxcb) && bpriority < p_mtxcb->p_mtxinib->ceilpri) {
225 return(false);
226 }
227 }
228
229 /*
230 * いずれの条件にも当てはまらなければtrueを返す.
231 */
232 return(true);
233}
234
235#endif /* TOPPERS_mtxchk */
236
237/*
238 * 優先度上限ミューテックスをロックしているかのチェック
239 */
240#ifdef TOPPERS_mtxscan
241
242bool_t
243mutex_scan_ceilmtx(TCB *p_tcb)
244{
245 QUEUE *p_queue;
246 MTXCB *p_mtxcb;
247
248 p_queue = p_tcb->mutex_queue.p_next;
249 while (p_queue != &(p_tcb->mutex_queue)) {
250 p_mtxcb = MTXCB_QUEUE(p_queue);
251 if (MTX_CEILING(p_mtxcb)) {
252 return(true);
253 }
254 p_queue = p_queue->p_next;
255 }
256 return(false);
257}
258
259#endif /* TOPPERS_mtxscan */
260
261/*
262 * タスクの現在優先度の計算
263 */
264#ifdef TOPPERS_mtxcalc
265
266uint_t
267mutex_calc_priority(TCB *p_tcb)
268{
269 uint_t priority;
270 QUEUE *p_queue;
271 MTXCB *p_mtxcb;
272
273 priority = p_tcb->bpriority;
274 p_queue = p_tcb->mutex_queue.p_next;
275 while (p_queue != &(p_tcb->mutex_queue)) {
276 p_mtxcb = MTXCB_QUEUE(p_queue);
277 if (MTX_CEILING(p_mtxcb) && p_mtxcb->p_mtxinib->ceilpri < priority) {
278 priority = p_mtxcb->p_mtxinib->ceilpri;
279 }
280 p_queue = p_queue->p_next;
281 }
282 return(priority);
283}
284
285#endif /* TOPPERS_mtxcalc */
286
287/*
288 * 要素優先度が上がる(または増える)場合の現在優先度変更処理
289 */
290Inline bool_t
291mutex_raise_priority(TCB *p_tcb, uint_t newpri)
292{
293 if (newpri < p_tcb->priority) {
294 return(change_priority(p_tcb, newpri, true));
295 }
296 return(false);
297}
298
299/*
300 * 要素優先度が下がる(または減る)場合の現在優先度変更処理
301 */
302Inline bool_t
303mutex_drop_priority(TCB *p_tcb, uint_t oldpri)
304{
305 uint_t newpri;
306
307 if (oldpri == p_tcb->priority) {
308 newpri = mutex_calc_priority(p_tcb);
309 if (newpri != p_tcb->priority) {
310 return(change_priority(p_tcb, newpri, true));
311 }
312 }
313 return(false);
314}
315
316/*
317 * ミューテックスをロックした場合の処理
318 */
319Inline bool_t
320mutex_acquire(TCB *p_loctsk, MTXCB *p_mtxcb)
321{
322 p_mtxcb->p_loctsk = p_loctsk;
323 queue_insert_next(&(p_loctsk->mutex_queue), &(p_mtxcb->mutex_queue));
324 if (MTX_CEILING(p_mtxcb)) {
325 return(mutex_raise_priority(p_loctsk, p_mtxcb->p_mtxinib->ceilpri));
326 }
327 return(false);
328}
329
330/*
331 * ミューテックスのロック解除
332 */
333#ifdef TOPPERS_mtxrel
334
335bool_t
336mutex_release(MTXCB *p_mtxcb)
337{
338 TCB *p_tcb;
339
340 if (queue_empty(&(p_mtxcb->wait_queue))) {
341 p_mtxcb->p_loctsk = NULL;
342 return(false);
343 }
344 else {
345 /*
346 * ミューテックス待ちキューの先頭タスク(p_tcb)に,ミューテッ
347 * クスをロックさせる.
348 */
349 p_tcb = (TCB *) queue_delete_next(&(p_mtxcb->wait_queue));
350 wait_dequeue_tmevtb(p_tcb);
351 p_tcb->p_winfo->wercd = E_OK;
352
353 p_mtxcb->p_loctsk = p_tcb;
354 queue_insert_prev(&(p_tcb->mutex_queue), &(p_mtxcb->mutex_queue));
355 if (MTX_CEILING(p_mtxcb)) {
356 if (p_mtxcb->p_mtxinib->ceilpri < p_tcb->priority) {
357 p_tcb->priority = p_mtxcb->p_mtxinib->ceilpri;
358 }
359 }
360 return(make_non_wait(p_tcb));
361 }
362}
363
364#endif /* TOPPERS_mtxrel */
365
366/*
367 * タスクがロックしているすべてのミューテックスのロック解除
368 */
369#ifdef TOPPERS_mtxrela
370
371bool_t
372mutex_release_all(TCB *p_tcb)
373{
374 MTXCB *p_mtxcb;
375 bool_t dspreq = false;
376
377 while (!queue_empty(&(p_tcb->mutex_queue))) {
378 p_mtxcb = MTXCB_QUEUE(p_tcb->mutex_queue.p_next);
379 queue_delete(&(p_mtxcb->mutex_queue));
380 if (mutex_release(p_mtxcb)) {
381 dspreq = true;
382 }
383 }
384 return(dspreq);
385}
386
387#endif /* TOPPERS_mtxrela */
388
389/*
390 * ミューテックスの生成
391 */
392#ifdef TOPPERS_acre_mtx
393
394ER_UINT
395acre_mtx(const T_CMTX *pk_cmtx)
396{
397 MTXCB *p_mtxcb;
398 MTXINIB *p_mtxinib;
399 ATR mtxatr;
400 PRI ceilpri;
401 ER ercd;
402
403 LOG_ACRE_MTX_ENTER(pk_cmtx);
404 CHECK_TSKCTX_UNL();
405
406 mtxatr = pk_cmtx->mtxatr;
407 ceilpri = pk_cmtx->ceilpri;
408
409 if (mtxatr == TA_CEILING) {
410 CHECK_PAR(VALID_TPRI(ceilpri));
411 }
412 else {
413 CHECK_RSATR(mtxatr, TA_TPRI);
414 }
415
416 t_lock_cpu();
417 if (tnum_mtx == 0 || queue_empty(&free_mtxcb)) {
418 ercd = E_NOID;
419 }
420 else {
421 p_mtxcb = ((MTXCB *) queue_delete_next(&free_mtxcb));
422 p_mtxinib = (MTXINIB *)(p_mtxcb->p_mtxinib);
423 p_mtxinib->mtxatr = mtxatr;
424 p_mtxinib->ceilpri = INT_PRIORITY(ceilpri);
425
426 queue_initialize(&(p_mtxcb->wait_queue));
427 queue_initialize(&(p_mtxcb->mutex_queue));
428 ercd = MTXID(p_mtxcb);
429 }
430 t_unlock_cpu();
431
432 error_exit:
433 LOG_ACRE_MTX_LEAVE(ercd);
434 return(ercd);
435}
436
437#endif /* TOPPERS_acre_mtx */
438
439/*
440 * ミューテックスの削除
441 */
442#ifdef TOPPERS_del_mtx
443
444ER
445del_mtx(ID mtxid)
446{
447 MTXCB *p_mtxcb;
448 bool_t dspreq = false;
449 MTXINIB *p_mtxinib;
450 TCB *p_loctsk;
451 ER ercd;
452
453 LOG_DEL_MTX_ENTER(mtxid);
454 CHECK_TSKCTX_UNL();
455 CHECK_MTXID(mtxid);
456 p_mtxcb = get_mtxcb(mtxid);
457
458 t_lock_cpu();
459 if (p_mtxcb->p_mtxinib->mtxatr == TA_NOEXS) {
460 ercd = E_NOEXS;
461 }
462 else if (MTXID(p_mtxcb) > tmax_smtxid) {
463 dspreq = init_wait_queue(&(p_mtxcb->wait_queue));
464 p_loctsk = p_mtxcb->p_loctsk;
465 if (p_loctsk != NULL) {
466 queue_delete(&(p_mtxcb->mutex_queue));
467 p_mtxcb->p_loctsk = NULL;
468 if (MTX_CEILING(p_mtxcb)) {
469 if (mutex_drop_priority(p_loctsk, p_mtxcb->p_mtxinib->ceilpri)) {
470 dspreq = true;
471 }
472 }
473 }
474 p_mtxinib = (MTXINIB *)(p_mtxcb->p_mtxinib);
475 p_mtxinib->mtxatr = TA_NOEXS;
476 queue_insert_prev(&free_mtxcb, &(p_mtxcb->wait_queue));
477 if (dspreq) {
478 dispatch();
479 }
480 ercd = E_OK;
481 }
482 else {
483 ercd = E_OBJ;
484 }
485 t_unlock_cpu();
486
487 error_exit:
488 LOG_DEL_MTX_LEAVE(ercd);
489 return(ercd);
490}
491
492#endif /* TOPPERS_del_mtx */
493
494/*
495 * ミューテックスのロック
496 */
497#ifdef TOPPERS_loc_mtx
498
499ER
500loc_mtx(ID mtxid)
501{
502 MTXCB *p_mtxcb;
503 WINFO_MTX winfo_mtx;
504 ER ercd;
505
506 LOG_LOC_MTX_ENTER(mtxid);
507 CHECK_DISPATCH();
508 CHECK_MTXID(mtxid);
509 p_mtxcb = get_mtxcb(mtxid);
510
511 t_lock_cpu();
512 if (p_mtxcb->p_mtxinib->mtxatr == TA_NOEXS) {
513 ercd = E_NOEXS;
514 }
515 else if (MTX_CEILING(p_mtxcb)
516 && p_runtsk->bpriority < p_mtxcb->p_mtxinib->ceilpri) {
517 ercd = E_ILUSE;
518 }
519 else if (p_mtxcb->p_loctsk == NULL) {
520 (void) mutex_acquire(p_runtsk, p_mtxcb);
521 /*
522 * 優先度上限ミューテックスをロックした場合,p_runtskの優先度
523 * が上がる可能性があるが,ディスパッチが必要になることはない.
524 */
525 assert(!(p_runtsk != p_schedtsk && dspflg));
526 ercd = E_OK;
527 }
528 else if (p_mtxcb->p_loctsk == p_runtsk) {
529 ercd = E_OBJ;
530 }
531 else {
532 p_runtsk->tstat = (TS_WAITING | TS_WAIT_MTX);
533 wobj_make_wait((WOBJCB *) p_mtxcb, (WINFO_WOBJ *) &winfo_mtx);
534 dispatch();
535 ercd = winfo_mtx.winfo.wercd;
536 }
537 t_unlock_cpu();
538
539 error_exit:
540 LOG_LOC_MTX_LEAVE(ercd);
541 return(ercd);
542}
543
544#endif /* TOPPERS_loc_mtx */
545
546/*
547 * ミューテックスのロック(ポーリング)
548 */
549#ifdef TOPPERS_ploc_mtx
550
551ER
552ploc_mtx(ID mtxid)
553{
554 MTXCB *p_mtxcb;
555 ER ercd;
556
557 LOG_PLOC_MTX_ENTER(mtxid);
558 CHECK_TSKCTX_UNL();
559 CHECK_MTXID(mtxid);
560 p_mtxcb = get_mtxcb(mtxid);
561
562 t_lock_cpu();
563 if (p_mtxcb->p_mtxinib->mtxatr == TA_NOEXS) {
564 ercd = E_NOEXS;
565 }
566 else if (MTX_CEILING(p_mtxcb)
567 && p_runtsk->bpriority < p_mtxcb->p_mtxinib->ceilpri) {
568 ercd = E_ILUSE;
569 }
570 else if (p_mtxcb->p_loctsk == NULL) {
571 (void) mutex_acquire(p_runtsk, p_mtxcb);
572 /*
573 * 優先度上限ミューテックスをロックした場合,p_runtskの優先度
574 * が上がる可能性があるが,ディスパッチが必要になることはない.
575 */
576 assert(!(p_runtsk != p_schedtsk && dspflg));
577 ercd = E_OK;
578 }
579 else if (p_mtxcb->p_loctsk == p_runtsk) {
580 ercd = E_OBJ;
581 }
582 else {
583 ercd = E_TMOUT;
584 }
585 t_unlock_cpu();
586
587 error_exit:
588 LOG_PLOC_MTX_LEAVE(ercd);
589 return(ercd);
590}
591
592#endif /* TOPPERS_ploc_mtx */
593
594/*
595 * ミューテックスのロック(タイムアウトあり)
596 */
597#ifdef TOPPERS_tloc_mtx
598
599ER
600tloc_mtx(ID mtxid, TMO tmout)
601{
602 MTXCB *p_mtxcb;
603 WINFO_MTX winfo_mtx;
604 TMEVTB tmevtb;
605 ER ercd;
606
607 LOG_TLOC_MTX_ENTER(mtxid, tmout);
608 CHECK_DISPATCH();
609 CHECK_MTXID(mtxid);
610 CHECK_TMOUT(tmout);
611 p_mtxcb = get_mtxcb(mtxid);
612
613 t_lock_cpu();
614 if (p_mtxcb->p_mtxinib->mtxatr == TA_NOEXS) {
615 ercd = E_NOEXS;
616 }
617 else if (MTX_CEILING(p_mtxcb)
618 && p_runtsk->bpriority < p_mtxcb->p_mtxinib->ceilpri) {
619 ercd = E_ILUSE;
620 }
621 else if (p_mtxcb->p_loctsk == NULL) {
622 (void) mutex_acquire(p_runtsk, p_mtxcb);
623 /*
624 * 優先度上限ミューテックスをロックした場合,p_runtskの優先度
625 * が上がる可能性があるが,ディスパッチが必要になることはない.
626 */
627 assert(!(p_runtsk != p_schedtsk && dspflg));
628 ercd = E_OK;
629 }
630 else if (p_mtxcb->p_loctsk == p_runtsk) {
631 ercd = E_OBJ;
632 }
633 else if (tmout == TMO_POL) {
634 ercd = E_TMOUT;
635 }
636 else {
637 p_runtsk->tstat = (TS_WAITING | TS_WAIT_MTX);
638 wobj_make_wait_tmout((WOBJCB *) p_mtxcb, (WINFO_WOBJ *) &winfo_mtx,
639 &tmevtb, tmout);
640 dispatch();
641 ercd = winfo_mtx.winfo.wercd;
642 }
643 t_unlock_cpu();
644
645 error_exit:
646 LOG_TLOC_MTX_LEAVE(ercd);
647 return(ercd);
648}
649
650#endif /* TOPPERS_tloc_mtx */
651
652/*
653 * ミューテックスのロック解除
654 */
655#ifdef TOPPERS_unl_mtx
656
657ER
658unl_mtx(ID mtxid)
659{
660 MTXCB *p_mtxcb;
661 bool_t dspreq = false;
662 ER ercd;
663
664 LOG_UNL_MTX_ENTER(mtxid);
665 CHECK_TSKCTX_UNL();
666 CHECK_MTXID(mtxid);
667 p_mtxcb = get_mtxcb(mtxid);
668
669 t_lock_cpu();
670 if (p_mtxcb->p_mtxinib->mtxatr == TA_NOEXS) {
671 ercd = E_NOEXS;
672 }
673 else if (p_mtxcb->p_loctsk != p_runtsk) {
674 ercd = E_OBJ;
675 }
676 else {
677 queue_delete(&(p_mtxcb->mutex_queue));
678 if (MTX_CEILING(p_mtxcb)) {
679 if (mutex_drop_priority(p_runtsk, p_mtxcb->p_mtxinib->ceilpri)) {
680 dspreq = true;
681 }
682 }
683 if (mutex_release(p_mtxcb)) {
684 dspreq = true;
685 }
686 if (dspreq) {
687 dispatch();
688 }
689 ercd = E_OK;
690 }
691 t_unlock_cpu();
692
693 error_exit:
694 LOG_UNL_MTX_LEAVE(ercd);
695 return(ercd);
696}
697
698#endif /* TOPPERS_unl_mtx */
699
700/*
701 * ミューテックスの初期化
702 */
703#ifdef TOPPERS_ini_mtx
704
705ER
706ini_mtx(ID mtxid)
707{
708 MTXCB *p_mtxcb;
709 TCB *p_loctsk;
710 bool_t dspreq;
711 ER ercd;
712
713 LOG_INI_MTX_ENTER(mtxid);
714 CHECK_TSKCTX_UNL();
715 CHECK_MTXID(mtxid);
716 p_mtxcb = get_mtxcb(mtxid);
717
718 t_lock_cpu();
719 if (p_mtxcb->p_mtxinib->mtxatr == TA_NOEXS) {
720 ercd = E_NOEXS;
721 }
722 else {
723 dspreq = init_wait_queue(&(p_mtxcb->wait_queue));
724 p_loctsk = p_mtxcb->p_loctsk;
725 if (p_loctsk != NULL) {
726 queue_delete(&(p_mtxcb->mutex_queue));
727 p_mtxcb->p_loctsk = NULL;
728 if (MTX_CEILING(p_mtxcb)) {
729 if (mutex_drop_priority(p_loctsk, p_mtxcb->p_mtxinib->ceilpri)) {
730 dspreq = true;
731 }
732 }
733 }
734 if (dspreq) {
735 dispatch();
736 }
737 ercd = E_OK;
738 }
739 t_unlock_cpu();
740
741 error_exit:
742 LOG_INI_MTX_LEAVE(ercd);
743 return(ercd);
744}
745
746#endif /* TOPPERS_ini_mtx */
747
748/*
749 * ミューテックスの状態参照
750 */
751#ifdef TOPPERS_ref_mtx
752
753ER
754ref_mtx(ID mtxid, T_RMTX *pk_rmtx)
755{
756 MTXCB *p_mtxcb;
757 ER ercd;
758
759 LOG_REF_MTX_ENTER(mtxid, pk_rmtx);
760 CHECK_TSKCTX_UNL();
761 CHECK_MTXID(mtxid);
762 p_mtxcb = get_mtxcb(mtxid);
763
764 t_lock_cpu();
765 if (p_mtxcb->p_mtxinib->mtxatr == TA_NOEXS) {
766 ercd = E_NOEXS;
767 }
768 else {
769 pk_rmtx->htskid = (p_mtxcb->p_loctsk != NULL) ? TSKID(p_mtxcb->p_loctsk)
770 : TSK_NONE;
771 pk_rmtx->wtskid = wait_tskid(&(p_mtxcb->wait_queue));
772 ercd = E_OK;
773 }
774 t_unlock_cpu();
775
776 error_exit:
777 LOG_REF_MTX_LEAVE(ercd, pk_rmtx);
778 return(ercd);
779}
780
781#endif /* TOPPERS_ref_mtx */
Note: See TracBrowser for help on using the repository browser.