msn: [email protected]
來源:http://yfydz.cublog.cn
1. 前言
struct list_head *next, *prev;
};
struct list_head name = LIST_HEAD_INIT(name)
(ptr)->next = (ptr); (ptr)->prev = (ptr); /
} while (0)
void list_add(struct list_head *new, struct list_head *head);
void list_add_tail(struct list_head *new, struct list_head *head);
void list_del(struct list_head *entry);
void list_move(struct list_head *list, struct list_head *head);
void list_move_tail(struct list_head *list,struct list_head *head);
int list_empty(struct list_head *head);
void list_splice(struct list_head *list, struct list_head *head);
#define list_entry(ptr, type, member) /
((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
#define list_for_each(pos, head) /
for (pos = (head)->next, prefetch(pos->next); pos != (head); /
pos = pos->next, prefetch(pos->next))
#define list_for_each_prev(pos, head) /
for (pos = (head)->prev, prefetch(pos->prev); pos != (head); /
pos = pos->prev, prefetch(pos->prev))
struct list_head list;
int data;
};
{
struct my_list *p;
int i;
for(i=0; i<100; i++){
p=kmalloc(sizeof(struct my_list), GFP_KERNEL);
list_add(&p->list, &mylist);
}
}
在內存中形成如下結構的一個雙向鏈表:
| |
| mylist 99 98 0 |
| +----+ +---------+ +---------+ +---------+ |
+->|next|--->|list.next|--->|list.next|--->...--->|list.next|---+
|----| |---------| |---------| |---------|
+--|prev|<---|list.prev|<---|list.prev|<---...<---|list.prev|<--+
| +----+ |---------| |---------| |---------| |
| | data | | data | | data | |
| +---------+ +---------+ +---------+ |
| |
+---------------------------------------------------------------+
{
list_del(&p->list, &mylist);
kfree(p);
}
((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
member是鏈表元素結構(如struct my_list)中鏈表頭結構list_head參數的名稱
type是鏈表元素結構類型(如struct my_list)
{
struct list_head *cur;
struct my_list *p;
p=list_entry(cur, struct my_list, list);
printk("data=%d/n", p->data);
}
}
1) 鏈表頭中元素置爲NULL不是初始化,與普通習慣不同;
2) 仍然需要單獨編寫各自的刪除整個鏈表的函數,不能統一處理,因爲不能保證所有鏈表元素結構中鏈表頭結構list_head的偏移地址都是相同的,當然如果把鏈表頭結構list_head都作爲鏈表元素結構的第一個參數,就可以用統一的刪除整個鏈表的函數。
3. HASH表
hash_conntrack(const struct ip_conntrack_tuple *tuple)
{
#if 0
dump_tuple(tuple);
#endif
return (jhash_3words(tuple->src.ip,
(tuple->dst.ip ^ tuple->dst.protonum),
(tuple->src.u.all | (tuple->dst.u.all << 16)),
ip_conntrack_hash_rnd) % ip_conntrack_htable_size);
}
static inline u32 jhash_3words(u32 a, u32 b, u32 c, u32 initval)
{
a += JHASH_GOLDEN_RATIO;
b += JHASH_GOLDEN_RATIO;
c += initval;
}
struct timer_list {
struct list_head list;
unsigned long expires;
unsigned long data;
void (*function)(unsigned long);
};
expires:到期時間
function:到期函數,時間到期時調用的函數
data:傳給到期函數的數據,實際應用中通常是一個指針轉化而來,該指針指向一個結構
timer的操作:
extern void add_timer(struct timer_list * timer);
extern int del_timer(struct timer_list * timer);
(del_timer()函數可能會失敗,這是因爲該timer本來已經不在系統timer鏈表中了,也就是已經刪除過了)
extern int del_timer_sync(struct timer_list * timer);
int mod_timer(struct timer_list *timer, unsigned long expires);
struct timer_list通常作爲數據結構中的一個參數,在初始化結構的時候初始化timer,表示到期時要進行的操作,實現定時動作,通常更多的是作爲超時處理的,timer函數作爲超時時的資源釋放函數。注意:如果超時了運行超時函數,此時系統是處在時鐘中斷的bottom half裏的,不能進行很複雜的操作,如果要完成一些複雜操作,如到期後的數據發送,不能直接在到期函數中處理,而是應該在到期函數中發個信號給特定內核線程轉到top half進行處理。
#define time_before(a,b) time_after(b,a)
#define time_before_eq(a,b) time_after_eq(b,a)
arg:線程主函數的參數;
flags:建立線程的標誌;
{
static struct completion startup __initdata = COMPLETION_INITIALIZER(startup);
wait_for_completion(&startup);
return 0;
}
{
struct task_struct *curtask = current;
DECLARE_WAITQUEUE(wait, curtask);
struct k_sigaction sa;
strcpy(curtask->comm, "keventd");
keventd_running = 1;
keventd_task = curtask;
siginitsetinv(&curtask->blocked, sigmask(SIGCHLD));
recalc_sigpending(curtask);
spin_unlock_irq(&curtask->sigmask_lock);
sa.sa.sa_handler = SIG_IGN;
sa.sa.sa_flags = 0;
siginitset(&sa.sa.sa_mask, sigmask(SIGCHLD));
do_sigaction(SIGCHLD, &sa, (struct k_sigaction *)0);
* If one of the functions on a task queue re-adds itself
* to the task queue we call schedule() in state TASK_RUNNING
*/
for (;;) {
set_task_state(curtask, TASK_INTERRUPTIBLE);
add_wait_queue(&context_task_wq, &wait);
if (TQ_ACTIVE(tq_context))
set_task_state(curtask, TASK_RUNNING);
schedule();
remove_wait_queue(&context_task_wq, &wait);
run_task_queue(&tq_context);
wake_up(&context_task_done);
if (signal_pending(curtask)) {
while (waitpid(-1, (unsigned int *)0, __WALL|WNOHANG) > 0)
;
spin_lock_irq(&curtask->sigmask_lock);
flush_signals(curtask);
recalc_sigpending(curtask);
spin_unlock_irq(&curtask->sigmask_lock);
}
}
}
struct my_struct{
int a;
int b;
}c;
...
}