linux中了等待佇列的毒,**中充斥著等待佇列。不信你翻翻**。
等待佇列的喚醒我們這裡叫啟用。免得和執行緒喚醒混淆。
頭結點wait_queue_head_t的結構
struct __wait_queue_head ;
// 熟悉的wait_queue_head_t實際上是struct __wait_queue_head
typedef struct __wait_queue_head wait_queue_head_t;
普通節點wait_queue_t的結構
typedef struct __wait_queue wait_queue_t;
//wait_queue_func_t的定義
typedef int (*wait_queue_func_t)(wait_queue_t *wait, unsigned mode, int sync, void *key);
//__wait_queue的定義
struct __wait_queue ;
#define init_list_head(ptr) do while (0)
static inline void init_waitqueue_head(wait_queue_head_t *q)
// 初始化乙個等待佇列entry
// 這個entry在啟用的時候直接會喚醒task_struct執行緒
static inline void init_waitqueue_entry(wait_queue_t *q, struct task_struct *p)
// 初始化乙個等待佇列entry
// 這個entry在啟用的時候僅僅呼叫func.
static inline void init_waitqueue_func_entry(wait_queue_t *q,
wait_queue_func_t func)
extern void fastcall(add_wait_queue(wait_queue_head_t *q, wait_queue_t * wait));
extern void fastcall(add_wait_queue_exclusive(wait_queue_head_t *q, wait_queue_t * wait));
**實現
void fastcall add_wait_queue(wait_queue_head_t *q, wait_queue_t *wait)
static inline void __add_wait_queue(wait_queue_head_t *head, wait_queue_t *new)
static inline void list_add(struct list_head *new, struct list_head *head)
簡化**看
void fastcall add_wait_queue(wait_queue_head_t *q, wait_queue_t *wait)
extern void fastcall(remove_wait_queue(wait_queue_head_t *q, wait_queue_t * wait));
//忽略
#define wake_up(x) __wake_up(x, task_uninterruptible | task_interruptible, 1, null)
#define wake_up_nr(x, nr) __wake_up(x, task_uninterruptible | task_interruptible, nr, null)
#define wake_up_all(x) __wake_up(x, task_uninterruptible | task_interruptible, 0, null)
#define wake_up_interruptible(x) __wake_up(x, task_interruptible, 1, null)
#define wake_up_interruptible_nr(x, nr) __wake_up(x, task_interruptible, nr, null)
#define wake_up_interruptible_all(x) __wake_up(x, task_interruptible, 0, null)
#define wake_up_locked(x) __wake_up_locked((x), task_uninterruptible | task_interruptible)
#define wake_up_interruptible_sync(x) __wake_up_sync((x),task_interruptible, 1)
/** * 啟用等待佇列.
* @q: the waitqueue
* @mode: which threads
* @nr_exclusive: 最多啟用多少個wq_flag_exclusive屬性的entry。0表示都不限制。
*/void fastcall __wake_up(wait_queue_head_t *q, unsigned int mode,
int nr_exclusive, void *key)
/* * 啟用核心**。遍歷所有task_list,取出wait_queue_t結構(巨集操作取出),執行裡面的func。
* nr_exclusive表示要執行多少個wq_flag_exclusive屬性的entry。
*/static void __wake_up_common(wait_queue_head_t *q, unsigned int mode,
int nr_exclusive, int sync, void *key)
}
在等待佇列中,佇列其實是由list_head構成的,而在遍歷啟用entry的時候,可以取出對應的wait_queue_t結構體。如何做到的?
看下wait_queue_t結構。
struct __wait_queue ;
我們一般是從外部去取內部成員,而核心鍊錶是通過內部成員去取外部結構體指標。有什麼好處?這樣可以做通用的鍊錶結構,而不用擔心內部單元型別。
那如何從內部成員獲得外部結構體指標呢?以wait_queue_t 的變數a為例,內部task_list位址記為b。
b- &( ( (wait_queue_t *) 0 )->task_list)
可以獲得wait_queue_t a的位址。
Linux核心等待佇列 原始碼簡單分析
一.概述 二.等待佇列 struct wait queue head typedef struct wait queue head wait queue head t 因為等待佇列可以在中斷的時候進行修改,所以操作佇列之前會給佇列加上乙個自旋鎖,task list其中是雙向佇列 struct wai...
Pytorch原始碼注釋
field類為可以由張量表示的常見文字處理資料型別建模。它包含乙個vocab物件,用於定義字段元素的可能值集及其對應的數字表示。field物件還包含與資料型別應如何數位化有關的其他引數,例如標記化方法和應生成的tensor型別。如果在資料集中的兩列之間共享字段 例如,qa資料集中的問題和答案 則它們...
devmem 原始碼注釋
include include include include include include include include include include include define fatal do while 0 define map size 4096ul define map mask...