source: asp_wo_cfg/trunk/kernel/task_sync.c@ 72

Last change on this file since 72 was 49, checked in by ertl-hiro, 12 years ago

asp_wo_kernelをコミット。

  • Property svn:keywords set to Id
File size: 10.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) 2000-2003 by Embedded and Real-Time Systems Laboratory
7 * Toyohashi Univ. of Technology, JAPAN
8 * Copyright (C) 2005-2012 by Embedded and Real-Time Systems Laboratory
9 * Graduate School of Information Science, Nagoya Univ., JAPAN
10 *
11 * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
12 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
13 * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
14 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
15 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
16 * スコード中に含まれていること.
17 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
18 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
19 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
20 * の無保証規定を掲載すること.
21 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
22 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
23 * と.
24 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
25 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
26 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
27 * 報告すること.
28 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
29 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
30 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
31 * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
32 * 免責すること.
33 *
34 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
35 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
36 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
37 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
38 * の責任を負わない.
39 *
40 * @(#) $Id: task_sync.c 49 2012-09-06 04:41:53Z ertl-hiro $
41 */
42
43/*
44 * タスク付属同期機能
45 */
46
47#include "kernel_impl.h"
48#include "check.h"
49#include "task.h"
50#include "wait.h"
51
52/*
53 * トレースログマクロのデフォルト定義
54 */
55#ifndef LOG_SLP_TSK_ENTER
56#define LOG_SLP_TSK_ENTER()
57#endif /* LOG_SLP_TSK_ENTER */
58
59#ifndef LOG_SLP_TSK_LEAVE
60#define LOG_SLP_TSK_LEAVE(ercd)
61#endif /* LOG_SLP_TSK_LEAVE */
62
63#ifndef LOG_TSLP_TSK_ENTER
64#define LOG_TSLP_TSK_ENTER(tmout)
65#endif /* LOG_TSLP_TSK_ENTER */
66
67#ifndef LOG_TSLP_TSK_LEAVE
68#define LOG_TSLP_TSK_LEAVE(ercd)
69#endif /* LOG_TSLP_TSK_LEAVE */
70
71#ifndef LOG_WUP_TSK_ENTER
72#define LOG_WUP_TSK_ENTER(tskid)
73#endif /* LOG_WUP_TSK_ENTER */
74
75#ifndef LOG_WUP_TSK_LEAVE
76#define LOG_WUP_TSK_LEAVE(ercd)
77#endif /* LOG_WUP_TSK_LEAVE */
78
79#ifndef LOG_IWUP_TSK_ENTER
80#define LOG_IWUP_TSK_ENTER(tskid)
81#endif /* LOG_IWUP_TSK_ENTER */
82
83#ifndef LOG_IWUP_TSK_LEAVE
84#define LOG_IWUP_TSK_LEAVE(ercd)
85#endif /* LOG_IWUP_TSK_LEAVE */
86
87#ifndef LOG_CAN_WUP_ENTER
88#define LOG_CAN_WUP_ENTER(tskid)
89#endif /* LOG_CAN_WUP_ENTER */
90
91#ifndef LOG_CAN_WUP_LEAVE
92#define LOG_CAN_WUP_LEAVE(ercd)
93#endif /* LOG_CAN_WUP_LEAVE */
94
95#ifndef LOG_REL_WAI_ENTER
96#define LOG_REL_WAI_ENTER(tskid)
97#endif /* LOG_REL_WAI_ENTER */
98
99#ifndef LOG_REL_WAI_LEAVE
100#define LOG_REL_WAI_LEAVE(ercd)
101#endif /* LOG_REL_WAI_LEAVE */
102
103#ifndef LOG_IREL_WAI_ENTER
104#define LOG_IREL_WAI_ENTER(tskid)
105#endif /* LOG_IREL_WAI_ENTER */
106
107#ifndef LOG_IREL_WAI_LEAVE
108#define LOG_IREL_WAI_LEAVE(ercd)
109#endif /* LOG_IREL_WAI_LEAVE */
110
111#ifndef LOG_SUS_TSK_ENTER
112#define LOG_SUS_TSK_ENTER(tskid)
113#endif /* LOG_SUS_TSK_ENTER */
114
115#ifndef LOG_SUS_TSK_LEAVE
116#define LOG_SUS_TSK_LEAVE(ercd)
117#endif /* LOG_SUS_TSK_LEAVE */
118
119#ifndef LOG_RSM_TSK_ENTER
120#define LOG_RSM_TSK_ENTER(tskid)
121#endif /* LOG_RSM_TSK_ENTER */
122
123#ifndef LOG_RSM_TSK_LEAVE
124#define LOG_RSM_TSK_LEAVE(ercd)
125#endif /* LOG_RSM_TSK_LEAVE */
126
127#ifndef LOG_DLY_TSK_ENTER
128#define LOG_DLY_TSK_ENTER(dlytim)
129#endif /* LOG_DLY_TSK_ENTER */
130
131#ifndef LOG_DLY_TSK_LEAVE
132#define LOG_DLY_TSK_LEAVE(ercd)
133#endif /* LOG_DLY_TSK_LEAVE */
134
135/*
136 * 起床待ち
137 */
138#ifdef TOPPERS_slp_tsk
139
140ER
141slp_tsk(void)
142{
143 WINFO winfo;
144 ER ercd;
145
146 LOG_SLP_TSK_ENTER();
147 CHECK_DISPATCH();
148
149 t_lock_cpu();
150 if (p_runtsk->wupque) {
151 p_runtsk->wupque = false;
152 ercd = E_OK;
153 }
154 else {
155 p_runtsk->tstat = (TS_WAITING | TS_WAIT_SLP);
156 make_wait(&winfo);
157 LOG_TSKSTAT(p_runtsk);
158 dispatch();
159 ercd = winfo.wercd;
160 }
161 t_unlock_cpu();
162
163 error_exit:
164 LOG_SLP_TSK_LEAVE(ercd);
165 return(ercd);
166}
167
168#endif /* TOPPERS_slp_tsk */
169
170/*
171 * 起床待ち(タイムアウトあり)
172 */
173#ifdef TOPPERS_tslp_tsk
174
175ER
176tslp_tsk(TMO tmout)
177{
178 WINFO winfo;
179 TMEVTB tmevtb;
180 ER ercd;
181
182 LOG_TSLP_TSK_ENTER(tmout);
183 CHECK_DISPATCH();
184 CHECK_TMOUT(tmout);
185
186 t_lock_cpu();
187 if (p_runtsk->wupque) {
188 p_runtsk->wupque = false;
189 ercd = E_OK;
190 }
191 else if (tmout == TMO_POL) {
192 ercd = E_TMOUT;
193 }
194 else {
195 p_runtsk->tstat = (TS_WAITING | TS_WAIT_SLP);
196 make_wait_tmout(&winfo, &tmevtb, tmout);
197 LOG_TSKSTAT(p_runtsk);
198 dispatch();
199 ercd = winfo.wercd;
200 }
201 t_unlock_cpu();
202
203 error_exit:
204 LOG_TSLP_TSK_LEAVE(ercd);
205 return(ercd);
206}
207
208#endif /* TOPPERS_tslp_tsk */
209
210/*
211 * タスクの起床
212 */
213#ifdef TOPPERS_wup_tsk
214
215ER
216wup_tsk(ID tskid)
217{
218 TCB *p_tcb;
219 ER ercd;
220
221 LOG_WUP_TSK_ENTER(tskid);
222 CHECK_TSKCTX_UNL();
223 CHECK_TSKID_SELF(tskid);
224 p_tcb = get_tcb_self(tskid);
225 CHECK_NOEXS(p_tcb->p_tinib->tskatr);
226
227 t_lock_cpu();
228 if (TSTAT_DORMANT(p_tcb->tstat)) {
229 ercd = E_OBJ;
230 }
231 else if (TSTAT_WAIT_SLP(p_tcb->tstat)) {
232 if (wait_complete(p_tcb)) {
233 dispatch();
234 }
235 ercd = E_OK;
236 }
237 else if (!(p_tcb->wupque)) {
238 p_tcb->wupque = true;
239 ercd = E_OK;
240 }
241 else {
242 ercd = E_QOVR;
243 }
244 t_unlock_cpu();
245
246 error_exit:
247 LOG_WUP_TSK_LEAVE(ercd);
248 return(ercd);
249}
250
251#endif /* TOPPERS_wup_tsk */
252
253/*
254 * タスクの起床(非タスクコンテキスト用)
255 */
256#ifdef TOPPERS_iwup_tsk
257
258ER
259iwup_tsk(ID tskid)
260{
261 TCB *p_tcb;
262 ER ercd;
263
264 LOG_IWUP_TSK_ENTER(tskid);
265 CHECK_INTCTX_UNL();
266 CHECK_TSKID(tskid);
267 p_tcb = get_tcb(tskid);
268 CHECK_NOEXS(p_tcb->p_tinib->tskatr);
269
270 i_lock_cpu();
271 if (TSTAT_DORMANT(p_tcb->tstat)) {
272 ercd = E_OBJ;
273 }
274 else if (TSTAT_WAIT_SLP(p_tcb->tstat)) {
275 if (wait_complete(p_tcb)) {
276 reqflg = true;
277 }
278 ercd = E_OK;
279 }
280 else if (!(p_tcb->wupque)) {
281 p_tcb->wupque = true;
282 ercd = E_OK;
283 }
284 else {
285 ercd = E_QOVR;
286 }
287 i_unlock_cpu();
288
289 error_exit:
290 LOG_IWUP_TSK_LEAVE(ercd);
291 return(ercd);
292}
293
294#endif /* TOPPERS_iwup_tsk */
295
296/*
297 * タスク起床要求のキャンセル
298 */
299#ifdef TOPPERS_can_wup
300
301ER_UINT
302can_wup(ID tskid)
303{
304 TCB *p_tcb;
305 ER_UINT ercd;
306
307 LOG_CAN_WUP_ENTER(tskid);
308 CHECK_TSKCTX_UNL();
309 CHECK_TSKID_SELF(tskid);
310 p_tcb = get_tcb_self(tskid);
311 CHECK_NOEXS(p_tcb->p_tinib->tskatr);
312
313 t_lock_cpu();
314 if (TSTAT_DORMANT(p_tcb->tstat)) {
315 ercd = E_OBJ;
316 }
317 else {
318 ercd = p_tcb->wupque ? 1 : 0;
319 p_tcb->wupque = false;
320 }
321 t_unlock_cpu();
322
323 error_exit:
324 LOG_CAN_WUP_LEAVE(ercd);
325 return(ercd);
326}
327
328#endif /* TOPPERS_can_wup */
329
330/*
331 * 待ち状態の強制解除
332 */
333#ifdef TOPPERS_rel_wai
334
335ER
336rel_wai(ID tskid)
337{
338 TCB *p_tcb;
339 ER ercd;
340
341 LOG_REL_WAI_ENTER(tskid);
342 CHECK_TSKCTX_UNL();
343 CHECK_TSKID(tskid);
344 p_tcb = get_tcb(tskid);
345 CHECK_NOEXS(p_tcb->p_tinib->tskatr);
346
347 t_lock_cpu();
348 if (!TSTAT_WAITING(p_tcb->tstat)) {
349 ercd = E_OBJ;
350 }
351 else {
352 if (wait_release(p_tcb)) {
353 dispatch();
354 }
355 ercd = E_OK;
356 }
357 t_unlock_cpu();
358
359 error_exit:
360 LOG_REL_WAI_LEAVE(ercd);
361 return(ercd);
362}
363
364#endif /* TOPPERS_rel_wai */
365
366/*
367 * 待ち状態の強制解除(非タスクコンテキスト用)
368 */
369#ifdef TOPPERS_irel_wai
370
371ER
372irel_wai(ID tskid)
373{
374 TCB *p_tcb;
375 ER ercd;
376
377 LOG_IREL_WAI_ENTER(tskid);
378 CHECK_INTCTX_UNL();
379 CHECK_TSKID(tskid);
380 p_tcb = get_tcb(tskid);
381 CHECK_NOEXS(p_tcb->p_tinib->tskatr);
382
383 i_lock_cpu();
384 if (!TSTAT_WAITING(p_tcb->tstat)) {
385 ercd = E_OBJ;
386 }
387 else {
388 if (wait_release(p_tcb)) {
389 reqflg = true;
390 }
391 ercd = E_OK;
392 }
393 i_unlock_cpu();
394
395 error_exit:
396 LOG_IREL_WAI_LEAVE(ercd);
397 return(ercd);
398}
399
400#endif /* TOPPERS_irel_wai */
401
402/*
403 * 強制待ち状態への移行
404 */
405#ifdef TOPPERS_sus_tsk
406
407ER
408sus_tsk(ID tskid)
409{
410 TCB *p_tcb;
411 ER ercd;
412
413 LOG_SUS_TSK_ENTER(tskid);
414 CHECK_TSKCTX_UNL();
415 CHECK_TSKID_SELF(tskid);
416 p_tcb = get_tcb_self(tskid);
417 CHECK_NOEXS(p_tcb->p_tinib->tskatr);
418
419 t_lock_cpu();
420 if (p_tcb == p_runtsk && !dspflg) {
421 ercd = E_CTX;
422 }
423 else if (TSTAT_DORMANT(p_tcb->tstat)) {
424 ercd = E_OBJ;
425 }
426 else if (TSTAT_RUNNABLE(p_tcb->tstat)) {
427 /*
428 * 実行できる状態から強制待ち状態への遷移
429 */
430 p_tcb->tstat = TS_SUSPENDED;
431 LOG_TSKSTAT(p_tcb);
432 if (make_non_runnable(p_tcb)) {
433 dispatch();
434 }
435 ercd = E_OK;
436 }
437 else if (TSTAT_SUSPENDED(p_tcb->tstat)) {
438 ercd = E_QOVR;
439 }
440 else {
441 /*
442 * 待ち状態から二重待ち状態への遷移
443 */
444 p_tcb->tstat |= TS_SUSPENDED;
445 LOG_TSKSTAT(p_tcb);
446 ercd = E_OK;
447 }
448 t_unlock_cpu();
449
450 error_exit:
451 LOG_SUS_TSK_LEAVE(ercd);
452 return(ercd);
453}
454
455#endif /* TOPPERS_sus_tsk */
456
457/*
458 * 強制待ち状態からの再開
459 */
460#ifdef TOPPERS_rsm_tsk
461
462ER
463rsm_tsk(ID tskid)
464{
465 TCB *p_tcb;
466 ER ercd;
467
468 LOG_RSM_TSK_ENTER(tskid);
469 CHECK_TSKCTX_UNL();
470 CHECK_TSKID(tskid);
471 p_tcb = get_tcb(tskid);
472 CHECK_NOEXS(p_tcb->p_tinib->tskatr);
473
474 t_lock_cpu();
475 if (!TSTAT_SUSPENDED(p_tcb->tstat)) {
476 ercd = E_OBJ;
477 }
478 else if (!TSTAT_WAITING(p_tcb->tstat)) {
479 /*
480 * 強制待ち状態から実行できる状態への遷移
481 */
482 p_tcb->tstat = TS_RUNNABLE;
483 LOG_TSKSTAT(p_tcb);
484 if (make_runnable(p_tcb)) {
485 dispatch();
486 }
487 ercd = E_OK;
488 }
489 else {
490 /*
491 * 二重待ち状態から待ち状態への遷移
492 */
493 p_tcb->tstat &= ~TS_SUSPENDED;
494 LOG_TSKSTAT(p_tcb);
495 ercd = E_OK;
496 }
497 t_unlock_cpu();
498
499 error_exit:
500 LOG_RSM_TSK_LEAVE(ercd);
501 return(ercd);
502}
503
504#endif /* TOPPERS_rsm_tsk */
505
506/*
507 * 自タスクの遅延
508 */
509#ifdef TOPPERS_dly_tsk
510
511ER
512dly_tsk(RELTIM dlytim)
513{
514 WINFO winfo;
515 TMEVTB tmevtb;
516 ER ercd;
517
518 LOG_DLY_TSK_ENTER(dlytim);
519 CHECK_DISPATCH();
520 CHECK_PAR(dlytim <= TMAX_RELTIM);
521
522 t_lock_cpu();
523 p_runtsk->tstat = (TS_WAITING | TS_WAIT_DLY);
524 (void) make_non_runnable(p_runtsk);
525 p_runtsk->p_winfo = &winfo;
526 winfo.p_tmevtb = &tmevtb;
527 tmevtb_enqueue(&tmevtb, dlytim, (CBACK) wait_tmout_ok, (void *) p_runtsk);
528 LOG_TSKSTAT(p_runtsk);
529 dispatch();
530 ercd = winfo.wercd;
531 t_unlock_cpu();
532
533 error_exit:
534 LOG_DLY_TSK_LEAVE(ercd);
535 return(ercd);
536}
537
538#endif /* TOPPERS_dly_tsk */
Note: See TracBrowser for help on using the repository browser.