spin_lock_irqsave() 에 대하여...
spin_lock 테스트 중에 spin_lock_irqsave(), sin_unlock_irqrestore() 를 사용하면 실행 시에 segmentation fault 를 내며 죽습니다.
아래 소스 중에 spin_lock_irqsave() 대신 spin_lock() 을 사용하고, spin_unlock_irqrestore() 대신 spin_unlock()을 사용하면 잘 돌아갑니다.
spin_lock_irqsave() 나 spin_lock_irq() 를 사용하면 local CPU 의 interrupt를 중지시킨다고 하고, 그냥 spin_lock()은 cpu의 interrupt에 대해서는 아무 처리도 하지 않는다는데.... cpu 의 interrupt에 대해서 정확히 파악되지 않아 안전해 보이는 spin_lock_irqsave()를 사용하려고 합니다.
환경
$ uname -a
Linux xxx.xxx.com 2.4.18 #7 SMP Wed Feb 19 15:44:28 KST 2003 i686 unknown
질문
1. spin_lock_irqsave() 사용시에 segmentation fault를 내고 죽는 이유. (코드 중에 잘못된 부분이 있는지... 아니면 버그인지)
2. CPU의 interrupt에 어떤 종류가 있는지...(질문이 별로군요. 죄송 ^^)
3. spin_lock(), spin_lock_irq(), spin_lock_irqsave() 를 각각 언제 사용해야 하는지...
참고하실 URL은 다음과 같습니다.
http://www.geocrawler.com/archives/3/9221/2002/8/0/9401898/
http://www.linuxgrill.com/anonymous/fire/netfilter/kernel-hacking-HOWTO-5.html
http://lxr.linux.no/source/Documentation/spinlocks.txt
http://www.linuxjournal.com/article.php?sid=5833
#include <asm/system.h>
#include <linux/spinlock.h>
#include <stdio.h>
#include <pthread.h>
#include <time.h>
spinlock_t my_lock;
static __inline__ void
waste_time(void) {
time_t ltime;
ltime = time(NULL);
while (time(NULL) == ltime) ;
}
#define pp(fmt, arg...) printf("thread %d : "fmt, thread_no , ##arg)
static void
thread_func(void *_arg)
{
int thread_no = (int)_arg;
time_t ltime;
unsigned long flags;
while (1) {
pp("out - 0\n");
waste_time();
pp("out - 1\n");
spin_lock_irqsave(&my_lock, flags);
pp("in - 2\n");
waste_time();
pp("in - 3\n");
spin_unlock_irqrestore(&my_lock, flags);
pp("out - 4\n");
}
return 0;
}
int
main(void)
{
pthread_t thread0, thread1, thread2, thread3;
my_lock = SPIN_LOCK_UNLOCKED;
pthread_create(&thread0, NULL, thread_func, (void *)0);
pthread_create(&thread1, NULL, thread_func, (void *)1);
pthread_create(&thread2, NULL, thread_func, (void *)2);
pthread_create(&thread3, NULL, thread_func, (void *)3);
pthread_join(thread0, NULL);
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
pthread_join(thread3, NULL);
return 0;
}

좀 더 찾아 들어가보니.... cli instruction에서 죽는것 같
좀 더 찾아 들어가보니.... cli instruction에서 죽는것 같네요.
제 linux에서는 다음과 같은 코드를 실행하면 "before __cli"까지만 나오고 segmentation fault를 내고 죽습니다.
다른분들은 어떠신지 모르겠네요.
#define __cli() __asm__ __volatile__("cli": : :"memory") #define __sti() __asm__ __volatile__("sti": : :"memory") int main(int argc, char **argv) { printf("before __cli\n"); __cli(); __sti(); printf("after __sti\n"); return 0; }우리 모두 리얼리스트가 되자. 그러나 가슴에 이룰 수 없는 꿈을 가지자
interrupt를 enable/disable하는 sti/cli는
interrupt를 enable/disable하는 sti/cli는
user mode에서 사용불가능합니다.
대신 pthread_mutex_lock/unlock을 사용하세요.
그랬군요.답변 감사합니다.
그랬군요.
답변 감사합니다.
우리 모두 리얼리스트가 되자. 그러나 가슴에 이룰 수 없는 꿈을 가지자
댓글 달기