struct lock * lock_create(const char *name) { struct lock* new_lock; new_lock = kmalloc(sizeof(struct lock)); if (new_lock == NULL) { return NULL; } new_lock->lk_name = kstrdup(name); if (new_lock->lk_name == NULL) { kfree(new_lock); return NULL; } new_lock->lk_wchan = wchan_create(new_lock->lk_name); if (new_lock->lk_wchan == NULL) { kfree(new_lock->lk_name); kfree(new_lock); return NULL; } spinlock_init(&new_lock->spin_lock); spinlock_data_set(&new_lock->lk_busy, 0); new_lock->lk_cpu = NULL; new_lock->lk_thread = NULL; return new_lock; }
void lock_release(struct lock *lock) { if(lock_do_i_hold(lock)) { spinlock_acquire(&lock->spin_lock); spinlock_data_set(&lock->lk_busy,0); lock->lk_cpu = NULL; lock->lk_thread = NULL; wchan_wakeone(lock->lk_wchan, &lock->spin_lock); spinlock_release(&lock->spin_lock); } }
/* * Release the lock. */ void spinlock_release(struct spinlock *lk) { /* this must work before curcpu initialization */ if (CURCPU_EXISTS()) { KASSERT(lk->lk_holder == curcpu->c_self); } lk->lk_holder = NULL; spinlock_data_set(&lk->lk_lock, 0); spllower(IPL_HIGH, IPL_NONE); }
/* * Initialize spinlock. */ void spinlock_init(struct spinlock *lk) { spinlock_data_set(&lk->lk_lock, 0); lk->lk_holder = NULL; }