使用rust实现linux里é¢çš„list_headæ•°æ®ç»“构,åªå®žçŽ°æ‰€éœ€è¦çš„功能,并ä¸æ˜¯å®Œå…¨ä½“。
rust
pub struct ListHead {
pub prev: *mut ListHead,
pub next: *mut ListHead,
}
rust
list_head! //声明一个ListHead并åˆå§‹åŒ–
list_head_init! //åˆå§‹åŒ–一个å˜åœ¨çš„listhead
list_add! //æ’入队列 head<-->3<-->2<-->1
list_add_tail! //尾端æ’å…¥ head<-->1<-->2<-->3
is_list_empty! //队列是å¦ç©º
list_del! //从队列ä¸åˆ 除
offset_of! // 结构体å—段å移é‡
container_of! // 从结构体å—段推导其宿主结构体
to_list_head_ptr! //主è¦list_hadå—段转为裸指针
align_to! // å‘上对é½
ç›®å‰ç”¨åœ¨slab模å—ä¸ï¼Œç”±äºŽslabä¸èƒ½ä½¿ç”¨rustå†…ä¸Žå †åˆ†é…相关的数æ®ç»“构以åŠæ™ºèƒ½æŒ‡é’ˆï¼Œå› æ¤åº•å±‚åªèƒ½ä»¥è£¸æŒ‡é’ˆçš„å½¢å¼æž„é€ åŒç«¯é“¾è¡¨ã€‚æ¤ç»“æž„ä¸èƒ½å•ç‹¬ä½¿ç”¨ï¼Œä¸€èˆ¬ä½œä¸ºæŸä¸ªå—段放在一个自定义结构体ä¸ã€‚
```rust
struct Demo { listhead: ListHead, first: usize, second: usize, } listhead!(head); let mut demo1 = Demo { listhead: ListHead::default(), first: 1, second: 2, }; listheadinit!(demo1.listhead); listadd!(tolistheadptr!(demo1.listhead), tolistheadptr!(head)); //listaddtail!(tolistheadptr!(demo1.listhead), tolistheadptr!(head)); listdel!(tolistheadptr!(demo1.listhead)); ```
计算å—段å移
rust
let mut demo1 = Demo {
list_head: ListHead::default(),
first: 1,
second: 2,
};
let list_head_ptr = to_list_head_ptr!(demo1.list_head);
let list_head_offset = offset_of!(Demo, list_head);
let list_head_ptr2 = list_head_ptr as usize - list_head_offset;
let demo1_ptr = list_head_ptr2 as *mut Demo;
assert_eq!(demo1_ptr, &mut demo1 as *mut Demo);
获å–宿主结构体
rust
let mut demo1 = Demo {
list_head: ListHead::default(),
first: 1,
second: 2,
};
let list_head_ptr = to_list_head_ptr!(demo1.list_head);
let demo1_ptr = container_of!(list_head_ptr as usize, Demo, list_head);
assert_eq!(demo1_ptr, &mut demo1 as *mut Demo);
使用iter
è¿ä»£
rust
list_head!(head); //链表头
list_head!(head2); //链表头
list_head!(head3); //链表头
list_add_tail!(to_list_head_ptr!(head2), to_list_head_ptr!(head));
list_add_tail!(to_list_head_ptr!(head3), to_list_head_ptr!(head));
let x = &head;
x.iter().for_each(|_list_head|{
//println!("list_head:{:?}", list_head);
});
assert_eq!(x.next, to_list_head_ptr!(head2));
assert_eq!(x.len(), 2);