Code: Select all
struct rwLock_t {
uint32t volatile readers;
uint32t volatile writer;
};
static inline uint32t rwLockAcquireRead(struct rwLock_t *lock) {
uint32t res;
asm volatile("0:\ttest $1,(%%edx)\n\t"
"je 1b\n\t"
"pause\n\t"
"jmp 0b\n\t"
"1:\tlock addl $1,(%%eax)\n\t"
"test $1,(%%edx)\n\t"
"je 2b\n\t"
"lock subl $1,(%%eax)\n\t"
"pause\n\t"
"jmp 1b\n\t"
"2:\tpushfl\n\t"
"popl %[output]\n\t"
"cli"
:[output]"=q"(res)
:"a"(&lock->readers), "d"(&lock->writers));
return res;
}
static inline void rwLockReleaseRead(struct rwLock_t *lock, uint32t flags) {
asm volatile("lock subl $1,(%[input])"
:
:[input]"q"(&lock->readers));
if(likely(flags & 0x200))
asm volatile("sti");
}
static inline uint32t rwLockAcquireWrite(struct rwLock_t *lock) {
uint32t res;
asm volatile("movl $1,%%edx\n\t"
"0:\ttest $1,(%%eax)\n\t"
"je 1f\n\t"
"pause\n\t"
"jmp 0b\n\t"
"1:\txchg (%%eax),%%edx\n\t"
"testl $1,%%edx\n\t"
"jne 0b\n\t"
"2:\tcmpl $0,(%%ebx)\n\t"
"je 3f\n\t"
"pause\n\t"
"jmp 2b\n\t"
"3:\tpushfl\n\t"
"pop %[output]\n\t"
"cli"
:[output]"=q"(res)
:"a"(&lock->writer), "b"(&lock->readers)
:"%edx", "memory");
return res;
}
static inline void rwLockReleaseWrite(struct rwLock_t *lock, uint32t flags) {
asm volatile(""
:
:
:"memory");
lock->writer= 0;
if(likely(flags & 0x200)
asm volatile("sti");
}