source: UsbWattMeter/trunk/asp_dcre/kernel/task_sync.c

Last change on this file was 167, checked in by coas-nagasima, 7 years ago

MIMEにSJISを設定

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-csrc; charset=SHIFT_JIS
File size: 10.2 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-2010 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 167 2016-03-08 11:37:45Z coas-nagasima $
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
226 t_lock_cpu();
227 if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
228 ercd = E_NOEXS;
229 }
230 else if (TSTAT_DORMANT(p_tcb->tstat)) {
231 ercd = E_OBJ;
232 }
233 else if (TSTAT_WAIT_SLP(p_tcb->tstat)) {
234 if (wait_complete(p_tcb)) {
235 dispatch();
236 }
237 ercd = E_OK;
238 }
239 else if (!(p_tcb->wupque)) {
240 p_tcb->wupque = true;
241 ercd = E_OK;
242 }
243 else {
244 ercd = E_QOVR;
245 }
246 t_unlock_cpu();
247
248 error_exit:
249 LOG_WUP_TSK_LEAVE(ercd);
250 return(ercd);
251}
252
253#endif /* TOPPERS_wup_tsk */
254
255/*
256 * タスクの起床(非タスクコンテキスト用)
257 */
258#ifdef TOPPERS_iwup_tsk
259
260ER
261iwup_tsk(ID tskid)
262{
263 TCB *p_tcb;
264 ER ercd;
265
266 LOG_IWUP_TSK_ENTER(tskid);
267 CHECK_INTCTX_UNL();
268 CHECK_TSKID(tskid);
269 p_tcb = get_tcb(tskid);
270
271 i_lock_cpu();
272 if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
273 ercd = E_NOEXS;
274 }
275 else if (TSTAT_DORMANT(p_tcb->tstat)) {
276 ercd = E_OBJ;
277 }
278 else if (TSTAT_WAIT_SLP(p_tcb->tstat)) {
279 if (wait_complete(p_tcb)) {
280 reqflg = true;
281 }
282 ercd = E_OK;
283 }
284 else if (!(p_tcb->wupque)) {
285 p_tcb->wupque = true;
286 ercd = E_OK;
287 }
288 else {
289 ercd = E_QOVR;
290 }
291 i_unlock_cpu();
292
293 error_exit:
294 LOG_IWUP_TSK_LEAVE(ercd);
295 return(ercd);
296}
297
298#endif /* TOPPERS_iwup_tsk */
299
300/*
301 * タスク起床要求のキャンセル
302 */
303#ifdef TOPPERS_can_wup
304
305ER_UINT
306can_wup(ID tskid)
307{
308 TCB *p_tcb;
309 ER_UINT ercd;
310
311 LOG_CAN_WUP_ENTER(tskid);
312 CHECK_TSKCTX_UNL();
313 CHECK_TSKID_SELF(tskid);
314 p_tcb = get_tcb_self(tskid);
315
316 t_lock_cpu();
317 if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
318 ercd = E_NOEXS;
319 }
320 else if (TSTAT_DORMANT(p_tcb->tstat)) {
321 ercd = E_OBJ;
322 }
323 else {
324 ercd = p_tcb->wupque ? 1 : 0;
325 p_tcb->wupque = false;
326 }
327 t_unlock_cpu();
328
329 error_exit:
330 LOG_CAN_WUP_LEAVE(ercd);
331 return(ercd);
332}
333
334#endif /* TOPPERS_can_wup */
335
336/*
337 * 待ち状態の強制解除
338 */
339#ifdef TOPPERS_rel_wai
340
341ER
342rel_wai(ID tskid)
343{
344 TCB *p_tcb;
345 ER ercd;
346
347 LOG_REL_WAI_ENTER(tskid);
348 CHECK_TSKCTX_UNL();
349 CHECK_TSKID(tskid);
350 p_tcb = get_tcb(tskid);
351
352 t_lock_cpu();
353 if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
354 ercd = E_NOEXS;
355 }
356 else if (!TSTAT_WAITING(p_tcb->tstat)) {
357 ercd = E_OBJ;
358 }
359 else {
360 if (wait_release(p_tcb)) {
361 dispatch();
362 }
363 ercd = E_OK;
364 }
365 t_unlock_cpu();
366
367 error_exit:
368 LOG_REL_WAI_LEAVE(ercd);
369 return(ercd);
370}
371
372#endif /* TOPPERS_rel_wai */
373
374/*
375 * 待ち状態の強制解除(非タスクコンテキスト用)
376 */
377#ifdef TOPPERS_irel_wai
378
379ER
380irel_wai(ID tskid)
381{
382 TCB *p_tcb;
383 ER ercd;
384
385 LOG_IREL_WAI_ENTER(tskid);
386 CHECK_INTCTX_UNL();
387 CHECK_TSKID(tskid);
388 p_tcb = get_tcb(tskid);
389
390 i_lock_cpu();
391 if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
392 ercd = E_NOEXS;
393 }
394 else if (!TSTAT_WAITING(p_tcb->tstat)) {
395 ercd = E_OBJ;
396 }
397 else {
398 if (wait_release(p_tcb)) {
399 reqflg = true;
400 }
401 ercd = E_OK;
402 }
403 i_unlock_cpu();
404
405 error_exit:
406 LOG_IREL_WAI_LEAVE(ercd);
407 return(ercd);
408}
409
410#endif /* TOPPERS_irel_wai */
411
412/*
413 * 強制待ち状態への移行
414 */
415#ifdef TOPPERS_sus_tsk
416
417ER
418sus_tsk(ID tskid)
419{
420 TCB *p_tcb;
421 ER ercd;
422
423 LOG_SUS_TSK_ENTER(tskid);
424 CHECK_TSKCTX_UNL();
425 CHECK_TSKID_SELF(tskid);
426 p_tcb = get_tcb_self(tskid);
427
428 t_lock_cpu();
429 if (p_tcb == p_runtsk && !dspflg) {
430 ercd = E_CTX;
431 }
432 else if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
433 ercd = E_NOEXS;
434 }
435 else if (TSTAT_DORMANT(p_tcb->tstat)) {
436 ercd = E_OBJ;
437 }
438 else if (TSTAT_RUNNABLE(p_tcb->tstat)) {
439 /*
440 * 実行できる状態から強制待ち状態への遷移
441 */
442 p_tcb->tstat = TS_SUSPENDED;
443 LOG_TSKSTAT(p_tcb);
444 if (make_non_runnable(p_tcb)) {
445 dispatch();
446 }
447 ercd = E_OK;
448 }
449 else if (TSTAT_SUSPENDED(p_tcb->tstat)) {
450 ercd = E_QOVR;
451 }
452 else {
453 /*
454 * 待ち状態から二重待ち状態への遷移
455 */
456 p_tcb->tstat |= TS_SUSPENDED;
457 LOG_TSKSTAT(p_tcb);
458 ercd = E_OK;
459 }
460 t_unlock_cpu();
461
462 error_exit:
463 LOG_SUS_TSK_LEAVE(ercd);
464 return(ercd);
465}
466
467#endif /* TOPPERS_sus_tsk */
468
469/*
470 * 強制待ち状態からの再開
471 */
472#ifdef TOPPERS_rsm_tsk
473
474ER
475rsm_tsk(ID tskid)
476{
477 TCB *p_tcb;
478 ER ercd;
479
480 LOG_RSM_TSK_ENTER(tskid);
481 CHECK_TSKCTX_UNL();
482 CHECK_TSKID(tskid);
483 p_tcb = get_tcb(tskid);
484
485 t_lock_cpu();
486 if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
487 ercd = E_NOEXS;
488 }
489 else if (!TSTAT_SUSPENDED(p_tcb->tstat)) {
490 ercd = E_OBJ;
491 }
492 else if (!TSTAT_WAITING(p_tcb->tstat)) {
493 /*
494 * 強制待ち状態から実行できる状態への遷移
495 */
496 p_tcb->tstat = TS_RUNNABLE;
497 LOG_TSKSTAT(p_tcb);
498 if (make_runnable(p_tcb)) {
499 dispatch();
500 }
501 ercd = E_OK;
502 }
503 else {
504 /*
505 * 二重待ち状態から待ち状態への遷移
506 */
507 p_tcb->tstat &= ~TS_SUSPENDED;
508 LOG_TSKSTAT(p_tcb);
509 ercd = E_OK;
510 }
511 t_unlock_cpu();
512
513 error_exit:
514 LOG_RSM_TSK_LEAVE(ercd);
515 return(ercd);
516}
517
518#endif /* TOPPERS_rsm_tsk */
519
520/*
521 * 自タスクの遅延
522 */
523#ifdef TOPPERS_dly_tsk
524
525ER
526dly_tsk(RELTIM dlytim)
527{
528 WINFO winfo;
529 TMEVTB tmevtb;
530 ER ercd;
531
532 LOG_DLY_TSK_ENTER(dlytim);
533 CHECK_DISPATCH();
534 CHECK_PAR(dlytim <= TMAX_RELTIM);
535
536 t_lock_cpu();
537 p_runtsk->tstat = (TS_WAITING | TS_WAIT_DLY);
538 (void) make_non_runnable(p_runtsk);
539 p_runtsk->p_winfo = &winfo;
540 winfo.p_tmevtb = &tmevtb;
541 tmevtb_enqueue(&tmevtb, dlytim, (CBACK) wait_tmout_ok, (void *) p_runtsk);
542 LOG_TSKSTAT(p_runtsk);
543 dispatch();
544 ercd = winfo.wercd;
545 t_unlock_cpu();
546
547 error_exit:
548 LOG_DLY_TSK_LEAVE(ercd);
549 return(ercd);
550}
551
552#endif /* TOPPERS_dly_tsk */
Note: See TracBrowser for help on using the repository browser.