mutex_init() / mutex_lock() / mutex_unlock()

2023-11-17

请求

1). 初始化互斥体 -- mutex_init();
2). 获得互斥体 -- mutex_lock();
3). 释放互斥体 -- mutex_unlock();

1.mutex_init(), 注意mutex使用之前都需要先init

void
__mutex_init(struct mutex *lock, const char *name, struct lock_class_key *key)
{
        atomic_long_set(&lock->owner, 0);
        spin_lock_init(&lock->wait_lock);
        INIT_LIST_HEAD(&lock->wait_list);
#ifdef CONFIG_MUTEX_SPIN_ON_OWNER
        osq_lock_init(&lock->osq);
#endif

        debug_mutex_init(lock, name, key);
}
EXPORT_SYMBOL(__mutex_init);

/**
 * mutex_init - initialize the mutex
 * @mutex: the mutex to be initialized
 *
 * Initialize the mutex to unlocked state.
 *
 * It is not allowed to initialize an already locked mutex.
 */
#define mutex_init(mutex)                                               \
do {                                                                    \
        static struct lock_class_key __key;                             \
                                                                        \
        __mutex_init((mutex), #mutex, &__key);                          \
} while (0)

2.mutex_lock(), 注意看注释说明,
a). 如果mutex已经被其他task获取,那么目前的task先sleep直到获取;
b). mutex不能被嵌套获取;上一个task释放mutex之后,才能被其他的task获取;
c). mutex要先被初始化才能使用;mutex正在使用过程中,其内存不能被释放;

//------kernel4.4------
/**
 * mutex_lock - acquire the mutex
 * @lock: the mutex to be acquired
 *
 * Lock the mutex exclusively for this task. If the mutex is not
 * available right now, it will sleep until it can get it.
 *
 * The mutex must later on be released by the same task that
 * acquired it. Recursive locking is not allowed. The task
 * may not exit without first unlocking the mutex. Also, kernel
 * memory where the mutex resides must not be freed with
 * the mutex still locked. The mutex must first be initialized
 * (or statically defined) before it can be locked. memset()-ing
 * the mutex to 0 is not allowed.
 *
 * ( The CONFIG_DEBUG_MUTEXES .config option turns on debugging
 *   checks that will enforce the restrictions and will also do
 *   deadlock debugging. )
 *
 * This function is similar to (but not equivalent to) down().
 */
void __sched mutex_lock(struct mutex *lock)
{
        might_sleep();
        /*
         * The locking fastpath is the 1->0 transition from
         * 'unlocked' into 'locked' state.
         */
        __mutex_fastpath_lock(&lock->count, __mutex_lock_slowpath);
        mutex_set_owner(lock);
}

//======kernel4.14======
/**
 * mutex_lock - acquire the mutex
 * @lock: the mutex to be acquired
 *
 * Lock the mutex exclusively for this task. If the mutex is not
 * available right now, it will sleep until it can get it.
 *
 * The mutex must later on be released by the same task that
 * acquired it. Recursive locking is not allowed. The task
 * may not exit without first unlocking the mutex. Also, kernel
 * memory where the mutex resides must not be freed with
 * the mutex still locked. The mutex must first be initialized
 * (or statically defined) before it can be locked. memset()-ing
 * the mutex to 0 is not allowed.
 *
 * (The CONFIG_DEBUG_MUTEXES .config option turns on debugging
 * checks that will enforce the restrictions and will also do
 * deadlock debugging)
 *
 * This function is similar to (but not equivalent to) down().
 */
void __sched mutex_lock(struct mutex *lock)
{
        might_sleep();
                
        if (!__mutex_trylock_fast(lock))
                __mutex_lock_slowpath(lock);
}
EXPORT_SYMBOL(mutex_lock);

3. mutex_unlock(), 释放互斥体
a). 释放之前获得的mutex;
b). mutex只有被获得,才能调用这个函数来释放;换言之,如果没有获得,就没有必要做释放的动作;

//======kernel 4.4======
/**
 * mutex_unlock - release the mutex
 * @lock: the mutex to be released
 *
 * Unlock a mutex that has been locked by this task previously.
 *
 * This function must not be used in interrupt context. Unlocking
 * of a not locked mutex is not allowed.
 *
 * This function is similar to (but not equivalent to) up().
 */
void __sched mutex_unlock(struct mutex *lock)
{
        /*
         * The unlocking fastpath is the 0->1 transition from 'locked'
         * into 'unlocked' state:
         */
#ifndef CONFIG_DEBUG_MUTEXES
        /*
         * When debugging is enabled we must not clear the owner before time,
         * the slow path will always be taken, and that clears the owner field
         * after verifying that it was indeed current.
         */
        mutex_clear_owner(lock);
#endif
        __mutex_fastpath_unlock(&lock->count, __mutex_unlock_slowpath);
}

EXPORT_SYMBOL(mutex_unlock);

//=======kernel 4.14======
/**     
 * mutex_unlock - release the mutex
 * @lock: the mutex to be released
 *
 * Unlock a mutex that has been locked by this task previously.
 *
 * This function must not be used in interrupt context. Unlocking
 * of a not locked mutex is not allowed.
 *      
 * This function is similar to (but not equivalent to) up().
 */
void __sched mutex_unlock(struct mutex *lock)
{
#ifndef CONFIG_DEBUG_LOCK_ALLOC
        if (__mutex_unlock_fast(lock))
                return;
#endif
        __mutex_unlock_slowpath(lock, _RET_IP_);
}       
EXPORT_SYMBOL(mutex_unlock);

 

如果lock只在interrupt handler里使用,则没有必要加。中断handler本身就是不可重入的,不存在竞争。 

static irqreturn_t xxxx_typec_interrupt(int irq, void *data)
{
        struct xxxx_typec *sc = data;
        u32 event;
        int ret;

        //mutex_lock(&sc->lock);
        ret = regmap_read(sc->regmap, XXXX_INT_MASK, &event);
        if (ret)
                goto unlock;

        event &= XXXX_EVENT_MASK;

        ret = regmap_read(sc->regmap, XXXX_STATUS, &sc->state);
        if (ret)
                goto clear_ints;

        sc->state &= XXXX_STATE_MASK;

        if (event & XXXX_ATTACH_INT) {
                ret = XXxx_typec_connect(sc, sc->state);
                if (ret)
                        dev_warn(sc->dev, "failed to register partner\n");
        } else if (event & XXXX_DETACH_INT) {
                xxxx_typec_disconnect(sc, sc->state);
        }

clear_ints:
        regmap_write(sc->regmap, XXXX_INT_CLR, event);
unlock:
        //mutex_unlock(&sc->lock);

        dev_info(sc->dev, "now works as DRP and is in %d state, event %d\n",
                sc->state, event);
        return IRQ_HANDLED;
}


static int xxxx_typec_probe(struct platform_device *pdev)
{
        struct xxxx_typec *sc;
        int ret;

        struct device *dev = &pdev->dev;
        struct device_node *node = pdev->dev.of_node;
        u32 value = 0;

        sc = devm_kzalloc(&pdev->dev, sizeof(*sc), GFP_KERNEL);
        if (!sc)
                return -ENOMEM;

        sc->edev = devm_extcon_dev_allocate(&pdev->dev, xxxx_typec_cable);
        if (IS_ERR(sc->edev)) {
                dev_err(&pdev->dev, "failed to allocate extcon device\n");
                return PTR_ERR();
        }

        ret = devm_extcon_dev_register(&pdev->dev, sc->edev);
        if (ret < 0) {
                dev_err(&pdev->dev, "can't register extcon device: %d\n", ret);
                return ret;
        }

        //mutex_init(&sc->lock);
        sc->dev = &pdev->dev;
        sc->irq = platform_get_irq(pdev, 0);
        ...
        ret = devm_request_threaded_irq(sc->dev, sc->irq, NULL,
                                        xxxx_typec_interrupt,
                                        IRQF_EARLY_RESUME | IRQF_ONESHOT,
                                        dev_name(sc->dev), sc);
        ...
}

 

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

mutex_init() / mutex_lock() / mutex_unlock() 的相关文章

  • Kconfig内容(详细)总结附示例快速掌握

    目录 一 简介 二 内容解析 2 1 menuconfig 2 2 choice endchoice 2 3 comment 2 4 menu endmunu 2 5 if endif 2 6 source 2 7 mainmenu 2 8
  • CPU虚拟化技术

    基本概念 物理CPU数量 实际服务器插槽上的CPU个数 核 一块CPU上面能处理数据的芯片组的数量 超线程 在一个实体芯片组中提供两个逻辑线程 逻辑CPU数量 物理CPU数量 核 超线程 若支持超线程 该值为2 vCPU 虚机分配的CPU
  • 联想小新Pro14安装Ubuntu后无法进入系统、亮度无法调节、蓝牙无法打开、输入卡顿延迟等问题的解决办法

    联想小新Pro14安装Ubuntu后无法进入系统 亮度无法调节 蓝牙无法打开等问题的解决办法 前言 月初买了台联想小新Pro14 AMD锐龙5800H版本 在安装Ubuntu 20 04 2 LTS 系统时遇到了一些问题 所幸在众多网友前辈
  • 树莓派基于Linux内核驱动开发详解

    目录 一 驱动认知 1 1 为什么要学习写驱动 1 2 文件名与设备号 1 3 open函数打通上层到底层硬件的详细过程 二 基于框架编写驱动代码 2 1 编写上层应用代码 2 2 修改内核驱动框架代码 2 3 部分代码解读 2 3 1 s
  • gdb调试常见命令详细总结(附示例操作)

    一 简介 通过gdb调试我们可以监控程序执行的每一个细节 包括变量的值 函数的调用过程 内存中数据 线程的调度等 从而发现隐藏的错误或者低效的代码 程序的调试过程主要有 单步执行 跳入函数 跳出函数 设置断点 设置观察点 查看变量 本文将主
  • 一文快速了解进程、线程与协程

    进程与线程 进程是操作系统进行资源分配的基本单位 每个进程都有自己的独立内存空间 由于进程比较重量 占据独立的内存 所以上下文进程间的切换开销 栈 寄存器 虚拟内存 文件句柄等 比较大 但相对比较稳定安全 线程又叫做轻量级进程 是进程的一个
  • 还不会部署高可用的kubernetes集群?企业DevOps实践之使用kubeadm方式安装高可用k8s集群v1.23.7...

    关注 WeiyiGeek 公众号 设为 特别关注 每天带你玩转网络安全运维 应用开发 物联网IOT学习 原文地址 还不会部署高可用的kubernetes集群 企业DevOps实践之使用kubeadm方式安装高可用k8s集群v1 23 7 本
  • arch/x86/entry/syscall_64.o:(.rodata+0xa78): undefined reference to `sys_get_pid_info‘

    今天添加系统调用以后 使用make指令编译内核的时候出现了 arch x86 entry syscall 64 o rodata 0xa78 undefined reference to sys myprint 这个错误 错误原因是我使用的
  • 基于mykernel的简单时间片轮转多道程序内核代码分析

    一 实验环境 1 mykernel mykernel是由科大孟宁老师建立的一个用于开发您自己的操作系统内核的平台 它基于Linux Kernel 3 9 4 source code 我们可以在这里找到mykernel的源代码 https g
  • 性能测试系列(二)

    性能测试之性能分析命令 1 CPU分析 a cpu基本信息 命令 lscpu Cpu架构 64 位 Cpu 核心数 6 NUMA UMA节点数为 2个 显示值加 1 Cpu的核心频率 说明此服务器为虚拟机 此服务器的 cpu使用的是 使用的
  • Linux的IO端口和IO内存

    Linux的IO端口和IO内存 分类 linux编程 2011 01 14 13 22 866人阅读 评论 1 收藏 举报 io linux linux内核 struct 平台 x86 CPU对外设端口物理地址的编址方式有两种 一种是IO映
  • 关于 Linux 之父,你可能不知道的 7 件事

    如果让你现在说出三个程序员的名字 Linus 很可能就在其中 作为世界上最著名的电脑程序员 黑客之一 Linus Benedict Torvalds 写出了 Linux 内核 1 0 版 发起了开源运动 开发了代码管理工具 Git 这三个成
  • 第一次动手构建 Linux 内核

    目录 背景 机器参数 参考链接 操作流程 步骤1 下载 Linux 内核源码 步骤 2 解压源码 步骤 3 下载所需软件包 步骤 4 内核配置 步骤 5 开始构建 步骤 5 1 make 步骤 5 2 make INSTALL MOD ST
  • Linux-DM9000C网卡移植(详解)

    上一节 我们学习了 网卡驱动介绍以及制作虚拟网卡驱动 http www cnblogs com lifexy p 7763352 html 接下来本节 学习网卡芯片DM9000C 如何编写移植DM9000C网卡驱动程序 1 首先来看DM90
  • Unix网络编程5种IO模型

    IO模型 用一幅图表示所支持的I O模型 纵向维度是 阻塞 Blocking 非阻塞 Non blocking 横向维度是 同步 异步 总结起来是四种模型 同步阻塞 同步非阻塞 异步阻塞 异步非阻塞 Unix网络编程 中划分出了 第五种 模
  • 不管人工智能发展如何 开发者都有必要了解 Linux 内核

    Linux内核在计算机世界的地位有目共睹 称它为计算机世界的基石也不为过 而且它还是全球最大的开源项目 几乎最知名的科技公司都参与其中 包括谷歌 Red Hat SUSE Intel Facebook 甲骨文和华为等 当然还包括Linux的
  • 国产开源IoTOS:腾讯物联网操作系统TencentOS Tiny的探索与实践

    导语 腾讯物联网终端操作系统 TencentOS tiny 是腾讯面向物联网领域自主研发的嵌入式实时操作系统 可助力物联网终端设备及业务快速接入腾讯云物联网平台 本文是对腾讯高级工程师汪礼超 赵健在云 社区 online 分享的整理 为大家
  • Linux用户空间与内核空间

    Linux用户空间与内核空间 2012 08 30 15 39 1969人阅读 评论 1 收藏 举报 linux linux内核 struct user system allocation Linux 操作系统和驱动程序运行在内核空间 应用
  • MS-RTOS 内核模块动态装载

    1 MS RTOS 内核模块动态装载简介 MS RTOS 支持内核模块动态装载功能 用户可以根据需要 在不需要对内核重新编译的情况下 使用 insmod rmmod 等命令动态地将模块加入或移出内核 这样可以提高 MS RTOS 的灵活性
  • 【Linux】向Linux 5.11.8内核加入新的系统调用

    目录 特殊声明 A mathcal A A 获取root权限

随机推荐

  • 【经验贴】新手项目经理如何接手并管好项目?

    最近有刷到这样一些求助帖 初入职场两三年的项目经理现在开始独立带项目 由于缺乏经验不知道从何下手 询问如何能快速接手并管好项目呢 这个话题也引起了大家的热议 今天就给大家分享一下一些实践经验 1 刚拿到项目时 应该做哪些准备 新接手项目时
  • Octave 计算数据 from 吴恩达的机器学习

    1 乘积 A C 2 点乘 A B 将矩阵A中的元素点乘B中的对应元素相乘 A 2 对矩阵A中的每一个元素平方 1 A 得到每一个元素的倒数 3 log A 对每个元素进行求对数运算 4 exp A 自然数e的幂次运算 就是以e为底 以这些
  • MySql8.0以上版本安装

    一 下载mysql8 0 1 官网地址 https www mysql com 2 进入下载页面 3 选择版本下载 二 安装mysql 1 配置环境变量 变量名 MYSQL HOME 变量值 mysql存放路径 例如 D mysql 8 0
  • postgresql 扩展pg_cron,pg_stat_statements安装配置

    一 概述 pg cron是基于cron的作业调度插件 语法与常规cron相同 但它可以直接从数据库执行PostgreSQL命令 pg stat statements模块提供一种方法追踪一个服务器所执行的所有 SQL 语句的执行统计信息 可以
  • 技术和商业角度刷脸支付都将成为未来趋势

    刷脸支付 我们作为消费者来说 最直观的感受就是我们的支付方式发生了变化 付钱更方便了 从最开始我们带着现金出门买东西 到后来二维码支付 一个手机扫遍天下 对于商家来说他不需要停下来手中在做的事情来收钱找零 而对于我们消费者来说也是非常的快捷
  • Python 内置数据类型 03----元组

    目 录 1 元组的简介 1 1 元组概念 1 2 元组创建方式 1 2 1 使用 直接创建 1 2 2 使用 tuple 函数创建 1 3 元组访问方式 2 处理元组的内置函数 2 1 len 函数 2 2 max 函数 2 3 min 函
  • 【编程测试题】数列还原

    数列还原 题目描述 牛牛的作业薄上有一个长度为 n 的排列 A 这个排列包含了从1到n的n个数 但是因为一些原因 其中有一些位置 不超过 10 个 看不清了 但是牛牛记得这个数列顺序对的数量是 k 顺序对是指满足 i lt j 且 A i
  • virtualbox网络常见问题,virtualbox linux 无法访问网络,virtual box 中 linux ping 不通,配置NAT ssh 无法连接

    问题1 在virtualbox 安装了 linux 发现无法访问网络 解决 不要去改 etc resolv conf 正确的做法是在virtual box配置NAT地址转发 补充一下 我发现mac每次加载虚拟机都要点开高级 然后点端口配置
  • python opencv数组转图片 并显示

    pred是数组类型 先转为8位 pred np array pred np uint8 cv2 imshow 123 pred cv2 waitKey 0
  • Basic Level 1025 反转链表 (25分)

    题目 给定一个常数 K 以及一个单链表 L 请编写程序将 L 中每 K 个结点反转 例如 给定 L 为 1 2 3 4 5 6 K 为 3 则输出应该为 3 2 1 6 5 4 如果 K 为 4 则输出应该为 4 3 2 1 5 6 即最后
  • vue项目 依赖打包 与 import和dependencies 的关系

    项目打包时 依赖与package json中的dependencies和devDependencies并无关 我曾这样认为了好久 原来他们之间的关系是这样的 项目打包的依赖来自于你import from xxx 如无特殊设置 import的
  • 信息安全无小事,手把手教你日志脱敏

    场景 我们开发的程序迟早有一天都会上线到生产环境运行 但是没有人能保证自己的代码100 不出BUG 别抬扛 真没BUG是代码写的少 当我们线上出BUG之后 最常见的定位问题方法就是排查日志文件 所以我们一般都会在开发程序时 在适当的位置输出
  • scikit-learn工具包中常用的特征选择方法介绍

    对于特征选择的作用在这里照搬 西瓜书 中的描述 常用的特征选择方法有以下三种 备注 以下代码采用Jupyter notebook编写 格式与传统稍有不同 1 过滤式特征选择 简单理解就是过滤式特征选择通过选择与响应变量 目标变量 相关性度量
  • typora 编辑器基本用法

    Markdown 由 Daring Fireball 创建 原始指南在 这里 但是 它的语法因不同的解析器或编辑器而异 Typora 正在使用 GitHub Flavored Markdown 1 段落换行 按 Shift Return 可
  • Unity3D碰撞后去掉相互之间的反弹力

    最近做一个小游戏的时候发现 小模型碰撞到墙壁之后会有一个小小的反弹力导致模型有一个微弱的回弹位移 这样给人一种不好的感觉 研究了一下 除了 rigidbody Freeze Rotation之外 在FixedUpdate 注意这里是物理特性
  • mysql 正序_请问mysql 中 怎么实现这种排序,按照状态排序正序,再按照开始时间排序正序,...

    展开全部 有两个思路 1 按照各自的活动状态先排序 插入到临时表 最后再union all所有结32313133353236313431303231363533e58685e5aeb931333363353862果集create tempo
  • calico分配网络使k8s节点指定固定网段

    文章目录 calico分配网络使k8s节点指定固定网段 1 配置calicoctl 1 1 下载calicoctl 1 2 配置calicoctl 1 3 测试calicoctl 2 配置ippool 3 添加ippool 4 创建pod测
  • vue3`

    1 ref是一个函数 响应式数据 使用前要引入 impor ref fro vue let name ref 张三 改变数据 name value 李四 vue3对不同对象处理不同 数据劫持才是响应式的根本 getset 处理对象用prox
  • SpringBoot生成二维码

    目录 Zxing原生方式 添加依赖 二维码生成工具类 添加Controller 添加测试页面 使用postman测试效果 Hutool的方式 添加依赖 创建QRCodeService 添加Controller 效果测试 我们使用两种方式 去
  • mutex_init() / mutex_lock() / mutex_unlock()

    请求 1 初始化互斥体 mutex init 2 获得互斥体 mutex lock 3 释放互斥体 mutex unlock 1 mutex init 注意mutex使用之前都需要先init void mutex init struct m