#include <acess.h>
#include <threads.h>
+#define TRACE_LOCKS 0
+
+#if TRACE_LOCKS
+extern struct sShortSpinlock glDebug_Lock;
+#endif
+
extern int GetCPUNum(void);
// === CODE ===
#endif
#if LOCK_DISABLE_INTS
- // Save interrupt state and clear interrupts
- __ASM__ ("pushf;\n\tpop %%eax\n\tcli" : "=a"(IF));
+ // Save interrupt state
+ __ASM__ ("pushf;\n\tpop %0" : "=r"(IF));
IF &= 0x200; // AND out all but the interrupt flag
#endif
#else
__ASM__("xchgl %%eax, (%%edi)":"=a"(v):"a"(1),"D"(&Lock->Lock));
#endif
+
+ #if LOCK_DISABLE_INTS
+ if( v ) __ASM__("sti"); // Re-enable interrupts
+ #endif
}
#if LOCK_DISABLE_INTS
+ __ASM__("cli");
Lock->IF = IF;
#endif
+
+ #if TRACE_LOCKS
+ if( Lock != &glDebug_Lock )
+ {
+ //Log_Log("LOCK", "%p locked by %p", Lock, __builtin_return_address(0));
+ LogF("Lock %p locked by %p\n", Lock, __builtin_return_address(0));
+ }
+ #endif
}
/**
* \brief Release a short lock
* \param Lock Lock pointer
*/
void SHORTREL(struct sShortSpinlock *Lock)
-{
+{
#if STACKED_LOCKS
if( Lock->Depth ) {
Lock->Depth --;
}
#endif
+ #if TRACE_LOCKS
+ if( Lock != &glDebug_Lock )
+ {
+ //Log_Log("LOCK", "%p released by %p", Lock, __builtin_return_address(0));
+ LogF("Lock %p released by %p\n", Lock, __builtin_return_address(0));
+ }
+ #endif
+
#if LOCK_DISABLE_INTS
// Lock->IF can change anytime once Lock->Lock is zeroed
if(Lock->IF) {
if(Num < Den*2) return 1;
if(Num == Den*2) return 2;
+ #if 1
+ i = 0; // Shut up
+ P[0] = Num;
+ P[1] = Den;
+ __asm__ __volatile__ (
+ "fildq %2\n\t" // Num
+ "fildq %1\n\t" // Den
+ "fdivp\n\t"
+ "fistpq %0"
+ : "=m" (q)
+ : "m" (P[0]), "m" (P[1])
+ );
+
+ //Log("%llx / %llx = %llx\n", Num, Den, q);
+ #else
// Restoring division, from wikipedia
// http://en.wikipedia.org/wiki/Division_(digital)
P[0] = Num; P[1] = 0;
P[1] += Den;
}
}
+ #endif
return q;
}