출처 http://kuaaan.tistory.com/99

Q1: 동일한 스레드에서 동일한 CriticalSection에 두번 진입하면 Block이 걸릴까?
A1: 아니다. 스레드가 이미 자신이 소유한 CriticalSection을 다시 소유하려고 시도하는 것은 전혀 문제될 것이 없다. CriticalSection 개체는 내부적으로 LockCount와 OwningThread라는 멤버가 있어서 자신이 몇번 Lock이 걸렸는지와 어느 스레드에 소유되었는지를 기억하고 있다. 
다른 스레드가 소유한 CriticalSection 개체에 대해 EnterCriticalSection을 시도하면 당연히 Block되겠지만, CriticalSection을 소유한 스레드가 다시 EnterCriticalSection을 시도하면 즉시 리턴되고, 내부적으로 LockCount가 하나 증가한다. 대신, EnterCriticalSection한 횟수만큼 LeaveCriticalSection을 호출해주어야 CriticalSection 개체가 Signaled 상태로 돌아온다. 두번 EnterCriticalSection한 후 한번만 LeaveCriticalSection하면? 당연히 한번 EnterCriticalSection했을 때의 상태와 동일해진다.

디버거에서 CriticalSection 개체를 들여다 보면 아래와 같은 멤버들로 구성된 것을 알 수 있다. LockCount의 초기값은 -1이고, 한번 소유되면 0으로 증가한다.

※ 참고로... linux의 posix mutex는 lock을 두번 걸 경우 데드락에 걸리는 문제가 있었다.


Q2: A라는 스레드가 소유한 CriticalSection을 B라는 제3의 스레드가 해제할 수 있나?
A2: 그렇다. CriticalSection에 진입할 때는 Thread를 확인하지만 Leave할때는 확인하지 않으며, 임의의 스레드라도 CriticalSection을 해제할 수 있다.

Q3: 어느 Thread에도 소유되지 않은 CriticalSection에 대해 LeaveCriticalSection을 호출하면 어떻게 되나?
A3: 이런 일이 벌어져선 안된다 ㅡ.ㅡ. LeaveCriticalSection을 호출하면 LockCount가 초기값인 -1에서 하나 더 감소하여 -2가 된다. 이 상태에서는 LeaveCriticalSection을 호출했던 스레드를 포함하여 어떠한 스레드도 EnterCriticalSection을 할 수 없게 된다. (시도하면 Block된다.)
이런 경우 CriticalSection을 삭제하고 다시 만드는 방법밖에 없다.

Q4: CriticalSection을 소유한 Thread가 죽어버리면 CriticalSection은 Lock이 풀릴까?
A4: 풀리지 않는다. (반면에 커널객체인 Mutex나 Event 등은 소유한 Process가 죽으면 소멸된다.) 따라서 이런 일이 벌어지면 Application이 Hang 걸려버리는 경우가 생긴다. 단, 위에서 언급한 바와 같이 소유한 Thread가 죽어버린 CriticalSection을 제 3의 Thread가 LeaveCriticalSection 해줄 수는 있다.

※ Mutex의 경우 해당 개체를 소유한 Thread가 죽으면 자동으로 Signaled 상태로 변경된다. 즉, 저절로 Lock이 풀리게 된다. 이때 WaitForSingleObject()로 대기중이던 스레드는 함수 리턴값으로 WAIT_ABANDONDED 을 받게 된다. (CriticalSectioin과 Mutex의 차이)

출처 : http://kuaaan.tistory.com/99
Posted by 패스맨

댓글을 달아 주세요

http://www.jegerlehner.ch/intel/opcode.html

TRANSFER
Name Comment Syntax
MOV Move (copy) MOV Dest,Source
XCHG Exchange XCHG Op1,Op2
STC Set Carry STC
CLC Clear Carry CLC
CMC Complement Carry CMC
STD Set Direction STD
CLD Clear Direction CLD
STI Set Interrupt STI
CLI Clear Interrupt CLI
PUSH Push onto stack PUSH Source
PUSHF Push flags PUSHF
PUSHA Push all general registers PUSHA
POP Pop from stack POP Dest
POPF Pop flags POPF
POPA Pop all general registers POPA
CBW Convert byte to word CBW
CWD Convert word to double CWD
CWDE Conv word extended double CWDE
IN Input IN Dest, Port
OUT Output OUT Port, Source

ARITHMETIC
Name Comment Syntax
ADD Add ADD Dest,Source
ADC Add with Carry ADC Dest,Source
SUB Subtract SUB Dest,Source
SBB Subtract with borrow SBB Dest,Source
DIV Divide (unsigned) DIV Op
IDIV Signed Integer Divide IDIV Op
MUL Multiply (unsigned) MUL Op
IMUL Signed Integer Multiply IMUL Op
INC Increment INC Op
DEC Decrement DEC Op
CMP Compare CMP Op1,Op2
SAL Shift arithmetic left SAL Op,Quantity
SAR Shift arithmetic right SAR Op,Quantity
RCL Rotate left through Carry RCL Op,Quantity
RCR Rotate right through Carry RCR Op,Quantity
ROL Rotate left ROL Op,Quantity
ROR Rotate right ROR Op,Quantity

LOGIC
Name Comment Syntax
NEG Negate (two-complement) NEG Op
NOT Invert each bit NOT Op
AND Logical and AND Dest,Source
OR Logical or OR Dest,Source
XOR Logical exclusive or XOR Dest,Source
SHL Shift logical left SHL Op,Quantity
SHR Shift logical right SHR Op,Quantity

MISCELLANEOUS
Name Comment Syntax
NOP No operation NOP
LEA Load effective adress LEA Dest,Source
INT Interrupt INT Nr

JUMPS (general)
Name Comment Syntax
CALL Call subroutine CALL Proc
JMP Jump JMP Dest
JE Jump if Equal JE Dest
JZ Jump if Zero JZ Dest
JCXZ Jump if CX Zero JCXZ Dest
JP Jump if Parity (Parity Even) JP Dest
JPE Jump if Parity Even JPE Dest
RET Return from subroutine RET
JNE Jump if not Equal JNE Dest
JNZ Jump if not Zero JNZ Dest
JECXZ Jump if ECX Zero JECXZ Dest
JNP Jump if no Parity (Parity Odd) JNP Dest
JPO Jump if Parity Odd JPO Dest

JUMPS unsigned (Cardinal)
JA Jump if Above JA Dest
JAE Jump if Above or Equal JAE Dest
JB Jump if Below JB Dest
JBE Jump if Below or Equal JBE Dest
JNA Jump if not Above JNA Dest
JNAE Jump if not Above or Equal JNAE Dest
JNB Jump if not Below JNB Dest
JNBE Jump if not Below or Equal JNBE Dest
JC Jump if Carry JC Dest
JNC Jump if no Carry JNC Dest

JUMPS signed (Integer)
JG Jump if Greater JG Dest
JGE Jump if Greater or Equal JGE Dest
JL Jump if Less JL Dest
JLE Jump if Less or Equal JLE Dest
JNG Jump if not Greater JNG Dest
JNGE Jump if not Greater or Equal JNGE Dest
JNL Jump if not Less JNL Dest
JNLE Jump if not Less or Equal JNLE Dest
JO Jump if Overflow JO Dest
JNO Jump if no Overflow JNO Dest
JS Jump if Sign (= negative) JS Dest
JNS Jump if no Sign (= positive) JNS Dest

'Programing > asm' 카테고리의 다른 글

어셈블리어  (0) 2011.11.29
OpCode of Intel Assembly 80x86  (0) 2011.03.07
Posted by 패스맨

댓글을 달아 주세요

http://dhna.tistory.com/44 출처



#define PATHNAME "/Movie/Action"

#define MOVIEDATA           PATHNAME##"/Data"



#, ##, #@

## 연산자
  ## 연산자를 사용해서 토큰을 합성해서 만들어 낼 수 있다. ##은 합치기 연산자 이다.
  ex) #define MACRO_APPEND(str1, str2) printf("%s\n", str1##str2)

# 연산자
  # 연산자는 전달된 인자를 문자열로 변환시킨다.
  ex) #define MACRO_STRING(str) printf("%s\n", #str);

#@ 연산자
  #@ 연산자는 전달된 인자를 문자로 변환시킨다.



미리 정의된 매크로

__STDC__ : 컴파일러가 ANSI C 표준을 따를 경우 1로 정의되며 그렇지 않을 경우
                 정의되지 않는다. C++로 컴파일할 때는 이 매크로가 없다.
__FILE__ : 현재 소스 파일의 완전 경로이다.
__LINE__ : 파일명
__DATE__  : 컴파일될 때의 날짜를 나타내는 문자열이다.
__TIME__ : 현재 소스가 최후로 수정된 날짜와 시간을 나타낸다. 
__TIMESTAMP__ : 현재 소스가 최후 컴파일된 시간을 나타내는 문자열이다.
__func__ : 함수명 (컴파일러가 처리, c99 표준) 
__FUNCTION__  : 함수명 (컴파일러가 처리, 컴파일러마다 다름)



Visual C++에서 미리 정의된 매크로

_DEBUG : 디버그 모드로 컴파일중일 때만 정의된다.
__cplusplus : C++ 모드로 컴파일중일 때만 정의된다.
_DLL : DLL 프로젝트일 때만 정의된다.
_MSC_VER : 비주얼 C++의 컴파일러 버전을 나타낸다. 6.0은 1200으로 정의되며 7.0(닷넷)은 1300으로 정의된다.
_MFC_VER : MFC 라이브러리의 버전값
_ATL_VER : ATL의 버전값
_WIN32 : Win32 환경일 때 정의된다.
_WIN64 : Win64 환경일 때 정의된다.
__COUNTER__ : 참조될 때마다 1씩 증가하는 정수값이다. 유일한 이름을 만들고자 할 때 이 매크로를 사용한다.
                        7.0 이상에서만 제공된다.
_M_ALPHA, _M_IX86, _M_IA64, _M_MPPC : CPU의 종류이다. 플랫폼에 따라 약간씩 코드가 달려져야 할 때 이 매크로를 참조한다. 


http://dhna.tistory.com/44 출처
Posted by 패스맨

댓글을 달아 주세요