工作队列的初始化(INIT_WORK的参数问题)

2023-05-16

在编写工作队列的小例子时,遇到

error: macro "INIT_WORK" passed 3 arguments, but takes just 2

 

从2.6.20的内核开始,INIT_WORK宏做了改变,

原来是三个参数,后来改成了两个参数

 

 

from http://blog.csdn.net/fudan_abc/archive/2007/08/20/1751565.aspx

于是就让我们来仔细看看INIT_WORK和INIT_DELAYED_WORK.其实前者是后者的一个特例,它们涉及到的就是传说中的工作队列.这两个宏都定义于include/linux/workqueue.h中:

     79 #define INIT_WORK(_work, _func)                                         /

     80         do {                                                            /

     81                 (_work)->data = (atomic_long_t) WORK_DATA_INIT();       /

     82                 INIT_LIST_HEAD(&(_work)->entry);                        /

     83                 PREPARE_WORK((_work), (_func));                         /

     84         } while (0)

     85

     86 #define INIT_DELAYED_WORK(_work, _func)                         /

     87         do {                                                    /

     88                 INIT_WORK(&(_work)->work, (_func));             /

     89                 init_timer(&(_work)->timer);                    /

     90         } while (0)

 

解决方法:

http://ubuntuforums.org/showthread.php?t=441180

Change the following lines:
static void ppsc_tq_int (void *data) 
change to 
static void ppsc_tq_int (struct work_struct *data)


INIT_WORK (&pha->wq, ppsc_tq_int, pha);

change to
INIT_WORK (&pha->wq, ppsc_tq_int);

成功!

 

另一个解决方法:container_of(不过没试过)

 

http://www.linuxsir.org/bbs/thread310620.html

=>

http://rt2x00.serialmonkey.com/phpBB/viewtopic.php?f=8&t=2951&start=0&st=0&sk=t&sd=a&sid=0681e465914045dedf06f35334b99131

==>

 (about work_struct and INIT_WORK )

http://lwn.net/Articles/213149/

 

 Okay.

(1) Any work_struct struct that has one of the following called upon it:

queue_delayed_work()
queue_delayed_work_on()
schedule_delayed_work()
schedule_delayed_work_on()
cancel_rearming_delayed_work()
cancel_rearming_delayed_workqueue()
cancel_delayed_work()

     needs changing into a delayed_work struct.

     Note that cancel_delayed_work() is often called where it'll be ineffective
     - I think people misunderstand what it does.

(2) A delayed_work struct must be initialised with:

__DELAYED_WORK_INITIALIZER
DECLARE_DELAYED_WORK
INIT_DELAYED_WORK

     Rather than:

__WORK_INITIALIZER
DECLARE_WORK
INIT_WORK

     Those only apply to work_struct (non-delayable work).

(3) The initialisation functions no longer take a data argument, and this
     should be deleted.

(4) Anywhere one of the following is called on a delayed_work struct:

queue_work()
queue_work_on()
schedule_work()
schedule_work_on()

     it must be converted to the equivalent one of:

queue_delayed_work()
queue_delayed_work_on()
schedule_delayed_work()
schedule_delayed_work_on()

     and given a 0 timeout argument as an additional argument.  This just
     queues the work item and doesn't set the timer.

(5) Anywhere the work item's pending flag is examined directly with:

test_bit(0, &work->pending)

     This should be replaced with the appropriate one of:

work_pending(work)
delayed_work_pending(work)

(6) The work function _must_ be changed to conform to the following prototype:

void foo_work_func(struct work_struct *work)
{
...
}

     This applies to both work_struct and delayed_work handlers.

     (a) If the arbitary datum previously passed to the initialiser was NULL,
     then the work argument should just be ignored.

     (b) If the datum was the address of the structure containing the
     work_struct, then something like the following should be used:

struct foo {
struct work_struct worker;
...
};

void foo_work_func(struct work_struct *work)
{
struct foo *foo = container_of(work, struct foo, worker);
...
}

If the work_struct can be placed at the beginning of the containing
structure this will eliminate the subtraction instruction
container_of() might otherwise require.

     (c) If the datum was the address of the structure containing the
     delayed_work, then something like the following should be used:

struct foo {
struct delayed_work worker;
...
};

void foo_work_func(struct work_struct *work)
{
struct foo *foo = container_of(work, struct foo, worker.work);
...
}

NOTE!  There's an extra ".work" in the container_of() because the
work_struct pointed to is embedded within the delayed_work.

     (d) If the datum is not a pointer to the container, but the container is
     guaranteed to exist whilst the work handler runs, then the datum can
     be stored in an extra variable in the container.

The handler would then be formed as for (b) or (c), and the extra
variable accessed after the container_of() line.

Quite often there's a linked pair of structures, with a work_struct in
one being initialised with the address of the other as its datum.  The
typical case is struct net_device and the private data.  In this case
just adding a back pointer from the private data to the net_device
struct seems to work.

     (e) If the auxiliary datum is totally unrelated and can't be stored in an
     extra variable because the container might go away, then the
     work_struct or delayed_work should be initialised with one of these
     instead:

DECLARE_WORK_NAR
DECLARE_DELAYED_WORK_NAR
INIT_WORK_NAR
INIT_DELAYED_WORK_NAR
__WORK_INITIALIZER_NAR
__DELAYED_WORK_INITIALIZER_NAR

These take the same arguments as the normal initialisers, but set a
flag in the work_struct to indicate that the pending flag is not to be
cleared before the work function is called.

The datum is then stored in an extra variable in the container:

struct foo {
struct work_struct worker;
void *worker_data;
...
};

And a work item is initialised with something like this:

void thing(struct foo *foo)
{
...
INIT_WORK_NAR(&foo->worker, foo_work_func);
foo->worker_data = silly_data;
...
}

And then the work function releases the work item itself when it has
extracted the auxiliary data:

void foo_work_func(struct work_struct *work)
{
struct foo *foo = container_of(work, struct foo, worker);
void *silly_data = foo->worker_data;
work_release(work);
...
}

As an added bonus, you can have multiple auxiliary data if you so
desire.  You're not limited to a single word.

(7) If the work function was being called directly, then rather than passing
     in the auxiliary datum, you have to pass in the address of the work_struct
     instead.  So for a work_struct, you'd change:

void call_work(struct foo *foo)
{
...
- foo_work_func(foo);
+ foo_work_func(&foo->worker);
...
}

     And for a delayed_work, you'd do:

void call_work(struct foo *foo)
{
...
- foo_work_func(foo);
+ foo_work_func(&foo->worker.work);
...
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

工作队列的初始化(INIT_WORK的参数问题) 的相关文章

  • python笔记 getattr() delattr() setattr() hasattr()

    python是动态语言 xff0c 类型可以在运行时而不是编译时确定 xff0c 因此就有了非脚本语言所没有的特性 xff0c 可以动态设置对象的属性 attr xff0c 可以使用python内置函数getattr delattr set
  • Python setup()函数使用

    python 有很方便的包管理工具 pip xff0c 实际上任何第三方包都可以通过从对应的pip源一键下载安装 xff0c 并将其所有的依赖 xff08 requirements xff09 自动安装 安装第三方包的本质是可以通过一个方便
  • 数据结构图的建立和遍历(邻接表、邻接矩阵)

    以本代码为基础增加了对图的最短路径计算 路径记录 交互界面等功能 增加代码请看 数据结构课程设计 图的建立和遍历 邻接矩阵 43 邻接表 和最短路径dijkstra路径记录 首先是图的存储结构 xff1a 一 邻接矩阵存储方式实现 邻接矩阵
  • 同时安装了Python2和Python3时的pip使用

    在我电脑上同时安装了Python2和Python3 xff0c 当时按正常操作pip的使用默认是直接调用命令pip install 43 库名 的 xff0c 我在只使用Python3时安装request包时如下 xff1a 直接下载安装
  • Python实现可视化界面多线程豆瓣电影信息爬虫,并绘制统计图分析结果

    完整代码见链接 xff1a https github com kuronekonano python scrapy movie 实现时使用图形界面 多线程 文件操作 数据库编程 网络编程 统计绘图六项技术 1 数据采集 xff08 1 xf
  • Switch离线升级教程【自用】

    想写这篇博客的原因还是因为自己发现明明已经自己通过大佬指导以及论坛教程指导 xff0c 自己实践两次过了完整流程后 xff0c 仍会因为相隔太久的固件更新而遗忘到底如何离线升级 当然这也是自己写的第一篇对于自己实用性较高的生活小技巧 首先根
  • 树莓派上搭建NAS

    树莓派搭建NAS 1 目的 为了实现手机快速备份相片 xff0c MAC Windows iOS Android 多平台之间的资料整合 xff0c 考虑搭建内网使用的私有云 要求价格低 xff0c 体积小 xff0c 功耗低 xff0c 无
  • GLIBC中的库函数fflush究竟做了什么?

    目录 目录 1 1 库函数fflush原型 1 2 FILE结构体 1 3 fflush函数实现 2 4 fclose函数实现 4 附1 xff1a 强弱函数名 5 附2 xff1a 属性 visibility 6 库函数fflush原型
  • vim中如何把在外部复制的内容全部替换粘贴进去

    首先在普通模式下输入ggVG来进行全选 gg命令将光标移动到这个文件的第一列 V命令进行列选择 xff0c 光标经过的行会进行选择 G命令将光标移动到最后一行 3个命令执行后 xff0c 就全选了 然后输入d来将全选的内容删除 然后按i进入
  • iOS关于搜索不规则瀑布流布局的实现小结

    最近在项目开发中遇到了不规则搜索布局的问题 之前常用的解决方案是用一个tableview用一个循环动态的加载 xff0c 唯一的缺点是需要动态的移除 xff0c 其实也已经足够 ios搜索历史记录不规则布局 IOS代码类资源 CSDN下载
  • WORD论文撰写中的必备技巧-公式与排版

    word撰写科技论文时 xff0c 经常会遇到下列问题 xff1a xff08 1 xff09 公式大小与文字不匹配 xff1b xff08 2 xff09 公式对齐问题 xff1b xff08 3 xff09 公式编辑的字符在段落中如何与
  • AirSim(五)---理解篇: Airsim世界坐标系、NED坐标系、机体坐标系以及控制相关API接口函数

    目录 1 坐标系 coordinate system 1 AirSim API的坐标系 xff1a NED 坐标系 with SI unit 2 Unreal Engine的坐标系 xff08 3 xff09 AirSim全局坐标系 61
  • 【部署】外网访问家庭计算机( 内网穿透)

    场景 很多时候需要通过远程访问来进行跨网络跨机器 大部分的场景是访问公司机器 这种一般比较容易实现 xff0c 因为公司都是固定ip xff0c 或者有vpn服务等等 实在不行也可以有teamviewer xff0c anydesk xff
  • 使用wxWidgets开发跨平台的GUI程序

    使用wxWidgets开发跨平台的GUI程序 Taii 回家念经 2006 05 20 1 探索背景 xff1a 1 1 引言 从开始使用c c 43 43 编码起算来也快有5年了 xff0c 期间完成了无数项目 xff0c 编写了无数程序
  • R-4.0.2 forecast预测

    library 34 forecast 34 skirts lt scan 34 http robjhyndman com tsdldata roberts skirts dat 34 skip 61 5 skirtsts lt ts sk
  • Linux远程连接图形界面的几种方法

    1 xff0c 利用Xmanager xff0c linux启用XDMCP协议 xff08 可直接修改配置文件 xff0c 也可以采用在Xshell中运行gdmconfig或gdmsetup xff0c 选择XDMCP选项卡 xff0c 勾
  • 什么是视图?作用是什么?

    1 1 视图 1 1 1 什么是视图 视图 VIEW 也被称作虚表 xff0c 即虚拟的表 xff0c 是一组数据的逻辑表示 其本质是对应于一条SELECT语句 xff0c 结果集被赋予一个名字 xff0c 即视图名字 视图本身并不包含任何
  • Python元组(tuple)详解

    目录 一 元组的基本概念 xff1a 二 元组的特点 xff1a 1 声明方式 2 访问方式 xff1a 3 元组中元素的修改 xff1a 三 xff0c 对元组的操作 1 元组的切片 xff1a 2 元组的拼接 xff1a 3 元组与数字
  • 解决debian下thinkpad x1没有声音的问题

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 文章目录 问题描述 一 解决方法 二 解决步骤 1 使用non free源 2 更改参数 3 更新源信息 4 安装以下驱动包 5 重启 问题描述 安装完debian 11后
  • windows环境变量配置你知道吗?

    1 什么是windows环境变量 xff1f 我们直接看百度的专业解释 环境变量 xff08 environment variables xff09 一般是指在操作系统中用来指定操作系统运行环境的一些参数 xff0c 如 xff1a 临时文

随机推荐