source: asp_ewarm/asp-1.7.0/extension/mutex/kernel/mutex.c@ 61

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

ASP for EWARM のコミット.

File size: 14.0 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-2009 by Embedded and Real-Time Systems Laboratory
7 * Graduate School of Information Science, Nagoya Univ., JAPAN
8 *
9 * ã‹L’˜ìŒ ŽÒ‚́CˆÈ‰º‚Ì(1)`(4)‚ÌðŒ‚ð–ž‚½‚·ê‡‚ÉŒÀ‚èC–{ƒ\ƒtƒgƒEƒF
10 * ƒAi–{ƒ\ƒtƒgƒEƒFƒA‚ð‰ü•Ï‚µ‚½‚à‚Ì‚ðŠÜ‚ށDˆÈ‰º“¯‚¶j‚ðŽg—pE•¡»E‰ü
11 * •ÏEÄ”z•ziˆÈ‰ºC—˜—p‚ƌĂԁj‚·‚邱‚Ƃ𖳏ž‚Å‹–‘ø‚·‚éD
12 * (1) –{ƒ\ƒtƒgƒEƒFƒA‚ðƒ\[ƒXƒR[ƒh‚ÌŒ`‚Å—˜—p‚·‚éê‡‚ɂ́Cã‹L‚Ì’˜ì
13 * Œ •\Ž¦C‚±‚Ì—˜—pðŒ‚¨‚æ‚щº‹L‚Ì–³•ÛØ‹K’肪C‚»‚Ì‚Ü‚Ü‚ÌŒ`‚Ń\[
14 * ƒXƒR[ƒh’†‚ÉŠÜ‚Ü‚ê‚Ä‚¢‚邱‚ƁD
15 * (2) –{ƒ\ƒtƒgƒEƒFƒA‚ðCƒ‰ƒCƒuƒ‰ƒŠŒ`Ž®‚ȂǁC‘¼‚̃\ƒtƒgƒEƒFƒAŠJ”­‚ÉŽg
16 * —p‚Å‚«‚éŒ`‚ōĔz•z‚·‚éê‡‚ɂ́CÄ”z•z‚É”º‚¤ƒhƒLƒ…
17ƒƒ“ƒgi—˜—p
18 * ŽÒƒ}ƒjƒ…
19ƒAƒ‹‚Ȃǁj‚ɁCã‹L‚Ì’˜ìŒ •\Ž¦C‚±‚Ì—˜—pðŒ‚¨‚æ‚щº‹L
20 * ‚Ì–³•ÛØ‹K’è‚ðŒfÚ‚·‚邱‚ƁD
21 * (3) –{ƒ\ƒtƒgƒEƒFƒA‚ðC‹@Ší‚É‘g‚ݍž‚ނȂǁC‘¼‚̃\ƒtƒgƒEƒFƒAŠJ”­‚ÉŽg
22 * —p‚Å‚«‚È‚¢Œ`‚ōĔz•z‚·‚éê‡‚ɂ́CŽŸ‚Ì‚¢‚¸‚ê‚©‚ÌðŒ‚ð–ž‚½‚·‚±
23 * ‚ƁD
24 * (a) Ä”z•z‚É”º‚¤ƒhƒLƒ…
25ƒƒ“ƒgi—˜—pŽÒƒ}ƒjƒ…
26ƒAƒ‹‚Ȃǁj‚ɁCã‹L‚Ì’˜
27 * ìŒ •\Ž¦C‚±‚Ì—˜—pðŒ‚¨‚æ‚щº‹L‚Ì–³•ÛØ‹K’è‚ðŒfÚ‚·‚邱‚ƁD
28 * (b) Ä”z•z‚ÌŒ`‘Ô‚ðC•Ê‚É’è‚ß‚é•û–@‚É‚æ‚Á‚āCTOPPERSƒvƒƒWƒFƒNƒg‚É
29 * •ñ‚·‚邱‚ƁD
30 * (4) –{ƒ\ƒtƒgƒEƒFƒA‚Ì—˜—p‚É‚æ‚è’¼Ú“I‚Ü‚½‚͊ԐړI‚ɐ¶‚¶‚é‚¢‚©‚Ȃ鑹
31 * ŠQ‚©‚ç‚àCã‹L’˜ìŒ ŽÒ‚¨‚æ‚ÑTOPPERSƒvƒƒWƒFƒNƒg‚ð–Ɛӂ·‚邱‚ƁD
32 * ‚Ü‚½C–{ƒ\ƒtƒgƒEƒFƒA‚̃†[ƒU‚Ü‚½‚̓Gƒ“ƒhƒ†[ƒU‚©‚ç‚Ì‚¢‚©‚Ȃ闝
33 * —R‚ÉŠî‚­¿‹‚©‚ç‚àCã‹L’˜ìŒ ŽÒ‚¨‚æ‚ÑTOPPERSƒvƒƒWƒFƒNƒg‚ð
34 * –Ɛӂ·‚邱‚ƁD
35 *
36 * –{ƒ\ƒtƒgƒEƒFƒA‚́C–³•ÛØ‚Å’ñ‹Ÿ‚³‚ê‚Ä‚¢‚é‚à‚Ì‚Å‚ ‚éDã‹L’˜ìŒ ŽÒ‚¨
37 * ‚æ‚ÑTOPPERSƒvƒƒWƒFƒNƒg‚́C–{ƒ\ƒtƒgƒEƒFƒA‚ÉŠÖ‚µ‚āC“Á’è‚ÌŽg—p–Ú“I
38 * ‚ɑ΂·‚é“K‡«‚àŠÜ‚߂āC‚¢‚©‚È‚é•ÛØ‚às‚í‚È‚¢D‚Ü‚½C–{ƒ\ƒtƒgƒEƒF
39 * ƒA‚Ì—˜—p‚É‚æ‚è’¼Ú“I‚Ü‚½‚͊ԐړI‚ɐ¶‚¶‚½‚¢‚©‚Ȃ鑹ŠQ‚ÉŠÖ‚µ‚Ä‚àC‚»
40 * ‚̐ӔC‚𕉂í‚È‚¢D
41 *
42 * @(#) $Id: mutex.c 1694 2010-01-01 15:59:09Z ertl-hiro $
43 */
44
45/*
46 * ƒ~ƒ…
47[ƒeƒbƒNƒX‹@”\
48 */
49
50#include "kernel_impl.h"
51#include "check.h"
52#include "task.h"
53#include "wait.h"
54#include "mutex.h"
55
56/*
57 * ƒgƒŒ[ƒXƒƒOƒ}ƒNƒ‚̃fƒtƒHƒ‹ƒg’è‹`
58 */
59#ifndef LOG_LOC_MTX_ENTER
60#define LOG_LOC_MTX_ENTER(mtxid)
61#endif /* LOG_LOC_MTX_ENTER */
62
63#ifndef LOG_LOC_MTX_LEAVE
64#define LOG_LOC_MTX_LEAVE(ercd)
65#endif /* LOG_LOC_MTX_LEAVE */
66
67#ifndef LOG_PLOC_MTX_ENTER
68#define LOG_PLOC_MTX_ENTER(mtxid)
69#endif /* LOG_PLOC_MTX_ENTER */
70
71#ifndef LOG_PLOC_MTX_LEAVE
72#define LOG_PLOC_MTX_LEAVE(ercd)
73#endif /* LOG_PLOC_MTX_LEAVE */
74
75#ifndef LOG_TLOC_MTX_ENTER
76#define LOG_TLOC_MTX_ENTER(mtxid, tmout)
77#endif /* LOG_TLOC_MTX_ENTER */
78
79#ifndef LOG_TLOC_MTX_LEAVE
80#define LOG_TLOC_MTX_LEAVE(ercd)
81#endif /* LOG_TLOC_MTX_LEAVE */
82
83#ifndef LOG_UNL_MTX_ENTER
84#define LOG_UNL_MTX_ENTER(mtxid)
85#endif /* LOG_UNL_MTX_ENTER */
86
87#ifndef LOG_UNL_MTX_LEAVE
88#define LOG_UNL_MTX_LEAVE(ercd)
89#endif /* LOG_UNL_MTX_LEAVE */
90
91#ifndef LOG_INI_MTX_ENTER
92#define LOG_INI_MTX_ENTER(mtxid)
93#endif /* LOG_INI_MTX_ENTER */
94
95#ifndef LOG_INI_MTX_LEAVE
96#define LOG_INI_MTX_LEAVE(ercd)
97#endif /* LOG_INI_MTX_LEAVE */
98
99#ifndef LOG_REF_MTX_ENTER
100#define LOG_REF_MTX_ENTER(mtxid, pk_rmtx)
101#endif /* LOG_REF_MTX_ENTER */
102
103#ifndef LOG_REF_MTX_LEAVE
104#define LOG_REF_MTX_LEAVE(ercd, pk_rmtx)
105#endif /* LOG_REF_MTX_LEAVE */
106
107/*
108 * ƒ~ƒ…
109[ƒeƒbƒNƒX‚̐”
110 */
111#define tnum_mtx ((uint_t)(tmax_mtxid - TMIN_MTXID + 1))
112
113/*
114 * ƒ~ƒ…
115[ƒeƒbƒNƒXID‚©‚çƒ~ƒ…
116[ƒeƒbƒNƒXŠÇ—ƒuƒƒbƒN‚ðŽæ‚èo‚·‚½‚߂̃}ƒNƒ
117 */
118#define INDEX_MTX(mtxid) ((uint_t)((mtxid) - TMIN_MTXID))
119#define get_mtxcb(mtxid) (&(mtxcb_table[INDEX_MTX(mtxid)]))
120
121/*
122 * ƒ~ƒ…
123[ƒeƒbƒNƒXŠÇ—ƒuƒƒbƒN’†‚Ìmutex_queue‚ւ̃|ƒCƒ“ƒ^‚©‚çCƒ~ƒ…
124[ƒeƒb
125 * ƒNƒXŠÇ—ƒuƒƒbƒN‚ւ̃|ƒCƒ“ƒ^‚ðŽæ‚èo‚·‚½‚߂̃}ƒNƒ
126 */
127#define MTXCB_QUEUE(p_queue) \
128 ((MTXCB *)(((char *) p_queue) - offsetof(MTXCB, mutex_queue)))
129
130/*
131 * ƒ~ƒ…
132[ƒeƒbƒNƒX‚̃vƒƒgƒRƒ‹‚ð”»’f‚·‚éƒ}ƒNƒ
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/*
139 * ƒtƒbƒNƒ‹[ƒ`ƒ“ŒÄo‚µ—p‚̕ϐ”
140 */
141#ifdef TOPPERS_mtxhook
142
143bool_t (*mtxhook_check_ceilpri)(TCB *p_tcb, uint_t bpriority) = NULL;
144bool_t (*mtxhook_scan_ceilmtx)(TCB *p_tcb) = NULL;
145bool_t (*mtxhook_release_all)(TCB *p_tcb) = NULL;
146
147#endif /* TOPPERS_mtxhook */
148
149/*
150 * ƒ~ƒ…
151[ƒeƒbƒNƒX‹@”\‚̏‰Šú‰»
152 */
153#ifdef TOPPERS_mtxini
154
155void
156initialize_mutex(void)
157{
158 uint_t i;
159 MTXCB *p_mtxcb;
160
161 mtxhook_check_ceilpri = mutex_check_ceilpri;
162 mtxhook_scan_ceilmtx = mutex_scan_ceilmtx;
163 mtxhook_release_all = mutex_release_all;
164
165 for (p_mtxcb = mtxcb_table, i = 0; i < tnum_mtx; p_mtxcb++, i++) {
166 queue_initialize(&(p_mtxcb->wait_queue));
167 p_mtxcb->p_mtxinib = &(mtxinib_table[i]);
168 p_mtxcb->p_loctsk = NULL;
169 }
170}
171
172#endif /* TOPPERS_mtxini */
173
174/*
175 * ãŒÀ—Dæ“xˆá”½‚̃`ƒFƒbƒN
176 */
177#ifdef TOPPERS_mtxchk
178
179bool_t
180mutex_check_ceilpri(TCB *p_tcb, uint_t bpriority)
181{
182 QUEUE *p_queue;
183 MTXCB *p_mtxcb;
184
185 /*
186 * ƒ^ƒXƒN‚ªƒƒbƒN‚µ‚Ä‚¢‚é—Dæ“xãŒÀƒ~ƒ…
187[ƒeƒbƒNƒX‚Ì’†‚ŁCãŒÀ—Dæ
188 * “x‚ªbpriority‚æ‚è‚à’á‚¢‚à‚Ì‚ª‚ ‚ê‚΁Cfalse‚ð•Ô‚·D
189 */
190 p_queue = p_tcb->mutex_queue.p_next;
191 while (p_queue != &(p_tcb->mutex_queue)) {
192 p_mtxcb = MTXCB_QUEUE(p_queue);
193 if (MTX_CEILING(p_mtxcb) && bpriority < p_mtxcb->p_mtxinib->ceilpri) {
194 return(false);
195 }
196 p_queue = p_queue->p_next;
197 }
198
199 /*
200 * ƒ^ƒXƒN‚ª—Dæ“xãŒÀƒ~ƒ…
201[ƒeƒbƒNƒX‚̃ƒbƒN‚ð‘Ò‚Á‚Ä‚¢‚éê‡‚ɁC‚»
202 * ‚̏ãŒÀ—Dæ“x‚ªbpriority‚æ‚è‚à’á‚­‚¯‚ê‚΁Cfalse‚ð•Ô‚·D
203 */
204 if (TSTAT_WAIT_MTX(p_tcb->tstat)) {
205 p_mtxcb = ((WINFO_MTX *)(p_tcb->p_winfo))->p_mtxcb;
206 if (MTX_CEILING(p_mtxcb) && bpriority < p_mtxcb->p_mtxinib->ceilpri) {
207 return(false);
208 }
209 }
210
211 /*
212 * ‚¢‚¸‚ê‚ÌðŒ‚É‚à“–‚Ä‚Í‚Ü‚ç‚È‚¯‚ê‚Îtrue‚ð•Ô‚·D
213 */
214 return(true);
215}
216
217#endif /* TOPPERS_mtxchk */
218
219/*
220 * —Dæ“xãŒÀƒ~ƒ…
221[ƒeƒbƒNƒX‚ðƒƒbƒN‚µ‚Ä‚¢‚é‚©‚̃`ƒFƒbƒN
222 */
223#ifdef TOPPERS_mtxscan
224
225bool_t
226mutex_scan_ceilmtx(TCB *p_tcb)
227{
228 QUEUE *p_queue;
229 MTXCB *p_mtxcb;
230
231 p_queue = p_tcb->mutex_queue.p_next;
232 while (p_queue != &(p_tcb->mutex_queue)) {
233 p_mtxcb = MTXCB_QUEUE(p_queue);
234 if (MTX_CEILING(p_mtxcb)) {
235 return(true);
236 }
237 p_queue = p_queue->p_next;
238 }
239 return(false);
240}
241
242#endif /* TOPPERS_mtxscan */
243
244/*
245 * ƒ^ƒXƒN‚ÌŒ»Ý—Dæ“x‚ÌŒvŽZ
246 */
247#ifdef TOPPERS_mtxcalc
248
249uint_t
250mutex_calc_priority(TCB *p_tcb)
251{
252 uint_t priority;
253 QUEUE *p_queue;
254 MTXCB *p_mtxcb;
255
256 priority = p_tcb->bpriority;
257 p_queue = p_tcb->mutex_queue.p_next;
258 while (p_queue != &(p_tcb->mutex_queue)) {
259 p_mtxcb = MTXCB_QUEUE(p_queue);
260 if (MTX_CEILING(p_mtxcb) && p_mtxcb->p_mtxinib->ceilpri < priority) {
261 priority = p_mtxcb->p_mtxinib->ceilpri;
262 }
263 p_queue = p_queue->p_next;
264 }
265 return(priority);
266}
267
268#endif /* TOPPERS_mtxcalc */
269
270/*
271 * —v‘f—Dæ“x‚ªã‚ª‚éi‚Ü‚½‚Í‘‚¦‚éjê‡‚ÌŒ»Ý—Dæ“x•ÏXˆ—
272 */
273Inline bool_t
274mutex_raise_priority(TCB *p_tcb, uint_t newpri)
275{
276 if (newpri < p_tcb->priority) {
277 return(change_priority(p_tcb, newpri, true));
278 }
279 return(false);
280}
281
282/*
283 * —v‘f—Dæ“x‚ª‰º‚ª‚éi‚Ü‚½‚ÍŒ¸‚éjê‡‚ÌŒ»Ý—Dæ“x•ÏXˆ—
284 */
285Inline bool_t
286mutex_drop_priority(TCB *p_tcb, uint_t oldpri)
287{
288 uint_t newpri;
289
290 if (oldpri == p_tcb->priority) {
291 newpri = mutex_calc_priority(p_tcb);
292 if (newpri != p_tcb->priority) {
293 return(change_priority(p_tcb, newpri, true));
294 }
295 }
296 return(false);
297}
298
299/*
300 * ƒ~ƒ…
301[ƒeƒbƒNƒX‚ðƒƒbƒN‚µ‚½ê‡‚̏ˆ—
302 */
303Inline bool_t
304mutex_acquire(TCB *p_loctsk, MTXCB *p_mtxcb)
305{
306 p_mtxcb->p_loctsk = p_loctsk;
307 queue_insert_prev(&(p_loctsk->mutex_queue), &(p_mtxcb->mutex_queue));
308 if (MTX_CEILING(p_mtxcb)) {
309 return(mutex_raise_priority(p_loctsk, p_mtxcb->p_mtxinib->ceilpri));
310 }
311 return(false);
312}
313
314/*
315 * ƒ~ƒ…
316[ƒeƒbƒNƒX‚̃ƒbƒN‰ðœ
317 */
318#ifdef TOPPERS_mtxrel
319
320bool_t
321mutex_release(MTXCB *p_mtxcb)
322{
323 TCB *p_tcb;
324
325 if (queue_empty(&(p_mtxcb->wait_queue))) {
326 p_mtxcb->p_loctsk = NULL;
327 return(false);
328 }
329 else {
330 /*
331 * ƒ~ƒ…
332[ƒeƒbƒNƒX‘Ò‚¿ƒLƒ…
333[‚̐擪ƒ^ƒXƒNip_tcbj‚ɁCƒ~ƒ…
334[ƒeƒb
335 * ƒNƒX‚ðƒƒbƒN‚³‚¹‚éD
336 */
337 p_tcb = (TCB *) queue_delete_next(&(p_mtxcb->wait_queue));
338 wait_dequeue_tmevtb(p_tcb);
339 p_tcb->p_winfo->wercd = E_OK;
340
341 p_mtxcb->p_loctsk = p_tcb;
342 queue_insert_prev(&(p_tcb->mutex_queue), &(p_mtxcb->mutex_queue));
343 if (MTX_CEILING(p_mtxcb)) {
344 if (p_mtxcb->p_mtxinib->ceilpri < p_tcb->priority) {
345 p_tcb->priority = p_mtxcb->p_mtxinib->ceilpri;
346 }
347 }
348 return(make_non_wait(p_tcb));
349 }
350}
351
352#endif /* TOPPERS_mtxrel */
353
354/*
355 * ƒ^ƒXƒN‚ªƒƒbƒN‚µ‚Ä‚¢‚é‚·‚ׂẴ~ƒ…
356[ƒeƒbƒNƒX‚̃ƒbƒN‰ðœ
357 */
358#ifdef TOPPERS_mtxrela
359
360bool_t
361mutex_release_all(TCB *p_tcb)
362{
363 MTXCB *p_mtxcb;
364 bool_t dspreq = false;
365
366 while (!queue_empty(&(p_tcb->mutex_queue))) {
367 p_mtxcb = MTXCB_QUEUE(p_tcb->mutex_queue.p_next);
368 queue_delete(&(p_mtxcb->mutex_queue));
369 if (mutex_release(p_mtxcb)) {
370 dspreq = true;
371 }
372 }
373 return(dspreq);
374}
375
376#endif /* TOPPERS_mtxrela */
377
378/*
379 * ƒ~ƒ…
380[ƒeƒbƒNƒX‚̃ƒbƒN
381 */
382#ifdef TOPPERS_loc_mtx
383
384ER
385loc_mtx(ID mtxid)
386{
387 MTXCB *p_mtxcb;
388 WINFO_MTX winfo_mtx;
389 ER ercd;
390
391 LOG_LOC_MTX_ENTER(mtxid);
392 CHECK_DISPATCH();
393 CHECK_MTXID(mtxid);
394 p_mtxcb = get_mtxcb(mtxid);
395
396 t_lock_cpu();
397 if (MTX_CEILING(p_mtxcb)
398 && p_runtsk->bpriority < p_mtxcb->p_mtxinib->ceilpri) {
399 ercd = E_ILUSE;
400 }
401 else if (p_mtxcb->p_loctsk == NULL) {
402 (void) mutex_acquire(p_runtsk, p_mtxcb);
403 /*
404 * —Dæ“xãŒÀƒ~ƒ…
405[ƒeƒbƒNƒX‚ðƒƒbƒN‚µ‚½ê‡Cp_runtsk‚Ì—Dæ“x
406 * ‚ªã‚ª‚é‰Â”\«‚ª‚ ‚邪CƒfƒBƒXƒpƒbƒ`‚ª•K—v‚ɂȂ邱‚Æ‚Í‚È‚¢D
407 */
408 assert(!(p_runtsk != p_schedtsk && dspflg));
409 ercd = E_OK;
410 }
411 else if (p_mtxcb->p_loctsk == p_runtsk) {
412 ercd = E_ILUSE;
413 }
414 else {
415 p_runtsk->tstat = (TS_WAITING | TS_WAIT_MTX);
416 wobj_make_wait((WOBJCB *) p_mtxcb, (WINFO_WOBJ *) &winfo_mtx);
417 dispatch();
418 ercd = winfo_mtx.winfo.wercd;
419 }
420 t_unlock_cpu();
421
422 error_exit:
423 LOG_LOC_MTX_LEAVE(ercd);
424 return(ercd);
425}
426
427#endif /* TOPPERS_loc_mtx */
428
429/*
430 * ƒ~ƒ…
431[ƒeƒbƒNƒX‚̃ƒbƒNiƒ|[ƒŠƒ“ƒOj
432 */
433#ifdef TOPPERS_ploc_mtx
434
435ER
436ploc_mtx(ID mtxid)
437{
438 MTXCB *p_mtxcb;
439 ER ercd;
440
441 LOG_PLOC_MTX_ENTER(mtxid);
442 CHECK_TSKCTX_UNL();
443 CHECK_MTXID(mtxid);
444 p_mtxcb = get_mtxcb(mtxid);
445
446 t_lock_cpu();
447 if (MTX_CEILING(p_mtxcb)
448 && p_runtsk->bpriority < p_mtxcb->p_mtxinib->ceilpri) {
449 ercd = E_ILUSE;
450 }
451 else if (p_mtxcb->p_loctsk == NULL) {
452 (void) mutex_acquire(p_runtsk, p_mtxcb);
453 /*
454 * —Dæ“xãŒÀƒ~ƒ…
455[ƒeƒbƒNƒX‚ðƒƒbƒN‚µ‚½ê‡Cp_runtsk‚Ì—Dæ“x
456 * ‚ªã‚ª‚é‰Â”\«‚ª‚ ‚邪CƒfƒBƒXƒpƒbƒ`‚ª•K—v‚ɂȂ邱‚Æ‚Í‚È‚¢D
457 */
458 assert(!(p_runtsk != p_schedtsk && dspflg));
459 ercd = E_OK;
460 }
461 else if (p_mtxcb->p_loctsk == p_runtsk) {
462 ercd = E_ILUSE;
463 }
464 else {
465 ercd = E_TMOUT;
466 }
467 t_unlock_cpu();
468
469 error_exit:
470 LOG_PLOC_MTX_LEAVE(ercd);
471 return(ercd);
472}
473
474#endif /* TOPPERS_ploc_mtx */
475
476/*
477 * ƒ~ƒ…
478[ƒeƒbƒNƒX‚̃ƒbƒNiƒ^ƒCƒ€ƒAƒEƒg‚ ‚èj
479 */
480#ifdef TOPPERS_tloc_mtx
481
482ER
483tloc_mtx(ID mtxid, TMO tmout)
484{
485 MTXCB *p_mtxcb;
486 WINFO_MTX winfo_mtx;
487 TMEVTB tmevtb;
488 ER ercd;
489
490 LOG_TLOC_MTX_ENTER(mtxid, tmout);
491 CHECK_DISPATCH();
492 CHECK_MTXID(mtxid);
493 CHECK_TMOUT(tmout);
494 p_mtxcb = get_mtxcb(mtxid);
495
496 t_lock_cpu();
497 if (MTX_CEILING(p_mtxcb)
498 && p_runtsk->bpriority < p_mtxcb->p_mtxinib->ceilpri) {
499 ercd = E_ILUSE;
500 }
501 else if (p_mtxcb->p_loctsk == NULL) {
502 (void) mutex_acquire(p_runtsk, p_mtxcb);
503 /*
504 * —Dæ“xãŒÀƒ~ƒ…
505[ƒeƒbƒNƒX‚ðƒƒbƒN‚µ‚½ê‡Cp_runtsk‚Ì—Dæ“x
506 * ‚ªã‚ª‚é‰Â”\«‚ª‚ ‚邪CƒfƒBƒXƒpƒbƒ`‚ª•K—v‚ɂȂ邱‚Æ‚Í‚È‚¢D
507 */
508 assert(!(p_runtsk != p_schedtsk && dspflg));
509 ercd = E_OK;
510 }
511 else if (p_mtxcb->p_loctsk == p_runtsk) {
512 ercd = E_ILUSE;
513 }
514 else if (tmout == TMO_POL) {
515 ercd = E_TMOUT;
516 }
517 else {
518 p_runtsk->tstat = (TS_WAITING | TS_WAIT_MTX);
519 wobj_make_wait_tmout((WOBJCB *) p_mtxcb, (WINFO_WOBJ *) &winfo_mtx,
520 &tmevtb, tmout);
521 dispatch();
522 ercd = winfo_mtx.winfo.wercd;
523 }
524 t_unlock_cpu();
525
526 error_exit:
527 LOG_TLOC_MTX_LEAVE(ercd);
528 return(ercd);
529}
530
531#endif /* TOPPERS_tloc_mtx */
532
533/*
534 * ƒ~ƒ…
535[ƒeƒbƒNƒX‚̃ƒbƒN‰ðœ
536 */
537#ifdef TOPPERS_unl_mtx
538
539ER
540unl_mtx(ID mtxid)
541{
542 MTXCB *p_mtxcb;
543 bool_t dspreq = false;
544 ER ercd;
545
546 LOG_UNL_MTX_ENTER(mtxid);
547 CHECK_TSKCTX_UNL();
548 CHECK_MTXID(mtxid);
549 p_mtxcb = get_mtxcb(mtxid);
550
551 t_lock_cpu();
552 if (p_mtxcb->p_loctsk != p_runtsk) {
553 ercd = E_ILUSE;
554 }
555 else {
556 queue_delete(&(p_mtxcb->mutex_queue));
557 if (MTX_CEILING(p_mtxcb)) {
558 if (mutex_drop_priority(p_runtsk, p_mtxcb->p_mtxinib->ceilpri)) {
559 dspreq = true;
560 }
561 }
562 if (mutex_release(p_mtxcb)) {
563 dspreq = true;
564 }
565 if (dspreq) {
566 dispatch();
567 }
568 ercd = E_OK;
569 }
570 t_unlock_cpu();
571
572 error_exit:
573 LOG_UNL_MTX_LEAVE(ercd);
574 return(ercd);
575}
576
577#endif /* TOPPERS_unl_mtx */
578
579/*
580 * ƒ~ƒ…
581[ƒeƒbƒNƒX‚̏‰Šú‰»
582 */
583#ifdef TOPPERS_ini_mtx
584
585ER
586ini_mtx(ID mtxid)
587{
588 MTXCB *p_mtxcb;
589 TCB *p_loctsk;
590 bool_t dspreq;
591 ER ercd;
592
593 LOG_INI_MTX_ENTER(mtxid);
594 CHECK_TSKCTX_UNL();
595 CHECK_MTXID(mtxid);
596 p_mtxcb = get_mtxcb(mtxid);
597
598 t_lock_cpu();
599 dspreq = init_wait_queue(&(p_mtxcb->wait_queue));
600 p_loctsk = p_mtxcb->p_loctsk;
601 if (p_loctsk != NULL) {
602 queue_delete(&(p_mtxcb->mutex_queue));
603 p_mtxcb->p_loctsk = NULL;
604 if (MTX_CEILING(p_mtxcb)) {
605 if (mutex_drop_priority(p_loctsk, p_mtxcb->p_mtxinib->ceilpri)) {
606 dspreq = true;
607 }
608 }
609 }
610 if (dspreq) {
611 dispatch();
612 }
613 ercd = E_OK;
614 t_unlock_cpu();
615
616 error_exit:
617 LOG_INI_MTX_LEAVE(ercd);
618 return(ercd);
619}
620
621#endif /* TOPPERS_ini_mtx */
622
623/*
624 * ƒ~ƒ…
625[ƒeƒbƒNƒX‚̏ó‘ÔŽQÆ
626 */
627#ifdef TOPPERS_ref_mtx
628
629ER
630ref_mtx(ID mtxid, T_RMTX *pk_rmtx)
631{
632 MTXCB *p_mtxcb;
633 ER ercd;
634
635 LOG_REF_MTX_ENTER(mtxid, pk_rmtx);
636 CHECK_TSKCTX_UNL();
637 CHECK_MTXID(mtxid);
638 p_mtxcb = get_mtxcb(mtxid);
639
640 t_lock_cpu();
641 pk_rmtx->htskid = (p_mtxcb->p_loctsk != NULL) ? TSKID(p_mtxcb->p_loctsk)
642 : TSK_NONE;
643 pk_rmtx->wtskid = wait_tskid(&(p_mtxcb->wait_queue));
644 ercd = E_OK;
645 t_unlock_cpu();
646
647 error_exit:
648 LOG_REF_MTX_LEAVE(ercd, pk_rmtx);
649 return(ercd);
650}
651
652#endif /* TOPPERS_ref_mtx */
Note: See TracBrowser for help on using the repository browser.