mtkernel_3/kernel/tkernel/task_sync.c | bare source | permlink (0.01 seconds) |
1: /* 2: *---------------------------------------------------------------------- 3: * micro T-Kernel 3.00.00 4: * 5: * Copyright (C) 2006-2019 by Ken Sakamura. 6: * This software is distributed under the T-License 2.1. 7: *---------------------------------------------------------------------- 8: * 9: * Released by TRON Forum(http://www.tron.org) at 2019/12/11. 10: * 11: *---------------------------------------------------------------------- 12: */ 13: 14: /* 15: * task_sync.c 16: * Task with Synchronize Function 17: */ 18: 19: #include "kernel.h" 20: #include "wait.h" 21: #include "check.h" 22: #include "limits.h" 23: 24: #ifdef USE_FUNC_TK_SUS_TSK 25: /* 26: * Suspend task 27: */ 28: SYSCALL ER tk_sus_tsk( ID tskid ) 29: { 30: TCB *tcb; 31: TSTAT state; 32: ER ercd = E_OK; 33: 34: CHECK_TSKID(tskid); 35: CHECK_NONSELF(tskid); 36: 37: tcb = get_tcb(tskid); 38: 39: BEGIN_CRITICAL_SECTION; 40: state = (TSTAT)tcb->state; 41: if ( !knl_task_alive(state) ) { 42: ercd = ( state == TS_NONEXIST )? E_NOEXS: E_OBJ; 43: goto error_exit; 44: } 45: if ( tcb == knl_ctxtsk && knl_dispatch_disabled >= DDS_DISABLE ) { 46: ercd = E_CTX; 47: goto error_exit; 48: } 49: if ( tcb->suscnt == INT_MAX ) { 50: ercd = E_QOVR; 51: goto error_exit; 52: } 53: 54: /* Update suspend request count */ 55: ++tcb->suscnt; 56: 57: /* Move to forced wait state */ 58: if ( state == TS_READY ) { 59: knl_make_non_ready(tcb); 60: tcb->state = TS_SUSPEND; 61: 62: } else if ( state == TS_WAIT ) { 63: tcb->state = TS_WAITSUS; 64: } 65: 66: error_exit: 67: END_CRITICAL_SECTION; 68: 69: return ercd; 70: } 71: #endif /* USE_FUNC_TK_SUS_TSK */ 72: 73: #ifdef USE_FUNC_TK_RSM_TSK 74: /* 75: * Resume task 76: */ 77: SYSCALL ER tk_rsm_tsk( ID tskid ) 78: { 79: TCB *tcb; 80: ER ercd = E_OK; 81: 82: CHECK_TSKID(tskid); 83: CHECK_NONSELF(tskid); 84: 85: tcb = get_tcb(tskid); 86: 87: BEGIN_CRITICAL_SECTION; 88: switch ( tcb->state ) { 89: case TS_NONEXIST: 90: ercd = E_NOEXS; 91: break; 92: 93: case TS_DORMANT: 94: case TS_READY: 95: case TS_WAIT: 96: ercd = E_OBJ; 97: break; 98: 99: case TS_SUSPEND: 100: if ( --tcb->suscnt == 0 ) { 101: knl_make_ready(tcb); 102: } 103: break; 104: case TS_WAITSUS: 105: if ( --tcb->suscnt == 0 ) { 106: tcb->state = TS_WAIT; 107: } 108: break; 109: 110: default: 111: ercd = E_SYS; 112: break; 113: } 114: END_CRITICAL_SECTION; 115: 116: return ercd; 117: } 118: #endif /* USE_FUNC_TK_RSM_TSK */ 119: 120: #ifdef USE_FUNC_TK_FRSM_TSK 121: /* 122: * Force resume task 123: */ 124: SYSCALL ER tk_frsm_tsk( ID tskid ) 125: { 126: TCB *tcb; 127: ER ercd = E_OK; 128: 129: CHECK_TSKID(tskid); 130: CHECK_NONSELF(tskid); 131: 132: tcb = get_tcb(tskid); 133: 134: BEGIN_CRITICAL_SECTION; 135: switch ( tcb->state ) { 136: case TS_NONEXIST: 137: ercd = E_NOEXS; 138: break; 139: 140: case TS_DORMANT: 141: case TS_READY: 142: case TS_WAIT: 143: ercd = E_OBJ; 144: break; 145: 146: case TS_SUSPEND: 147: tcb->suscnt = 0; 148: knl_make_ready(tcb); 149: break; 150: case TS_WAITSUS: 151: tcb->suscnt = 0; 152: tcb->state = TS_WAIT; 153: break; 154: 155: default: 156: ercd = E_SYS; 157: break; 158: } 159: END_CRITICAL_SECTION; 160: 161: return ercd; 162: } 163: #endif /* USE_FUNC_TK_FRSM_TSK */ 164: 165: /* ------------------------------------------------------------------------ */ 166: 167: /* 168: * Definition of task wait specification 169: */ 170: LOCAL CONST WSPEC knl_wspec_slp = { TTW_SLP, NULL, NULL }; 171: 172: #ifdef USE_FUNC_TK_SLP_TSK 173: /* 174: * Move its own task state to wait state 175: */ 176: SYSCALL ER tk_slp_tsk( TMO tmout ) 177: { 178: ER ercd = E_OK; 179: 180: CHECK_TMOUT(tmout); 181: CHECK_DISPATCH(); 182: 183: BEGIN_CRITICAL_SECTION; 184: 185: if ( knl_ctxtsk->wupcnt > 0 ) { 186: knl_ctxtsk->wupcnt--; 187: } else { 188: ercd = E_TMOUT; 189: if ( tmout != TMO_POL ) { 190: knl_ctxtsk->wspec = &knl_wspec_slp; 191: knl_ctxtsk->wid = 0; 192: knl_ctxtsk->wercd = &ercd; 193: knl_make_wait(tmout, TA_NULL); 194: QueInit(&knl_ctxtsk->tskque); 195: } 196: } 197: 198: END_CRITICAL_SECTION; 199: 200: return ercd; 201: } 202: #endif /* USE_FUNC_TK_SLP_TSK */ 203: 204: #ifdef USE_FUNC_TK_WUP_TSK 205: /* 206: * Wakeup task 207: */ 208: SYSCALL ER tk_wup_tsk( ID tskid ) 209: { 210: TCB *tcb; 211: TSTAT state; 212: ER ercd = E_OK; 213: 214: CHECK_TSKID(tskid); 215: CHECK_NONSELF(tskid); 216: 217: tcb = get_tcb(tskid); 218: 219: BEGIN_CRITICAL_SECTION; 220: state = (TSTAT)tcb->state; 221: if ( !knl_task_alive(state) ) { 222: ercd = ( state == TS_NONEXIST )? E_NOEXS: E_OBJ; 223: 224: } else if ( (state & TS_WAIT) != 0 && tcb->wspec == &knl_wspec_slp ) { 225: knl_wait_release_ok(tcb); 226: 227: } else if ( tcb->wupcnt == INT_MAX ) { 228: ercd = E_QOVR; 229: } else { 230: ++tcb->wupcnt; 231: } 232: END_CRITICAL_SECTION; 233: 234: return ercd; 235: } 236: #endif /* USE_FUNC_TK_WUP_TSK */ 237: 238: #ifdef USE_FUNC_TK_CAN_WUP 239: /* 240: * Cancel wakeup request 241: */ 242: SYSCALL INT tk_can_wup( ID tskid ) 243: { 244: TCB *tcb; 245: ER ercd = E_OK; 246: 247: CHECK_TSKID_SELF(tskid); 248: 249: tcb = get_tcb_self(tskid); 250: 251: BEGIN_CRITICAL_SECTION; 252: switch ( tcb->state ) { 253: case TS_NONEXIST: 254: ercd = E_NOEXS; 255: break; 256: case TS_DORMANT: 257: ercd = E_OBJ; 258: break; 259: 260: default: 261: ercd = tcb->wupcnt; 262: tcb->wupcnt = 0; 263: } 264: END_CRITICAL_SECTION; 265: 266: return ercd; 267: } 268: #endif /* USE_FUNC_TK_CAN_WUP */ 269: 270: #ifdef USE_FUNC_TK_DLY_TSK 271: /* 272: * Definition of task delay wait specification 273: */ 274: LOCAL CONST WSPEC knl_wspec_dly = { TTW_DLY, NULL, NULL }; 275: 276: /* 277: * Task delay 278: */ 279: SYSCALL ER tk_dly_tsk( RELTIM dlytim ) 280: { 281: ER ercd = E_OK; 282: 283: CHECK_RELTIM(dlytim); 284: 285: CHECK_DISPATCH(); 286: 287: if ( dlytim > 0 ) { 288: BEGIN_CRITICAL_SECTION; 289: knl_ctxtsk->wspec = &knl_wspec_dly; 290: knl_ctxtsk->wid = 0; 291: knl_ctxtsk->wercd = &ercd; 292: knl_make_wait_reltim(dlytim, TA_NULL); 293: QueInit(&knl_ctxtsk->tskque); 294: END_CRITICAL_SECTION; 295: } 296: 297: return ercd; 298: } 299: #endif /* USE_FUNC_TK_DLY_TSK */ 300: