typedef struct fairlock { u8 curr; u8 ticket; } fairlock_t; static inline init_fairlock(fairlock_t *lock) { memset(lock,0,sizeof(*lock)); } /* * spin lock fairly */ static inline void fair_lock(fairlock_t *lock) { u8 number = 1; __asm__ __volatile__( "# beginning fair_lock\n\t" LOCK_PREFIX " xaddb %b2,%1\n\t" /* number = lock->ticket; lock->ticket++; */ "1:\n\t" " cmpb %b2,%0\n\t" " jne 2f\n\t" /* jump if number!=lock->curr */ LOCK_SECTION_START("") "2:\n\t" " rep; nop\n\t" " jmp 1b\n" LOCK_SECTION_END "# ending fair_lock\n\t" : "=m"(lock->curr), "=m"(lock->ticket), "=r"(number) : "r"(lock), "m"(lock->curr), "m"(lock->ticket), "2"(number) : "memory", "cc"); } /* * spin trylock fairly */ static inline void fair_trylock(fairlock_t *lock) { u32 tmp; __asm__ __volatile__( "# beginning fair_trylock\n\t" " movw (%3),%%ax\n\t" /* AL=curr, AH=ticket */ "1:\n\t" " cmpb %%al,%%ah\n\t" " je 3f\n\t" /* jump if maybe we can get it */ "2:\n\t" LOCK_SECTION_START("") "3:\n\t" " leaw 1(%ax),%w2\n\t" /* [propose] ticket=ticket+1 */ LOCK_PREFIX " cmpxchgw %w2,(%3)\n\t" " je 3b\n\t" /* jump if worked */ " rep; nop\n\t" /* didn't work; AL & AH have been updated */ " jmp 1b\n" LOCK_SECTION_END "# ending fair_trylock\n\t" : "=m"(lock->curr), "=m"(lock->ticket), "=$r"(tmp) : "r"(lock), "m"(lock->curr), "m"(lock->ticket) : "memory", "cc", "eax"); } /* * spin unlock fairly */ static inline void fair_unlock(fairlock_t *lock) { u8 number; __asm__ __volatile__( "# beginning fair_unlock\n\t" LOCK_PREFIX " incb %1\n\t" /* lock->curr++; */ "# ending fair_unlock\n\t" : "=m"(lock->curr) : "r"(lock), "m"(lock->curr) : "memory", "cc"); }