source: asp3_tinet_ecnl_arm/trunk/asp3_dcre/kernel/task_sync.c@ 352

Last change on this file since 352 was 352, checked in by coas-nagasima, 6 years ago

arm向けASP3版ECNLを追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 10.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) 2000-2003 by Embedded and Real-Time Systems Laboratory
7 * Toyohashi Univ. of Technology, JAPAN
8 * Copyright (C) 2005-2015 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$
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_CAN_WUP_ENTER
80#define LOG_CAN_WUP_ENTER(tskid)
81#endif /* LOG_CAN_WUP_ENTER */
82
83#ifndef LOG_CAN_WUP_LEAVE
84#define LOG_CAN_WUP_LEAVE(ercd)
85#endif /* LOG_CAN_WUP_LEAVE */
86
87#ifndef LOG_REL_WAI_ENTER
88#define LOG_REL_WAI_ENTER(tskid)
89#endif /* LOG_REL_WAI_ENTER */
90
91#ifndef LOG_REL_WAI_LEAVE
92#define LOG_REL_WAI_LEAVE(ercd)
93#endif /* LOG_REL_WAI_LEAVE */
94
95#ifndef LOG_SUS_TSK_ENTER
96#define LOG_SUS_TSK_ENTER(tskid)
97#endif /* LOG_SUS_TSK_ENTER */
98
99#ifndef LOG_SUS_TSK_LEAVE
100#define LOG_SUS_TSK_LEAVE(ercd)
101#endif /* LOG_SUS_TSK_LEAVE */
102
103#ifndef LOG_RSM_TSK_ENTER
104#define LOG_RSM_TSK_ENTER(tskid)
105#endif /* LOG_RSM_TSK_ENTER */
106
107#ifndef LOG_RSM_TSK_LEAVE
108#define LOG_RSM_TSK_LEAVE(ercd)
109#endif /* LOG_RSM_TSK_LEAVE */
110
111#ifndef LOG_DLY_TSK_ENTER
112#define LOG_DLY_TSK_ENTER(dlytim)
113#endif /* LOG_DLY_TSK_ENTER */
114
115#ifndef LOG_DLY_TSK_LEAVE
116#define LOG_DLY_TSK_LEAVE(ercd)
117#endif /* LOG_DLY_TSK_LEAVE */
118
119/*
120 * 起床待ち
121 */
122#ifdef TOPPERS_slp_tsk
123
124ER
125slp_tsk(void)
126{
127 WINFO winfo;
128 ER ercd;
129
130 LOG_SLP_TSK_ENTER();
131 CHECK_DISPATCH();
132
133 lock_cpu_dsp();
134 if (p_runtsk->raster) {
135 ercd = E_RASTER;
136 }
137 else if (p_runtsk->wupque) {
138 p_runtsk->wupque = false;
139 ercd = E_OK;
140 }
141 else {
142 p_runtsk->tstat = TS_WAITING_SLP;
143 make_wait(&winfo);
144 LOG_TSKSTAT(p_runtsk);
145 dispatch();
146 ercd = winfo.wercd;
147 }
148 unlock_cpu_dsp();
149
150 error_exit:
151 LOG_SLP_TSK_LEAVE(ercd);
152 return(ercd);
153}
154
155#endif /* TOPPERS_slp_tsk */
156
157/*
158 * 起床待ち(タイムアウトあり)
159 */
160#ifdef TOPPERS_tslp_tsk
161
162ER
163tslp_tsk(TMO tmout)
164{
165 WINFO winfo;
166 TMEVTB tmevtb;
167 ER ercd;
168
169 LOG_TSLP_TSK_ENTER(tmout);
170 CHECK_DISPATCH();
171 CHECK_PAR(VALID_TMOUT(tmout));
172
173 lock_cpu_dsp();
174 if (p_runtsk->raster) {
175 ercd = E_RASTER;
176 }
177 else if (p_runtsk->wupque) {
178 p_runtsk->wupque = false;
179 ercd = E_OK;
180 }
181 else if (tmout == TMO_POL) {
182 ercd = E_TMOUT;
183 }
184 else {
185 p_runtsk->tstat = TS_WAITING_SLP;
186 make_wait_tmout(&winfo, &tmevtb, tmout);
187 LOG_TSKSTAT(p_runtsk);
188 dispatch();
189 ercd = winfo.wercd;
190 }
191 unlock_cpu_dsp();
192
193 error_exit:
194 LOG_TSLP_TSK_LEAVE(ercd);
195 return(ercd);
196}
197
198#endif /* TOPPERS_tslp_tsk */
199
200/*
201 * タスクの起床
202 */
203#ifdef TOPPERS_wup_tsk
204
205ER
206wup_tsk(ID tskid)
207{
208 TCB *p_tcb;
209 ER ercd;
210
211 LOG_WUP_TSK_ENTER(tskid);
212 CHECK_UNL();
213 if (tskid == TSK_SELF && !sense_context()) {
214 p_tcb = p_runtsk;
215 }
216 else {
217 CHECK_ID(VALID_TSKID(tskid));
218 p_tcb = get_tcb(tskid);
219 }
220
221 lock_cpu();
222 if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
223 ercd = E_NOEXS;
224 }
225 else if (TSTAT_DORMANT(p_tcb->tstat)) {
226 ercd = E_OBJ;
227 }
228 else if (TSTAT_WAIT_SLP(p_tcb->tstat)) {
229 wait_complete(p_tcb);
230 if (p_runtsk != p_schedtsk) {
231 if (!sense_context()) {
232 dispatch();
233 }
234 else {
235 request_dispatch();
236 }
237 }
238 ercd = E_OK;
239 }
240 else if (!(p_tcb->wupque)) {
241 p_tcb->wupque = true;
242 ercd = E_OK;
243 }
244 else {
245 ercd = E_QOVR;
246 }
247 unlock_cpu();
248
249 error_exit:
250 LOG_WUP_TSK_LEAVE(ercd);
251 return(ercd);
252}
253
254#endif /* TOPPERS_wup_tsk */
255
256/*
257 * タスク起床要求のキャンセル
258 */
259#ifdef TOPPERS_can_wup
260
261ER_UINT
262can_wup(ID tskid)
263{
264 TCB *p_tcb;
265 ER_UINT ercd;
266
267 LOG_CAN_WUP_ENTER(tskid);
268 CHECK_TSKCTX_UNL();
269 if (tskid == TSK_SELF) {
270 p_tcb = p_runtsk;
271 }
272 else {
273 CHECK_ID(VALID_TSKID(tskid));
274 p_tcb = get_tcb(tskid);
275 }
276
277 lock_cpu();
278 if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
279 ercd = E_NOEXS;
280 }
281 else if (TSTAT_DORMANT(p_tcb->tstat)) {
282 ercd = E_OBJ;
283 }
284 else {
285 ercd = p_tcb->wupque ? 1 : 0;
286 p_tcb->wupque = false;
287 }
288 unlock_cpu();
289
290 error_exit:
291 LOG_CAN_WUP_LEAVE(ercd);
292 return(ercd);
293}
294
295#endif /* TOPPERS_can_wup */
296
297/*
298 * 待ち状態の強制解除
299 */
300#ifdef TOPPERS_rel_wai
301
302ER
303rel_wai(ID tskid)
304{
305 TCB *p_tcb;
306 ER ercd;
307
308 LOG_REL_WAI_ENTER(tskid);
309 CHECK_UNL();
310 CHECK_ID(VALID_TSKID(tskid));
311 p_tcb = get_tcb(tskid);
312
313 lock_cpu();
314 if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
315 ercd = E_NOEXS;
316 }
317 else if (!TSTAT_WAITING(p_tcb->tstat)) {
318 ercd = E_OBJ;
319 }
320 else {
321 wait_dequeue_wobj(p_tcb);
322 wait_dequeue_tmevtb(p_tcb);
323 p_tcb->p_winfo->wercd = E_RLWAI;
324 make_non_wait(p_tcb);
325 if (p_runtsk != p_schedtsk) {
326 if (!sense_context()) {
327 dispatch();
328 }
329 else {
330 request_dispatch();
331 }
332 }
333 ercd = E_OK;
334 }
335 unlock_cpu();
336
337 error_exit:
338 LOG_REL_WAI_LEAVE(ercd);
339 return(ercd);
340}
341
342#endif /* TOPPERS_rel_wai */
343
344/*
345 * 強制待ち状態への移行[NGKI1298]
346 */
347#ifdef TOPPERS_sus_tsk
348
349ER
350sus_tsk(ID tskid)
351{
352 TCB *p_tcb;
353 ER ercd;
354
355 LOG_SUS_TSK_ENTER(tskid);
356 CHECK_TSKCTX_UNL(); /*[NGKI1299][NGKI1300]*/
357 if (tskid == TSK_SELF) {
358 p_tcb = p_runtsk; /*[NGKI1310]*/
359 }
360 else {
361 CHECK_ID(VALID_TSKID(tskid)); /*[NGKI1302]*/
362 p_tcb = get_tcb(tskid);
363 }
364
365 lock_cpu();
366 if (p_tcb == p_runtsk && !dspflg) { /*[NGKI1311][NGKI3604]*/
367 ercd = E_CTX;
368 }
369 else if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
370 ercd = E_NOEXS; /*[NGKI1303]*/
371 }
372 else if (TSTAT_DORMANT(p_tcb->tstat)) {
373 ercd = E_OBJ; /*[NGKI1305]*/
374 }
375 else if (p_tcb->raster) {
376 ercd = E_RASTER; /*[NGKI3605]*/
377 }
378 else if (TSTAT_RUNNABLE(p_tcb->tstat)) {
379 /*
380 * 実行できる状態から強制待ち状態への遷移[NGKI1307]
381 */
382 p_tcb->tstat = TS_SUSPENDED;
383 LOG_TSKSTAT(p_tcb);
384 make_non_runnable(p_tcb);
385 if (p_runtsk != p_schedtsk) {
386 dispatch();
387 }
388 ercd = E_OK;
389 }
390 else if (TSTAT_SUSPENDED(p_tcb->tstat)) {
391 ercd = E_QOVR; /*[NGKI1306]*/
392 }
393 else {
394 /*
395 * 待ち状態から二重待ち状態への遷移[NGKI1308]
396 */
397 p_tcb->tstat |= TS_SUSPENDED;
398 LOG_TSKSTAT(p_tcb);
399 ercd = E_OK;
400 }
401 unlock_cpu();
402
403 error_exit:
404 LOG_SUS_TSK_LEAVE(ercd);
405 return(ercd);
406}
407
408#endif /* TOPPERS_sus_tsk */
409
410/*
411 * 強制待ち状態からの再開
412 */
413#ifdef TOPPERS_rsm_tsk
414
415ER
416rsm_tsk(ID tskid)
417{
418 TCB *p_tcb;
419 ER ercd;
420
421 LOG_RSM_TSK_ENTER(tskid);
422 CHECK_TSKCTX_UNL();
423 CHECK_ID(VALID_TSKID(tskid));
424 p_tcb = get_tcb(tskid);
425
426 lock_cpu();
427 if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
428 ercd = E_NOEXS;
429 }
430 else if (!TSTAT_SUSPENDED(p_tcb->tstat)) {
431 ercd = E_OBJ;
432 }
433 else if (!TSTAT_WAITING(p_tcb->tstat)) {
434 /*
435 * 強制待ち状態から実行できる状態への遷移
436 */
437 p_tcb->tstat = TS_RUNNABLE;
438 LOG_TSKSTAT(p_tcb);
439 make_runnable(p_tcb);
440 if (p_runtsk != p_schedtsk) {
441 dispatch();
442 }
443 ercd = E_OK;
444 }
445 else {
446 /*
447 * 二重待ち状態から待ち状態への遷移
448 */
449 p_tcb->tstat &= ~TS_SUSPENDED;
450 LOG_TSKSTAT(p_tcb);
451 ercd = E_OK;
452 }
453 unlock_cpu();
454
455 error_exit:
456 LOG_RSM_TSK_LEAVE(ercd);
457 return(ercd);
458}
459
460#endif /* TOPPERS_rsm_tsk */
461
462/*
463 * 自タスクの遅延
464 */
465#ifdef TOPPERS_dly_tsk
466
467ER
468dly_tsk(RELTIM dlytim)
469{
470 WINFO winfo;
471 TMEVTB tmevtb;
472 ER ercd;
473
474 LOG_DLY_TSK_ENTER(dlytim);
475 CHECK_DISPATCH();
476 CHECK_PAR(VALID_RELTIM(dlytim));
477
478 lock_cpu_dsp();
479 if (p_runtsk->raster) {
480 ercd = E_RASTER;
481 }
482 else {
483 p_runtsk->tstat = TS_WAITING_DLY;
484 make_non_runnable(p_runtsk);
485 p_runtsk->p_winfo = &winfo;
486 winfo.p_tmevtb = &tmevtb;
487 tmevtb.callback = (CBACK) wait_tmout_ok;
488 tmevtb.arg = (void *) p_runtsk;
489 tmevtb_enqueue(&tmevtb, dlytim);
490 LOG_TSKSTAT(p_runtsk);
491 dispatch();
492 ercd = winfo.wercd;
493 }
494 unlock_cpu_dsp();
495
496 error_exit:
497 LOG_DLY_TSK_LEAVE(ercd);
498 return(ercd);
499}
500
501#endif /* TOPPERS_dly_tsk */
Note: See TracBrowser for help on using the repository browser.