source: azure_iot_hub/trunk/asp3_dcre/kernel/mutex.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: 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 * 上記著作権者
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 388 2019-05-22 11:25:18Z coas-nagasima $
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 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 ATR mtxatr;
394 PRI ceilpri;
395 ER ercd;
396
397 LOG_ACRE_MTX_ENTER(pk_cmtx);
398 CHECK_TSKCTX_UNL(); /*[NGKI2023][NGKI2024]*/
399
400 mtxatr = pk_cmtx->mtxatr;
401 ceilpri = pk_cmtx->ceilpri;
402
403 if (mtxatr == TA_CEILING) {
404 CHECK_PAR(VALID_TPRI(ceilpri)); /*ï¼»NGKI2037ï¼½*/
405 }
406 else {
407 CHECK_RSATR(mtxatr, TA_TPRI); /*ï¼»NGKI2025ï¼½*/
408 }
409
410 lock_cpu();
411 if (tnum_mtx == 0 || queue_empty(&free_mtxcb)) {
412 ercd = E_NOID; /*ï¼»NGKI2031ï¼½*/
413 }
414 else {
415 p_mtxcb = ((MTXCB *) queue_delete_next(&free_mtxcb));
416 p_mtxinib = (MTXINIB *)(p_mtxcb->p_mtxinib);
417 p_mtxinib->mtxatr = mtxatr;
418 p_mtxinib->ceilpri = INT_PRIORITY(ceilpri);
419
420 queue_initialize(&(p_mtxcb->wait_queue));
421 p_mtxcb->p_loctsk = NULL; /*ï¼»NGKI2033ï¼½*/
422 ercd = MTXID(p_mtxcb);
423 }
424 unlock_cpu();
425
426 error_exit:
427 LOG_ACRE_MTX_LEAVE(ercd);
428 return(ercd);
429}
430
431#endif /* TOPPERS_acre_mtx */
432
433/*
434 * ミューテックスの削除[NGKI2056]
435 */
436#ifdef TOPPERS_del_mtx
437
438ER
439del_mtx(ID mtxid)
440{
441 MTXCB *p_mtxcb, **pp_prevmtx;
442 MTXINIB *p_mtxinib;
443 TCB *p_loctsk;
444 ER ercd;
445
446 LOG_DEL_MTX_ENTER(mtxid);
447 CHECK_TSKCTX_UNL(); /*[NGKI2057][NGKI2058]*/
448 CHECK_ID(VALID_MTXID(mtxid)); /*ï¼»NGKI2059ï¼½*/
449 p_mtxcb = get_mtxcb(mtxid);
450
451 lock_cpu();
452 if (p_mtxcb->p_mtxinib->mtxatr == TA_NOEXS) {
453 ercd = E_NOEXS; /*ï¼»NGKI2060ï¼½*/
454 }
455 else if (mtxid <= tmax_smtxid) {
456 ercd = E_OBJ; /*ï¼»NGKI2062ï¼½*/
457 }
458 else {
459 init_wait_queue(&(p_mtxcb->wait_queue)); /*ï¼»NGKI2065ï¼½*/
460 p_loctsk = p_mtxcb->p_loctsk;
461 if (p_loctsk != NULL) {
462 /*
463 * p_loctskがロックしているミューテックスのリストから対象
464 * ミュークスを削除し,必
465要な場合にはp_loctskの現在優å…
466ˆåº¦
467 * を変更する[NGKI2064].
468 */
469 pp_prevmtx = &(p_loctsk->p_lastmtx);
470 while (*pp_prevmtx != NULL) {
471 if (*pp_prevmtx == p_mtxcb) {
472 *pp_prevmtx = p_mtxcb->p_prevmtx;
473 break;
474 }
475 pp_prevmtx = &((*pp_prevmtx)->p_prevmtx);
476 }
477 mutex_drop_priority(p_loctsk, p_mtxcb);
478 }
479 p_mtxinib = (MTXINIB *)(p_mtxcb->p_mtxinib);
480 p_mtxinib->mtxatr = TA_NOEXS; /*ï¼»NGKI2063ï¼½*/
481 queue_insert_prev(&free_mtxcb, &(p_mtxcb->wait_queue));
482 if (p_runtsk != p_schedtsk) {
483 dispatch();
484 }
485 ercd = E_OK;
486 }
487 unlock_cpu();
488
489 error_exit:
490 LOG_DEL_MTX_LEAVE(ercd);
491 return(ercd);
492}
493
494#endif /* TOPPERS_del_mtx */
495
496/*
497 * ミューテックスのロック
498 */
499#ifdef TOPPERS_loc_mtx
500
501ER
502loc_mtx(ID mtxid)
503{
504 MTXCB *p_mtxcb;
505 WINFO_MTX winfo_mtx;
506 ER ercd;
507
508 LOG_LOC_MTX_ENTER(mtxid);
509 CHECK_DISPATCH();
510 CHECK_ID(VALID_MTXID(mtxid));
511 p_mtxcb = get_mtxcb(mtxid);
512
513 lock_cpu_dsp();
514 if (p_mtxcb->p_mtxinib->mtxatr == TA_NOEXS) {
515 ercd = E_NOEXS;
516 }
517 else if (p_runtsk->raster) {
518 ercd = E_RASTER;
519 }
520 else if (MTX_CEILING(p_mtxcb)
521 && p_runtsk->bpriority < p_mtxcb->p_mtxinib->ceilpri) {
522 ercd = E_ILUSE;
523 }
524 else if (p_mtxcb->p_loctsk == NULL) {
525 mutex_acquire(p_runtsk, p_mtxcb);
526 /*
527 * 優å…
528ˆåº¦ä¸Šé™ãƒŸãƒ¥ãƒ¼ãƒ†ãƒƒã‚¯ã‚¹ã‚’ロックした場合,p_runtskの優å…
529ˆåº¦
530 * が上がる可能性があるが,ディスパッチが必
531要になることはない.
532 */
533 assert(p_runtsk == p_schedtsk);
534 ercd = E_OK;
535 }
536 else if (p_mtxcb->p_loctsk == p_runtsk) {
537 ercd = E_OBJ;
538 }
539 else {
540 p_runtsk->tstat = TS_WAITING_MTX;
541 wobj_make_wait((WOBJCB *) p_mtxcb, (WINFO_WOBJ *) &winfo_mtx);
542 dispatch();
543 ercd = winfo_mtx.winfo.wercd;
544 }
545 unlock_cpu_dsp();
546
547 error_exit:
548 LOG_LOC_MTX_LEAVE(ercd);
549 return(ercd);
550}
551
552#endif /* TOPPERS_loc_mtx */
553
554/*
555 * ミューテックスのロック(ポーリング)
556 */
557#ifdef TOPPERS_ploc_mtx
558
559ER
560ploc_mtx(ID mtxid)
561{
562 MTXCB *p_mtxcb;
563 ER ercd;
564
565 LOG_PLOC_MTX_ENTER(mtxid);
566 CHECK_TSKCTX_UNL();
567 CHECK_ID(VALID_MTXID(mtxid));
568 p_mtxcb = get_mtxcb(mtxid);
569
570 lock_cpu();
571 if (p_mtxcb->p_mtxinib->mtxatr == TA_NOEXS) {
572 ercd = E_NOEXS;
573 }
574 else if (MTX_CEILING(p_mtxcb)
575 && p_runtsk->bpriority < p_mtxcb->p_mtxinib->ceilpri) {
576 ercd = E_ILUSE;
577 }
578 else if (p_mtxcb->p_loctsk == NULL) {
579 mutex_acquire(p_runtsk, p_mtxcb);
580 /*
581 * 優å…
582ˆåº¦ä¸Šé™ãƒŸãƒ¥ãƒ¼ãƒ†ãƒƒã‚¯ã‚¹ã‚’ロックした場合,p_runtskの優å…
583ˆåº¦
584 * が上がる可能性があるが,ディスパッチが必
585要になることはない.
586 */
587 assert(p_runtsk == p_schedtsk);
588 ercd = E_OK;
589 }
590 else if (p_mtxcb->p_loctsk == p_runtsk) {
591 ercd = E_OBJ;
592 }
593 else {
594 ercd = E_TMOUT;
595 }
596 unlock_cpu();
597
598 error_exit:
599 LOG_PLOC_MTX_LEAVE(ercd);
600 return(ercd);
601}
602
603#endif /* TOPPERS_ploc_mtx */
604
605/*
606 * ミューテックスのロック(タイムアウトあり)
607 */
608#ifdef TOPPERS_tloc_mtx
609
610ER
611tloc_mtx(ID mtxid, TMO tmout)
612{
613 MTXCB *p_mtxcb;
614 WINFO_MTX winfo_mtx;
615 TMEVTB tmevtb;
616 ER ercd;
617
618 LOG_TLOC_MTX_ENTER(mtxid, tmout);
619 CHECK_DISPATCH();
620 CHECK_ID(VALID_MTXID(mtxid));
621 CHECK_PAR(VALID_TMOUT(tmout));
622 p_mtxcb = get_mtxcb(mtxid);
623
624 lock_cpu_dsp();
625 if (p_mtxcb->p_mtxinib->mtxatr == TA_NOEXS) {
626 ercd = E_NOEXS;
627 }
628 else if (p_runtsk->raster) {
629 ercd = E_RASTER;
630 }
631 else if (MTX_CEILING(p_mtxcb)
632 && p_runtsk->bpriority < p_mtxcb->p_mtxinib->ceilpri) {
633 ercd = E_ILUSE;
634 }
635 else if (p_mtxcb->p_loctsk == NULL) {
636 mutex_acquire(p_runtsk, p_mtxcb);
637 /*
638 * 優å…
639ˆåº¦ä¸Šé™ãƒŸãƒ¥ãƒ¼ãƒ†ãƒƒã‚¯ã‚¹ã‚’ロックした場合,p_runtskの優å…
640ˆåº¦
641 * が上がる可能性があるが,ディスパッチが必
642要になることはない.
643 */
644 assert(p_runtsk == p_schedtsk);
645 ercd = E_OK;
646 }
647 else if (p_mtxcb->p_loctsk == p_runtsk) {
648 ercd = E_OBJ;
649 }
650 else if (tmout == TMO_POL) {
651 ercd = E_TMOUT;
652 }
653 else {
654 p_runtsk->tstat = TS_WAITING_MTX;
655 wobj_make_wait_tmout((WOBJCB *) p_mtxcb, (WINFO_WOBJ *) &winfo_mtx,
656 &tmevtb, tmout);
657 dispatch();
658 ercd = winfo_mtx.winfo.wercd;
659 }
660 unlock_cpu_dsp();
661
662 error_exit:
663 LOG_TLOC_MTX_LEAVE(ercd);
664 return(ercd);
665}
666
667#endif /* TOPPERS_tloc_mtx */
668
669/*
670 * ミューテックスのロック解除
671 */
672#ifdef TOPPERS_unl_mtx
673
674ER
675unl_mtx(ID mtxid)
676{
677 MTXCB *p_mtxcb;
678 ER ercd;
679
680 LOG_UNL_MTX_ENTER(mtxid);
681 CHECK_TSKCTX_UNL();
682 CHECK_ID(VALID_MTXID(mtxid));
683 p_mtxcb = get_mtxcb(mtxid);
684
685 lock_cpu();
686 if (p_mtxcb->p_mtxinib->mtxatr == TA_NOEXS) {
687 ercd = E_NOEXS;
688 }
689 else if (p_mtxcb != p_runtsk->p_lastmtx) {
690 ercd = E_OBJ;
691 }
692 else {
693 p_runtsk->p_lastmtx = p_mtxcb->p_prevmtx;
694 mutex_drop_priority(p_runtsk, p_mtxcb);
695 mutex_release(p_mtxcb);
696 if (p_runtsk != p_schedtsk) {
697 dispatch();
698 }
699 ercd = E_OK;
700 }
701 unlock_cpu();
702
703 error_exit:
704 LOG_UNL_MTX_LEAVE(ercd);
705 return(ercd);
706}
707
708#endif /* TOPPERS_unl_mtx */
709
710/*
711 * ミューテックスの再初期化
712 */
713#ifdef TOPPERS_ini_mtx
714
715ER
716ini_mtx(ID mtxid)
717{
718 MTXCB *p_mtxcb, **pp_prevmtx;
719 TCB *p_loctsk;
720 ER ercd;
721
722 LOG_INI_MTX_ENTER(mtxid);
723 CHECK_TSKCTX_UNL();
724 CHECK_ID(VALID_MTXID(mtxid));
725 p_mtxcb = get_mtxcb(mtxid);
726
727 lock_cpu();
728 if (p_mtxcb->p_mtxinib->mtxatr == TA_NOEXS) {
729 ercd = E_NOEXS;
730 }
731 else {
732 init_wait_queue(&(p_mtxcb->wait_queue));
733 p_loctsk = p_mtxcb->p_loctsk;
734 if (p_loctsk != NULL) {
735 p_mtxcb->p_loctsk = NULL;
736 pp_prevmtx = &(p_loctsk->p_lastmtx);
737 while (*pp_prevmtx != NULL) {
738 if (*pp_prevmtx == p_mtxcb) {
739 *pp_prevmtx = p_mtxcb->p_prevmtx;
740 break;
741 }
742 pp_prevmtx = &((*pp_prevmtx)->p_prevmtx);
743 }
744 mutex_drop_priority(p_loctsk, p_mtxcb);
745 }
746 if (p_runtsk != p_schedtsk) {
747 dispatch();
748 }
749 ercd = E_OK;
750 }
751 unlock_cpu();
752
753 error_exit:
754 LOG_INI_MTX_LEAVE(ercd);
755 return(ercd);
756}
757
758#endif /* TOPPERS_ini_mtx */
759
760/*
761 * ミューテックスの状æ…
762‹å‚ç…
763§
764 */
765#ifdef TOPPERS_ref_mtx
766
767ER
768ref_mtx(ID mtxid, T_RMTX *pk_rmtx)
769{
770 MTXCB *p_mtxcb;
771 ER ercd;
772
773 LOG_REF_MTX_ENTER(mtxid, pk_rmtx);
774 CHECK_TSKCTX_UNL();
775 CHECK_ID(VALID_MTXID(mtxid));
776 p_mtxcb = get_mtxcb(mtxid);
777
778 lock_cpu();
779 if (p_mtxcb->p_mtxinib->mtxatr == TA_NOEXS) {
780 ercd = E_NOEXS;
781 }
782 else {
783 pk_rmtx->htskid = (p_mtxcb->p_loctsk != NULL) ? TSKID(p_mtxcb->p_loctsk)
784 : TSK_NONE;
785 pk_rmtx->wtskid = wait_tskid(&(p_mtxcb->wait_queue));
786 ercd = E_OK;
787 }
788 unlock_cpu();
789
790 error_exit:
791 LOG_REF_MTX_LEAVE(ercd, pk_rmtx);
792 return(ercd);
793}
794
795#endif /* TOPPERS_ref_mtx */
Note: See TracBrowser for help on using the repository browser.