· KLDP.org · KLDP.net · KLDP Wiki · KLDP BBS ·
Memory Bus Lock

Memory bus lock (Mutex)

개요


  • 메모리의 Bus lock을 lock이라는 어셈블리 명령어를 사용하여 C언어만으로는 만들수 없는 Lock을 구현한것입니다. 이 소스는 SMP에서도 잘 돌아갈것입니다. 이유는 Memory의 bus를 lock하는 것이기 때문에 가능한 것입니다. x86계열 호환입니다. 코드는 VC++ 또는 gcc 로 컴파일 가능합니다.
  • PowerPC계열의 PPC405(IBM) 관련해서 포팅하면 다음과 같이 되겠죠. (AtomicExchangeSwap)

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");


소스


/*
 Code by JaeHyuk Cho <mailto:minzkn@infoeq.com> Made in KOREA
 http://minzkn.pe.ky
*/

#ifndef DEF_SOURCE_lock_c
#define DEF_SOURCE_lock_c "lock.c"

#include <stdio.h>
#include <sched.h>

#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 */



ID
Password
Join
You have the power to influence all with whom you come in contact.


sponsored by andamiro
sponsored by cdnetworks
sponsored by HP

Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2004-12-04 20:30:06
Processing time 0.0036 sec