rk3188--12.linux内核中工作队列的实现

两个结构体
struct work_struct {
atomic_long_t data;
struct list_head entry;
work_func_t func;
};

struct workqueue_struct {
unsigned int flags;
union {
struct cpu_workqueue_struct __percpu *pcpu;
struct cpu_workqueue_struct *single;
unsigned long v;
} cpu_wq;
struct list_head list;

struct mutex    flush_mutex;    
int             work_color;     
int             flush_color;     
atomic_t        nr_cwqs_to_flush; 
struct wq_flusher   *first_flusher;    
struct list_head    flusher_queue;     
struct list_head    flusher_overflow; 

mayday_mask_t       mayday_mask;    
struct worker       *rescuer;

int                 saved_max_active; 
const char          *name;        

};

工作队列的使用步骤如下:
//0.首先定义两个结构体:
struct work_struct my_work;
struct workqueue_struct *my_work_queue;
//1.填充一个work_struct
INIT_WORK(&my_work, my_work_process);
//2.显式的创建一个工作队列
my_work_queue = create_workqueue(“my_work”);
//3.将工作提交到工作队列
queue_work(my_work_queue, &my_work);
//4. 调用工作队列处理函数
my_work_process(struct work_struct *work)

  1. 填充一个work_struct

define INIT_WORK(_work, _func) \

do {                            \
    __INIT_WORK((_work), (_func), 0);        \
} while (0)

即:

define __INIT_WORK(_work, _func, _onstack) \

do {                                \
    __init_work((_work), _onstack);                \
    (_work)->data = (atomic_long_t) WORK_DATA_INIT();    \
    INIT_LIST_HEAD(&(_work)->entry);            \
    PREPARE_WORK((_work), (_func));                \
} while (0)

展开后:
__init_work(my_work, 0);
my_work->data = (atomic_long_t) WORK_DATA_INIT();
INIT_LIST_HEAD(&my_work->entry);
PREPARE_WORK(my_work, my_work_process);

  1. 显式的创建一个工作队列

define create_workqueue(name) \

alloc_workqueue((name), WQ_MEM_RECLAIM, 1)

define create_freezable_workqueue(name) \

alloc_workqueue((name), WQ_FREEZABLE | WQ_UNBOUND | WQ_MEM_RECLAIM, 1)

define create_singlethread_workqueue(name) \

alloc_workqueue((name), WQ_UNBOUND | WQ_MEM_RECLAIM, 1)

create_workqueue 与 create_singlethread_workqueue都是调用了alloc_workqueue

define alloc_workqueue(name, flags, max_active) \

__alloc_workqueue_key((name), (flags), (max_active), NULL, NULL)

struct workqueue_struct *__alloc_workqueue_key(const char *name,unsigned int flags, int max_active, struct lock_class_key *key, const char *lock_name)
{
struct workqueue_struct *wq;
unsigned int cpu;

if (flags & WQ_MEM_RECLAIM)
    flags |= WQ_RESCUER;
if (flags & WQ_UNBOUND)
    flags |= WQ_HIGHPRI;

max_active = max_active ?: WQ_DFL_ACTIVE;
max_active = wq_clamp_max_active(max_active, flags, name);

wq = kzalloc(sizeof(*wq), GFP_KERNEL);

wq->flags = flags;
wq->saved_max_active = max_active;
mutex_init(&wq->flush_mutex);
atomic_set(&wq->nr_cwqs_to_flush, 0);
INIT_LIST_HEAD(&wq->flusher_queue);
INIT_LIST_HEAD(&wq->flusher_overflow);

wq->name = name;
lockdep_init_map(&wq->lockdep_map, lock_name, key, 0);
INIT_LIST_HEAD(&wq->list);

alloc_cwqs(wq);        

for_each_cwq_cpu(cpu, wq) {
    struct cpu_workqueue_struct *cwq = get_cwq(cpu, wq);
    struct global_cwq *gcwq = get_gcwq(cpu);

    cwq->gcwq = gcwq;
    cwq->wq = wq;
    cwq->flush_color = -1;
    cwq->max_active = max_active;
    INIT_LIST_HEAD(&cwq->delayed_works);
}

if (flags & WQ_RESCUER) {
    struct worker *rescuer;
    alloc_mayday_mask(&wq->mayday_mask, GFP_KERNEL);
    wq->rescuer = rescuer = alloc_worker();
    rescuer->task = kthread_create(rescuer_thread, wq, "%s", name);
    rescuer->task->flags |= PF_THREAD_BOUND;
    wake_up_process(rescuer->task);
}

spin_lock(&workqueue_lock);

if (workqueue_freezing && wq->flags & WQ_FREEZABLE)
    for_each_cwq_cpu(cpu, wq)
        get_cwq(cpu, wq)->max_active = 0;

list_add(&wq->list, &workqueues);

spin_unlock(&workqueue_lock);

return wq;

}
EXPORT_SYMBOL_GPL(__alloc_workqueue_key);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值