X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=palacios%2Fsrc%2Fpalacios%2Fvmm_lock.c;h=7b3a09186c624e5f145ebab301d70ef5eac93d65;hb=fd8ffc465479e68f4938f85b718a9fb35d05bee0;hp=c2bdba798824370c98092b2556cf7651a85a67f8;hpb=794a794cec97cecc8c7de7f8b5fe33381a1e02e0;p=palacios.git diff --git a/palacios/src/palacios/vmm_lock.c b/palacios/src/palacios/vmm_lock.c index c2bdba7..7b3a091 100644 --- a/palacios/src/palacios/vmm_lock.c +++ b/palacios/src/palacios/vmm_lock.c @@ -50,13 +50,86 @@ void v3_unlock(v3_lock_t lock) { } addr_t v3_lock_irqsave(v3_lock_t lock) { - addr_t irq_state = v3_irq_save(); - os_hooks->mutex_lock((void *)lock, 1); - return irq_state; + return (addr_t) (os_hooks->mutex_lock_irqsave((void *)lock, 1)); } void v3_unlock_irqrestore(v3_lock_t lock, addr_t irq_state) { - os_hooks->mutex_unlock((void *)lock); - v3_irq_restore(irq_state); + os_hooks->mutex_unlock_irqrestore((void *)lock,(void*)irq_state); +} + + +int v3_rw_lock_init(v3_rw_lock_t *lock) +{ + lock->reader_count=0; + return v3_lock_init(&(lock->lock)); +} + +void v3_rw_lock_deinit(v3_rw_lock_t *lock) +{ + v3_lock_deinit(&(lock->lock)); + lock->reader_count=0; +} + +void v3_read_lock(v3_rw_lock_t *lock) +{ + addr_t flags; + + flags=v3_lock_irqsave(lock->lock); + lock->reader_count++; + v3_unlock_irqrestore(lock->lock,flags); + // readers can come in after us, writers cannot +} +void v3_read_unlock(v3_rw_lock_t *lock) +{ + addr_t flags; + + flags=v3_lock_irqsave(lock->lock); + lock->reader_count--; + v3_unlock_irqrestore(lock->lock,flags); + // readers can come in after us, and also writers if reader_count==0 +} + +void v3_write_lock(v3_rw_lock_t *lock) +{ + // a less hideous implementation is possible, of course... + while (1) { + v3_lock(lock->lock); + if (!(lock->reader_count)) { + break; + } + v3_unlock(lock->lock); + V3_Yield(); + } + // holding lock now - reader or writer cannot come in after us +} + +addr_t v3_write_lock_irqsave(v3_rw_lock_t *lock) +{ + addr_t flags; + + while (1) { + flags=v3_lock_irqsave(lock->lock); + if (!(lock->reader_count)) { + break; + } + v3_unlock_irqrestore(lock->lock,flags); + V3_Yield(); + } + // holding lock now with interrupts off - reader or writer canot come in after us + return flags; +} + +void v3_write_unlock(v3_rw_lock_t *lock) +{ + // I am already holding this lock + v3_unlock(lock->lock); + // readers/writers can now come in +} + +void v3_write_unlock_irqrestore(v3_rw_lock_t *lock, addr_t irq_state) +{ + // I am already holding this lock with interrupts off + v3_unlock_irqrestore(lock->lock,irq_state); + // readers/writers can now come in }