[CBRD-25591] Memory in lock free module should be freed only when reusable.
http://jira.cubrid.org/browse/CBRD-25591
Purpose lock free 메모리가 잘못된 타이밍에 free되어 옳지 않은 메모리 참조를 일으킬 수 있으므로 수정이 필요하다.
Implementation 메모리가 재사용 가능하다고 확인된 순간, 즉 메모리가 오직 현재 스레드에 의해서만 접근되고 있는 순간에 free를 수행하도록 한다.
Remarks 기존의 코드에는 MEMORY_BARRIER가 존재했지만, 불필요하다고 생각하여 제거하였다.
1. 기존 MEMORY_BARRIER의 목적은 thread local한 연결 리스트의 블록들을 global 연결 리스트에 넘겨줄 때 thread local 연결 리스트의 연결을 확실하게 끊기 위해 존재했다.
thread local: a->b->c->d (b부터 재사용 가능) global: h->i
(thread local의 블록을 global에 넘겨준다. 이때 thread local의 a에서 b를 가리키는 연결이 끊어져야 한다)
thread local: a global: b->c->d->h->i
2. 그러나 하드웨어 최적화로 인해 연결을 끊는 처리가 조금 밀렸다고 해도 아래 구조가 된다.
thread local: a->b->c->d->h->i global: b->c->d->h->i
하드웨어 최적화는 각 명령 간의 의존성이 존재하지 않을 때까지 미뤄질 수 있다. 즉, 현재 스레드가 다시 a에 접근하기 전까지 미뤄질 수 있다. 그리고 이 연결 리스트는 thread local하므로 미뤄져도 문제가 없다. 다른 스레드에서 접근하지 않을 것이고, 이 스레드에서 a에 접근할 때 a에 대한 처리가 순차적이고 올바르게 이뤄지도록 앞의 명령(연결을 끊는다)을 처리할 것이다.
@hyahong
- 재현 시나리오 (디버깅 로그를 통해 확인)
- LK_ENTRY는 트랜잭션 종속적으로 알고 있는데, 이슈에 리포팅하신 것처럼 상호 참조되는 경우 공유
- 수정 방향성 관련
- 참조가 있다면, 참조되고 있는데 freelist에 들어가는 것이 어색해 보임 (관련해서 논의 필요)