mtkernel_3/kernel/tkernel/klock.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: * klock.c Kernel Lock 15: * Locked task is the highest run priority. 16: * Unable to nest lock. 17: */ 18: 19: #include "kernel.h" 20: #include "klock.h" 21: #include "ready_queue.h" 22: 23: /* 24: * Object lock 25: * Do not call from critical section 26: */ 27: EXPORT void knl_LockOBJ( OBJLOCK *loc ) 28: { 29: BOOL klocked; 30: 31: retry: 32: BEGIN_CRITICAL_SECTION; 33: klocked = knl_ctxtsk->klocked; 34: if ( !klocked ) { 35: if ( loc->wtskq.next == NULL ) { 36: /* Lock */ 37: QueInit(&loc->wtskq); 38: 39: knl_ctxtsk->klocked = klocked = TRUE; 40: knl_ready_queue.klocktsk = knl_ctxtsk; 41: } else { 42: /* Ready for lock */ 43: knl_ready_queue_delete(&knl_ready_queue, knl_ctxtsk); 44: knl_ctxtsk->klockwait = TRUE; 45: QueInsert(&knl_ctxtsk->tskque, &loc->wtskq); 46: 47: knl_schedtsk = knl_ready_queue_top(&knl_ready_queue); 48: } 49: } 50: END_CRITICAL_SECTION; 51: /* Since wait could be freed without getting lock, 52: need to re-try if lock is not got */ 53: if ( !klocked ) { 54: goto retry; 55: } 56: } 57: 58: /* 59: * Object unlock 60: * It may be called from a critical section. 61: */ 62: EXPORT void knl_UnlockOBJ( OBJLOCK *loc ) 63: { 64: TCB *tcb; 65: 66: BEGIN_CRITICAL_SECTION; 67: knl_ctxtsk->klocked = FALSE; 68: knl_ready_queue.klocktsk = NULL; 69: 70: tcb = (TCB*)QueRemoveNext(&loc->wtskq); 71: if ( tcb == NULL ) { 72: /* Free lock */ 73: loc->wtskq.next = NULL; 74: } else { 75: /* Wake lock wait task */ 76: tcb->klockwait = FALSE; 77: tcb->klocked = TRUE; 78: knl_ready_queue_insert_top(&knl_ready_queue, tcb); 79: } 80: 81: knl_schedtsk = knl_ready_queue_top(&knl_ready_queue); 82: END_CRITICAL_SECTION; 83: }