diff --git a/src/sys/i386/spinlock.c b/src/sys/i386/spinlock.c index a09ec6b..c5fae1e 100644 --- a/src/sys/i386/spinlock.c +++ b/src/sys/i386/spinlock.c @@ -27,7 +27,6 @@ *****************************************************************************************/ -#include #include #include @@ -44,43 +43,6 @@ /* Pause instruction to prevent excess processor bus usage */ #define cpu_relax() asm volatile("pause\n": : :"memory") -/* Atomic exchange (of various sizes) */ -static inline u_long xchg_64(volatile uint32_t *ptr, u_long x) { - __asm__ __volatile__("xchgq %1,%0" - :"+r" (x), - "+m" (*ptr)); - - return x; -} - -static inline unsigned xchg_32(volatile uint32_t *ptr, uint32_t x) { - __asm__ __volatile__("xchgl %1,%0" - :"+r" (x), - "+m" (*ptr)); - - return x; -} - -static inline unsigned short xchg_16(volatile uint32_t *ptr, uint16_t x) { - __asm__ __volatile__("xchgw %1,%0" - :"+r" (x), - "+m" (*ptr)); - - return x; -} - -/* Test and set a bit */ -static inline char atomic_bitsetandtest(void *ptr, int x) { - char out; - __asm__ __volatile__("lock; bts %2,%1\n" - "sbb %0,%0\n" - :"=r" (out), "=m" (*(volatile long long *)ptr) - :"Ir" (x) - :"memory"); - - return out; -} - void spinLockInit(spinLock_t lock) { memset(lock, 0x0, sizeof(spinLock_t)); } diff --git a/src/sys/include/ubixos/spinlock.h b/src/sys/include/ubixos/spinlock.h index 21352d6..e9a61bf 100644 --- a/src/sys/include/ubixos/spinlock.h +++ b/src/sys/include/ubixos/spinlock.h @@ -25,7 +25,7 @@ $Id: spinlock.h 79 2016-01-11 16:21:27Z reddawg $ -*****************************************************************************************/ + *****************************************************************************************/ #ifndef _SPINLOCK_H #define _SPINLOCK_H @@ -57,4 +57,41 @@ int spinLockLocked(spinLock_t *); +/* Atomic exchange (of various sizes) */ +static inline u_long xchg_64(volatile uint32_t *ptr, u_long x) { + __asm__ __volatile__("xchgq %1,%0" + :"+r" (x), + "+m" (*ptr)); + + return x; +} + +static inline unsigned xchg_32(volatile uint32_t *ptr, uint32_t x) { + __asm__ __volatile__("xchgl %1,%0" + :"+r" (x), + "+m" (*ptr)); + + return x; +} + +static inline unsigned short xchg_16(volatile uint32_t *ptr, uint16_t x) { + __asm__ __volatile__("xchgw %1,%0" + :"+r" (x), + "+m" (*ptr)); + + return x; +} + +/* Test and set a bit */ +static inline char atomic_bitsetandtest(void *ptr, int x) { + char out; + __asm__ __volatile__("lock; bts %2,%1\n" + "sbb %0,%0\n" + :"=r" (out), "=m" (*(volatile long long *)ptr) + :"Ir" (x) + :"memory"); + + return out; +} + #endif diff --git a/src/sys/kernel/ubthread.c b/src/sys/kernel/ubthread.c index 7b6c875..60ada0c 100644 --- a/src/sys/kernel/ubthread.c +++ b/src/sys/kernel/ubthread.c @@ -90,14 +90,20 @@ if (ubmutex->lock == true && ubmutex->pid != _current->id) { kprintf("Mutex Already Lock By PID %x Wiating To Be Relocked By %x\n",ubmutex->pid,_current->id); + while (1) { + if (!xchg_32(&ubmutex->lock, true)) + break; + while (ubmutex->lock == true) sched_yield(); } + } else if (ubmutex->lock == true && ubmutex->pid == _current->id) { kprintf("Mutex Already Locked By This Thread"); + return(0x0); } - atomic_exchange(&ubmutex->lock, true); + ubmutex->pid = _current->id; return(0x0); } @@ -106,7 +112,8 @@ ubthread_mutex_t ubmutex = *mutex; if (ubmutex->pid == _current->id) { - atomic_exchange(&ubmutex->lock, false); + while(xchg_32(&ubmutex->lock, false)) + sched_yield(); return(0x0); } else { @@ -114,7 +121,8 @@ while (ubmutex->pid != _current->id) sched_yield(); kprintf("GOT IT UNLOCKING"); - atomic_exchange(&ubmutex->lock, false); + while (!xchg_32(&ubmutex->lock, false)) + sched_yield(); return(0x0); } } @@ -123,7 +131,7 @@ ubthread_cond_t ubcond = *cond; ubthread_mutex_t ubmutex = *mutex; - uInt32 enterTime = systemVitals->sysUptime+20; + uint32_t enterTime = systemVitals->sysUptime+20; ubthread_mutex_unlock(mutex); @@ -148,6 +156,7 @@ int ubthread_cond_signal(ubthread_cond_t *cond) { ubthread_cond_t ubcond = *cond; - atomic_exchange(&ubcond->lock, false); + while (xchg_32(&ubcond->lock, false)) + sched_yield(); return(0x0); }