semaphore.c中的等待列表实现

时间:2014-03-26 04:47:01

标签: c list linux-kernel semaphore

这是semaphore.h中的信号量结构

16 struct semaphore {
17         raw_spinlock_t          lock;
18         unsigned int            count;
19         struct list_head        wait_list;
20 };

这是semaphore.c中的等待队列结构。

193 struct semaphore_waiter {
194         struct list_head list;
195         struct task_struct *task;
196         int up;
197 };

在函数内部有以下3个语句。

207         struct task_struct *task = current;
208         struct semaphore_waiter waiter;
209 
210         list_add_tail(&waiter.list, &sem->wait_list);

我知道list_add_tail会将waiter.list添加到sem->wait_list的尾部。我不明白的是,由此产生的结构。由于waiter.list属于semaphore_waitersem->wait_list属于struct semaphore,结果列表的类型是struct semaphore还是struct semaphore_waiter

1 个答案:

答案 0 :(得分:2)

list_add_tail

void list_add_tail(struct list_head * new,
                   struct list_head * head);

new添加到head指向的列表的开头。

请注意,内核中的大多数列表都将next / prev指针保留为list_head结构,这是列表本身数据结构的一部分

因此,当您迭代列表(例如p = p->next)时,next指针会将而不是指向数据的开头(此处为struct semaphore_waiter }),但而不是到该结构的list成员

要获取指向列表中包含的数据的指针,请使用container_of宏。这将返回一个指向包含list

的结构的指针

所以,假设您有一个struct semaphore *sem,为简单起见,我们假设它在列表中有一个semaphore_waiter。我们可以得到一个指向该服务员的指针,如:

struct semaphore *sem = <something>;
struct list_head *first;
struct semaphore_waiter *waiter;

// This is a pointer to the 'list' member of the first
// semaphore_waiter in the list
first = sem->wait_list.next;

// Now we "back out" from the list member to the
// (containing) semaphore_waiter itself
waiter = container_of(first, struct semaphore_waiter, list);