X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Kernel%2Farch%2Fx86%2Finclude%2Farch.h;h=0fec144e65bc7ef77c0d9c8656c55a07d5c09d8f;hb=15999a03acd4083fb2618c92bebbc557813c5084;hp=67a629016f6839576c7bbf30fb921dffa5decacb;hpb=7d881c2e5fef91a6570e46ef69a5d4a5cf0e8b4d;p=tpg%2Facess2.git diff --git a/Kernel/arch/x86/include/arch.h b/Kernel/arch/x86/include/arch.h index 67a62901..0fec144e 100644 --- a/Kernel/arch/x86/include/arch.h +++ b/Kernel/arch/x86/include/arch.h @@ -29,47 +29,70 @@ #define __ASM__ __asm__ __volatile__ -#define LONGLOCK_NUM_THREADS 8 - -// === MACROS === +// === Spinlocks === +/** + * \brief Short Spinlock structure + */ struct sShortSpinlock { - volatile int Lock; - int IF; + volatile int Lock; //!< Lock value + int IF; //!< Interrupt state on call to SHORTLOCK }; /** * \brief Determine if a short spinlock is locked + * \param Lock Lock pointer */ static inline int IS_LOCKED(struct sShortSpinlock *Lock) { return !!Lock->Lock; } /** * \brief Acquire a Short Spinlock - * \note Stops interrupts, so be careful + * \param Lock Lock pointer + * + * This type of mutex should only be used for very short sections of code, + * or in places where a Mutex_* would be overkill, such as appending + * an element to linked list (usually two assignement lines in C) + * + * \note This type of lock halts interrupts, so ensure that no timing + * functions are called while it is held. */ static inline void SHORTLOCK(struct sShortSpinlock *Lock) { int v = 1; - __ASM__ ("pushf;\n\tpop %%eax" : "=a"(Lock->IF)); - Lock->IF &= 0x200; - __ASM__ ("cli"); // Stop task switches + int IF; + // int val = GetCPUNum() + 1; + + // Save interrupt state and clear interrupts + __ASM__ ("pushf;\n\tcli;\n\tpop %%eax" : "=a"(IF)); + IF &= 0x200; + // Wait for another CPU to release while(v) - __ASM__("xchgl %%eax, (%%edi)":"=a"(v):"a"(1),"D"(&Lock->Lock)); + __ASM__("xchgl %%ecx, (%%edi)":"=c"(v):"a"(1),"D"(&Lock->Lock)); + + Lock->IF = IF; } /** * \brief Release a short lock + * \param Lock Lock pointer */ static inline void SHORTREL(struct sShortSpinlock *Lock) { - Lock->Lock = 0; - #if 0 - __ASM__ ("pushf;\n\tor %0, (%%esp);\n\tpopf" : : "a"(Lock->IF)); - #else - if(Lock->IF) __ASM__ ("sti"); - #endif + // Lock->IF can change anytime once Lock->Lock is zeroed + if(Lock->IF) { + Lock->Lock = 0; + __ASM__ ("sti"); + } + else { + Lock->Lock = 0; + } } + +// === MACROS === /** * \brief Halt the CPU */ #define HALT() __asm__ __volatile__ ("hlt") +/** + * \brief Fire a magic breakpoint (bochs) + */ #define MAGIC_BREAK() __asm__ __volatile__ ("xchg %bx, %bx") // === TYPES ===