source: asp3_wo_tecs/trunk/extension/dcre/kernel/mutex.c@ 302

Last change on this file since 302 was 302, checked in by ertl-honda, 7 years ago

TECSレスのASP3の開発のため以下のtrunkからコピー
http://dev.toppers.jp/svn/asp3/branches/WO_TECS-3.C.0

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