1 #include <common/mutex.h> 2 #include <mm/slab.h> 3 #include <sched/sched.h> 4 5 /** 6 * @brief 初始化互斥量 7 * 8 * @param lock mutex结构体 9 */ mutex_init(mutex_t * lock)10void mutex_init(mutex_t *lock) 11 { 12 atomic_set(&lock->count, 1); 13 spin_init(&lock->wait_lock); 14 list_init(&lock->wait_list); 15 } 16 __mutex_sleep()17static void __mutex_sleep() 18 { 19 current_pcb->state = PROC_UNINTERRUPTIBLE; 20 current_pcb->flags |= PF_NEED_SCHED; 21 sched(); 22 } 23 __mutex_acquire(mutex_t * lock)24static void __mutex_acquire(mutex_t *lock) 25 { 26 } 27 /** 28 * @brief 对互斥量加锁 29 * 30 * @param lock mutex结构体 31 */ mutex_lock(mutex_t * lock)32void mutex_lock(mutex_t *lock) 33 { 34 bool lock_ok = 0; 35 36 while (lock_ok == false) 37 { 38 spin_lock(&lock->wait_lock); 39 if (likely(mutex_is_locked(lock))) 40 { 41 struct mutex_waiter_t *waiter = (struct mutex_waiter_t *)kzalloc(sizeof(struct mutex_waiter_t), 0); 42 if (waiter == NULL) 43 { 44 kerror("In mutex_lock: no memory to alloc waiter. Program's behaviour might be indetermined!"); 45 spin_unlock(&lock->wait_lock); 46 return; 47 } 48 // memset(waiter, 0, sizeof(struct mutex_waiter_t)); 49 waiter->pcb = current_pcb; 50 list_init(&waiter->list); 51 list_append(&lock->wait_list, &waiter->list); 52 53 spin_unlock(&lock->wait_lock); 54 55 __mutex_sleep(); 56 } 57 else 58 { 59 atomic_dec(&lock->count); 60 spin_unlock(&lock->wait_lock); 61 lock_ok = true; 62 } 63 } 64 } 65 66 /** 67 * @brief 对互斥量解锁 68 * 69 * @param lock mutex结构体 70 */ mutex_unlock(mutex_t * lock)71void mutex_unlock(mutex_t *lock) 72 { 73 if (unlikely(!mutex_is_locked(lock))) 74 return; 75 76 spin_lock(&lock->wait_lock); 77 struct mutex_waiter_t *wt = NULL; 78 if (mutex_is_locked(lock)) 79 { 80 if (!list_empty(&lock->wait_list)) 81 wt = container_of(list_next(&lock->wait_list), struct mutex_waiter_t, list); 82 83 atomic_inc(&lock->count); 84 if (wt != NULL) 85 list_del(&wt->list); 86 } 87 88 spin_unlock(&lock->wait_lock); 89 90 if (wt != NULL) 91 { 92 process_wakeup(wt->pcb); 93 kfree(wt); 94 } 95 } 96 97 /** 98 * @brief 尝试对互斥量加锁 99 * 100 * @param lock mutex结构体 101 * 102 * @return 成功加锁->1, 加锁失败->0 103 */ mutex_trylock(mutex_t * lock)104int mutex_trylock(mutex_t *lock) 105 { 106 if (mutex_is_locked(lock)) 107 return 0; 108 109 spin_lock(&lock->wait_lock); 110 if (mutex_is_locked(lock)) 111 { 112 spin_unlock(&lock->wait_lock); 113 return 0; 114 } 115 else 116 { 117 atomic_dec(&lock->count); 118 spin_unlock(&lock->wait_lock); 119 return 1; 120 } 121 }