== Memory bus lock (Mutex) == === °³¿ä === * ¸Þ¸ð¸®ÀÇ Bus lockÀ» '''lock'''À̶ó´Â ¾î¼Àºí¸® ¸í·É¾î¸¦ »ç¿ëÇÏ¿© C¾ð¾î¸¸À¸·Î´Â ¸¸µé¼ö ¾ø´Â LockÀ» ±¸ÇöÇÑ°ÍÀÔ´Ï´Ù. ÀÌ ¼Ò½º´Â '''SMP'''¿¡¼­µµ Àß µ¹¾Æ°¥°ÍÀÔ´Ï´Ù. ÀÌÀ¯´Â '''MemoryÀÇ bus¸¦ lock'''ÇÏ´Â °ÍÀ̱⠶§¹®¿¡ °¡´ÉÇÑ °ÍÀÔ´Ï´Ù. x86°è¿­ ȣȯÀÔ´Ï´Ù. ÄÚµå´Â '''VC++''' ¶Ç´Â '''gcc''' ·Î ÄÄÆÄÀÏ °¡´ÉÇÕ´Ï´Ù. * PowerPC°è¿­ÀÇ PPC405(IBM) °ü·ÃÇؼ­ Æ÷ÆÃÇÏ¸é ´ÙÀ½°ú °°ÀÌ µÇ°ÚÁÒ. (AtomicExchangeSwap) {{{#!vim c int s_Return; MZ_ASM( "0:\n\t" "lwarx %0,0,%1\n\t" "stwcx. %2,0,%1 \n\t" "bne- 0b\n\t" "\n\t" : "=&r" (s_Return) : "r" (s_To), "r" (s_Value) : "cr0", "memory"); }}} === ¼Ò½º === {{{#!vim c /* Code by JaeHyuk Cho Made in KOREA http://minzkn.pe.ky */ #ifndef DEF_SOURCE_lock_c #define DEF_SOURCE_lock_c "lock.c" #include #include #define DEF_STDCALL __attribute__((stdcall)) #define __DEF_FCTYPE__ DEF_STDCALL /* Pascal È£Ãâ±ÔÄ¢»ç¿ëÀ¸·Î Á» ºü¸¦·Á³ª? */ #ifdef WIN32 #define MZ_ASM __asm #else #define MZ_ASM __asm__ volatile #endif static int __DEF_FCTYPE__ __MZ_Lock__(int * volatile s_LockFlag, int s_Switch); static int __DEF_FCTYPE__ __MZ_AtomicExchange__(int * volatile s_To, int s_Value); int MZ_InitLock(int * volatile s_Key); void MZ_Lock(int * volatile s_Key); void MZ_UnLock(int * volatile s_Key); static int __DEF_FCTYPE__ __MZ_Lock__(int * volatile s_LockFlag, int s_Switch) { int s_Return; int s_LockTime = 0, s_TimeOut; s_TimeOut = (s_Switch >> 2) * 100; L_SpinLoop:; s_Return = __MZ_AtomicExchange__(s_LockFlag, s_Switch); if(s_Switch != 0 && s_Return != 0) { if(s_TimeOut != 0 && s_LockTime > s_TimeOut) { fprintf(stderr, "%s: %s - [ERROR] Dead-lock instead of off (%d second timeout) !!!\n", __FILE__, __FUNCTION__, s_TimeOut * 100); s_Return = __MZ_AtomicExchange__(s_LockFlag, 0); } else { sched_yield(); s_LockTime++; goto L_SpinLoop; } } return(s_Return); } static int __DEF_FCTYPE__ __MZ_AtomicExchange__(int * volatile s_To, int s_Value) { register int s_Return; #ifdef WIN32 MZ_ASM { PUSH EBX; MOV EAX, s_Value; MOV EBX, s_To; LOCK XCHG DWORD PTR [EBX], EAX; POP EBX; } #else MZ_ASM( "\n\t" "lock xchgl %1, (%2)\n\t" "\n\t" : "=a"(s_Return) : "a"(s_Value), "r"(s_To) ); #endif return(s_Return); } int MZ_InitLock(int * volatile s_Key) { if(s_Key)MZ_UnLock(s_Key); return(0); } void MZ_Lock(int * volatile s_Key) { (void)__MZ_Lock__(s_Key, 1); } void MZ_UnLock(int * volatile s_Key) { (void)__MZ_Lock__(s_Key, 0); } #endif /* End of source */ }}}