source: asp3_tinet_ecnl_arm/trunk/asp3_dcre/kernel/mutex.c@ 352

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

arm向けASP3版ECNLを追加

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