본문 바로가기
실습/리눅스 커널

커널 타이머, 태스크릿, 작업큐

by 써드아이 2021. 2. 8.

[블로그 통합으로 이전해 온 자료] - 2008. 4. 25. 04:42

 

<asm/hardirq.h>

in_interrupt() - 프로세스가 인터럽트 문맥에 있는지 검사 true == 0
in_atomic() - 스케줄링 허용 여부 true == 0
 h/w, s/w 인터럽트는 물론 spinlock을 쥐고있는 경우에도 해당

* kernel timer

- 사용자 영역에 접근해서는 안된다. (copy_*_user류의 함수와 같은..)
 프로세스 문맥이 없으므로 특정 프로세스에 관련된 사용자 영역을 가를키는 경로가 없다.

- current 포인터를 사용해서는 안된다.

- 잠들기나 스케줄링을 수행할 수 없다.
 schedule_(), wait_event_(), kmalloc(), 세마포어등 사용 금지


 <linux/timer.h>
 
 struct timer_list ktimer;
 
 ktimer.data = (unsigned long) data;
 ktimer.expires = jffies var + 지연 값;
 ktimer.function = timer_func;
 
 void timer_func( unsigned long arg )
 {
 }
 
 
 void init_timer( struct timer_list *timer );
 struct timer_list TIMER_INITIALIZER( _function, _expires, _data );
 
 void add_timer( struct timer_list *timer );
 int del_timer( struct timer_list *timer );
 int mod_timer( struct timer_list *timer, unsigned long expires );
 int del_timer_sync( struct timer_list *timer );
 
 int imter_pending( const struct timer_list *timer );


* tasklet

인터럽트 문맥에서 동작해야하며, atomic하게 동작해야한다.

 <linux/interrupt.h>
 
 struct tasklet_struct ktasklet;
 
 ktasklet.func = tasklet_func;
 ktasklet.data = (unsigned long) data;
 
 void tasklet_func( unsigned long arg )
 {
 }
 
 void tasklet_init( struct tasklet_struct *t, void (*func)( unsigned long ), unsigned long data );
 DECLARE_TASKLET( name, func, data );
 DECLARE_TASKET_DISABLE( namac, func, data );
 
 void tasklet_disable( struct tasklet_struct *t );
 void tasklet_disable_nosync( struct tasklet_struct *t );
 void tasklet_enable( struct tasklet_struct *t );
 void tasklet_schedule( struct tasklet_struct *t );
 void tasklet_hi_schedule( struct tasklet_struct *t );
 void tasklet_kill( struct tasklet_struct *t );
 
* work queue

특스 커널 문맥(?)에서 동작하며 atomic할 필요가 없다. 잠들기가 가능하다.

 <linux/workqueue.h>
 
 // 각 프로세스별로 개별 작업큐 생성
 struct workqueue_struct *create_workqueue( const char *name );
 // 단일 작업큐 생성
 struct workqueue_struct *create_singlethread_workqueue( const char *name );

 DECLARE_WORK( name, void (*func)(void*), void *data );
 
 INIT_WORK( struct work_struct *work, void (*function)(void*), void *data );
 PREPARE_WORK( struct work_struct *work, void (*function)(void*), void *data );

 int queue_work( struct workqueue_struct *queue, struct work_struct *work );
 int queue_delayed_work( struct workqueue_struct *queue, struct work_struct *work, unsigned long delay );
 
 int cabcek_dekated_work( struct work_struct *work );
 
 void flush_workqueue( struct workqueue_struct *queue );
 
 void destory_workqueue( struct workqueue_struct *queue );
 

* shared queue

 쓰지 말자. -_-;;

'실습 > 리눅스 커널' 카테고리의 다른 글

Memory Mapping  (0) 2021.02.08
인터럽트 (Interrupt) 처리  (0) 2021.02.08
드라이버 코드의 실행 지연  (0) 2021.02.08
커널에서 Blocking I/O  (0) 2021.02.08
커널에서 condition race 제거  (0) 2021.02.08