linux -信号量semphore分析

news2024/11/26 2:39:56

linux -信号量分析

      • 1 struct semaphore和sema_init
        • 1.1 struct semaphore
        • 1.2 sema_init
      • 2 down
      • 3 up
      • 4 down_interruptible
      • 5 down_killable
      • 6 down_timeout
      • 7 down_trylock

基于linux-5.15分析,信号量在使用是是基于spin lock封装实现的。

1 struct semaphore和sema_init

1.1 struct semaphore

/* Please don’t access any members of this structure directly */
struct semaphore {
raw_spinlock_t lock;
unsigned int count;
struct list_head wait_list;
};

1.2 sema_init

在这里插入图片描述

#define __SEMAPHORE_INITIALIZER(name, n)                                \
{                                                                       \
        .lock           = __RAW_SPIN_LOCK_UNLOCKED((name).lock),        \
        .count          = n,                                            \
        .wait_list      = LIST_HEAD_INIT((name).wait_list),             \
}
                                                                                                                                                                                                           
#define DEFINE_SEMAPHORE(name)  \
        struct semaphore name = __SEMAPHORE_INITIALIZER(name, 1)

static inline void sema_init(struct semaphore *sem, int val)
{
        static struct lock_class_key __key;
        *sem = (struct semaphore) __SEMAPHORE_INITIALIZER(*sem, val);
        lockdep_init_map(&sem->lock.dep_map, "semaphore->lock", &__key, 0); 
}

2 down

在这里插入图片描述

static inline int __sched __down_common(struct semaphore *sem, long state,
                                                                long timeout)
{
        struct semaphore_waiter waiter;

        list_add_tail(&waiter.list, &sem->wait_list);
        waiter.task = current;
        waiter.up = false;

        for (;;) {
                if (signal_pending_state(state, current)) 
                        goto interrupted;
                if (unlikely(timeout <= 0))
                        goto timed_out;
                __set_current_state(state);
                raw_spin_unlock_irq(&sem->lock);
                timeout = schedule_timeout(timeout);                                                                                                                                                       
                raw_spin_lock_irq(&sem->lock);
                if (waiter.up)
                        return 0;
        }

 timed_out:
        list_del(&waiter.list);
        return -ETIME;

 interrupted:
        list_del(&waiter.list);
        return -EINTR;
}
        
static noinline void __sched __down(struct semaphore *sem)
{       
        __down_common(sem, TASK_UNINTERRUPTIBLE, MAX_SCHEDULE_TIMEOUT);
}

/**
 * down - acquire the semaphore
 * @sem: the semaphore to be acquired
 *
 * Acquires the semaphore.  If no more tasks are allowed to acquire the
 * semaphore, calling this function will put the task to sleep until the
 * semaphore is released.
 *
 * Use of this function is deprecated, please use down_interruptible() or
 * down_killable() instead.
 */
void down(struct semaphore *sem)
{
        unsigned long flags;

        might_sleep();
        raw_spin_lock_irqsave(&sem->lock, flags);
        if (likely(sem->count > 0))
                sem->count--;
        else                                                                                                                                                                                               
                __down(sem);
        raw_spin_unlock_irqrestore(&sem->lock, flags);
}

3 up

暂时无法在{app_display_name}文档外展示此内容

static noinline void __sched __up(struct semaphore *sem)
{       
        struct semaphore_waiter *waiter = list_first_entry(&sem->wait_list,
                                                struct semaphore_waiter, list);
        list_del(&waiter->list);
        waiter->up = true;                                                                                                                                                                                 
        wake_up_process(waiter->task);
}

/**    
 * up - release the semaphore
 * @sem: the semaphore to release
 *
 * Release the semaphore.  Unlike mutexes, up() may be called from any
 * context and even by tasks which have never called down().
 */    
void up(struct semaphore *sem)                                                                                                                                                                             
{
        unsigned long flags;

        raw_spin_lock_irqsave(&sem->lock, flags);
        if (likely(list_empty(&sem->wait_list)))
                sem->count++;
        else
                __up(sem);
        raw_spin_unlock_irqrestore(&sem->lock, flags);
}

4 down_interruptible

static noinline int __sched __down_interruptible(struct semaphore *sem)
{                                                                                                                                                                                                          
        return __down_common(sem, TASK_INTERRUPTIBLE, MAX_SCHEDULE_TIMEOUT);
}

/**    
 * down_interruptible - acquire the semaphore unless interrupted
 * @sem: the semaphore to be acquired
 *
 * Attempts to acquire the semaphore.  If no more tasks are allowed to
 * acquire the semaphore, calling this function will put the task to sleep.
 * If the sleep is interrupted by a signal, this function will return -EINTR.
 * If the semaphore is successfully acquired, this function returns 0.
 */    
int down_interruptible(struct semaphore *sem)                                                                                                                                                              
{
        unsigned long flags;
        int result = 0;

        might_sleep();
        raw_spin_lock_irqsave(&sem->lock, flags);
        if (likely(sem->count > 0))    
                sem->count--;
        else
                result = __down_interruptible(sem);
        raw_spin_unlock_irqrestore(&sem->lock, flags);

        return result;
}

5 down_killable

static noinline int __sched __down_killable(struct semaphore *sem)
{
        return __down_common(sem, TASK_KILLABLE, MAX_SCHEDULE_TIMEOUT);
}

/**    
 * down_killable - acquire the semaphore unless killed
 * @sem: the semaphore to be acquired
 *
 * Attempts to acquire the semaphore.  If no more tasks are allowed to
 * acquire the semaphore, calling this function will put the task to sleep.
 * If the sleep is interrupted by a fatal signal, this function will return
 * -EINTR.  If the semaphore is successfully acquired, this function returns
 * 0.  
 */    
int down_killable(struct semaphore *sem)                                                                                                                                                                   
{
        unsigned long flags;
        int result = 0;

        might_sleep();
        raw_spin_lock_irqsave(&sem->lock, flags);
        if (likely(sem->count > 0))    
                sem->count--;
        else
                result = __down_killable(sem); 
        raw_spin_unlock_irqrestore(&sem->lock, flags);

        return result;
}

6 down_timeout

static noinline int __sched __down_timeout(struct semaphore *sem, long timeout)
{
        return __down_common(sem, TASK_UNINTERRUPTIBLE, timeout);
}

/**
 * down_timeout - acquire the semaphore within a specified time
 * @sem: the semaphore to be acquired
 * @timeout: how long to wait before failing
 *
 * Attempts to acquire the semaphore.  If no more tasks are allowed to
 * acquire the semaphore, calling this function will put the task to sleep.
 * If the semaphore is not released within the specified number of jiffies,
 * this function returns -ETIME.  It returns 0 if the semaphore was acquired.
 */
int down_timeout(struct semaphore *sem, long timeout)
{
        unsigned long flags;                                                                                                                                                                               
        int result = 0;

        might_sleep();
        raw_spin_lock_irqsave(&sem->lock, flags);
        if (likely(sem->count > 0))
                sem->count--;
        else
                result = __down_timeout(sem, timeout);
        raw_spin_unlock_irqrestore(&sem->lock, flags);

        return result;
}

7 down_trylock

  • count = sem->count - 1;
  • likely(count >= 0)
  • sem->count = count;
/**
 * down_trylock - try to acquire the semaphore, without waiting
 * @sem: the semaphore to be acquired
 *
 * Try to acquire the semaphore atomically.  Returns 0 if the semaphore has
 * been acquired successfully or 1 if it cannot be acquired.
 *
 * NOTE: This return value is inverted from both spin_trylock and
 * mutex_trylock!  Be careful about this when converting code.
 *
 * Unlike mutex_trylock, this function can be used from interrupt context,
 * and the semaphore can be released by any task or interrupt.
 */
int down_trylock(struct semaphore *sem)
{
        unsigned long flags;
        int count;
                                                                                                                                                                                                           
        raw_spin_lock_irqsave(&sem->lock, flags);
        count = sem->count - 1;
        if (likely(count >= 0))
                sem->count = count;    
        raw_spin_unlock_irqrestore(&sem->lock, flags);

        return (count < 0);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/701359.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

爬虫入门指南:如何使用正则表达式进行数据提取和处理

文章目录 正则表达式正则表达式中常用的元字符和特殊序列案例 使用正则表达式提取数据案例存储数据到文件或数据库使用SQLite数据库存储数据的示例代码SQLite基本语法创建表格&#xff1a;插入数据&#xff1a;查询数据&#xff1a;更新数据&#xff1a;删除数据&#xff1a;条…

【雕爷学编程】Arduino动手做(137)---MT8870语音解码

37款传感器与执行器的提法&#xff0c;在网络上广泛流传&#xff0c;其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块&#xff0c;依照实践出真知&#xff08;一定要动手做&#xff09;的理念&#xff0c;以学习和交流为目的&am…

【uview calendar日历 】如何选择今天之前的数据

在日常工作中&#xff0c;使用uniappuview的ui组件&#xff0c;使用日历组件默认是无法选择当前之前的日期&#xff0c;现在讲下解决的方法 设置 最小的可选日期minDate&#xff0c;最大可选日期maxDate&#xff0c; 默认选中的日期&#xff0c;mode为multiple或range是必须为数…

自定义选项卡组件,选项可插槽html

文件夹xxtabs 四个文件 index暴露 render vue添加虚拟节点到插槽&#xff08;自定义标签结构&#xff09; tabs选项卡整体 abpaneq切换区 tabs.vue <template><div class"gnip-tab"><div class"gnip-tab-nav"><divv-for"(item,…

“sudo”组不存在”或“用户不在 sudoers 文件中。此事将被报告”

解决方法: 使用命令&#xff1a;usermod -a -G sudo tom (换成其他的用户名&#xff0c;也是一个道理)&#xff0c;不过还是不行。 实际解决还是要执行 sudo visudo &#xff0c;在这个文件中去添加用户 这样修改之后&#xff0c;保存并退出&#xff0c;亲测有效&#xff01; …

【FFmpeg实战】AAC编码介绍

AAC&#xff08;Advanced Audio Coding&#xff0c;译为&#xff1a;高级音频编码&#xff09;&#xff0c;是由Fraunhofer IIS、杜比实验室、AT&T、Sony、Nokia等公司共同开发的有损音频编码和文件格式。 对比MP3 AAC被设计为MP3格式的后继产品&#xff0c;通常在相同的比…

训练自己的ChatGPT 语言模型(一).md

0x00 Background 为什么研究这个&#xff1f; ChatGPT在国内外都受到了广泛关注&#xff0c;很多高校、研究机构和企业都计划推出类似的模型。然而&#xff0c;ChatGPT并没有开源&#xff0c;且复现难度非常大&#xff0c;即使到现在&#xff0c;没有任何单位或企业能够完全复…

Atlas200 DK A2与Arduino进行UART串口通信

我们在做一些人工智能的应用开发时往往使用人工智能开发板作为上位机&#xff08;比如我们的小滕&#xff09;&#xff0c;Arduino、stm32等作为下位机控制板&#xff0c;通过上位机进行人工智能模型的推理之后进而给下位机传输对应的控制命令实现智能控制。那么如何实现两者的…

简化交互体验——探索Gradio的ClearButton模块

❤️觉得内容不错的话&#xff0c;欢迎点赞收藏加关注&#x1f60a;&#x1f60a;&#x1f60a;&#xff0c;后续会继续输入更多优质内容❤️ &#x1f449;有问题欢迎大家加关注私戳或者评论&#xff08;包括但不限于NLP算法相关&#xff0c;linux学习相关&#xff0c;读研读博…

ndarray对象怎样创建?ndarray基本属性列举

numpy中包含一个N维数组对象&#xff0c;即ndarray对象&#xff0c;该对象具有矢量算术能力和复杂的广播能力&#xff0c;常用于科学计算。ndarray对象中的元素可以通过索引访问&#xff0c;索引序号从0开始;ndarray对象中存储的所有元素的类型必须相同。创建ndarray对象的方式…

输入框设置placeholder的文字居中

<input classlogin-form-pwd placeholder请输入商家登录密码 placeholder-class"center"></input> .center{ text-align: center; }

Linux下 MHA故障切换 主从角色提升

目录 所有主机共同操作 manger操作 其他四台安装 搭建主从复制环境 nobe slave1 配置 slave2 slave3 配置 配置MHA环境 简述MHA&#xff1a; MHA&#xff08;Master High Availability&#xff09;目前在MySQL高可用方面是一个相对成熟的解决方案&#xff0c;它由…

MySQL中的DDL操作,MySQL中DML操作,MySQL查询数据,SQL函数,MySQL中的索引,MySQL事务,MySQL的用户管理,MySQL分页查询

目录 MySQL中的DDL操作 一、创建表与删除表 1&#xff0c;创建表 2&#xff0c;查看已创建的表。 3&#xff0c;删除表 二、修改表 1&#xff0c;修改表名 2&#xff0c;修改列名 3&#xff0c;修改列类型 4&#xff0c;添加新列 5&#xff0c;删除指定列 三、MySQ…

劳保鞋厂家带你深入了解防静电安全鞋——百华劳保

静电小则电人&#xff0c;大则引起火灾。静电的能量虽然不大&#xff0c;但其易放电&#xff0c;会出现静电火花&#xff0c;在易燃易爆场所&#xff0c;可能因静电火花引起火灾和爆炸。现在的工厂不少都是要求穿着具有防静电性能的工作鞋&#xff0c;很多劳动者都会穿着防静电…

使用Docker Swarm部署RabbitMQ+HAProxy高可用集群(三节点-镜像模式)

1. 部署规划 当前规划中&#xff0c;只启动一个HAProxy服务&#xff0c;主要用来做RabbitMQ节点的负载均衡和代理&#xff0c;但是HAProxy可能会出现单点故障&#xff0c;后续需要启动多个HAProxy节点&#xff0c;然后结合Keepalived来进行 设置虚拟IP 做故障转移 节点名称节…

nvm安装nodejs-2023年6月29日

nvm安装nodejs-2023年6月29日 cmd命令行&#xff0c;执行如下代码&#xff0c;表示安装最新稳定版本的node,这里默认是国外的node节点服务器 nvm install lts报错的话&#xff0c;找到安装目录&#xff0c;打开settings.txt&#xff0c;添加如下代码 更换node的国内淘宝镜像节…

cnocr安装和识别文字

cnocr 介绍 参考&#xff1a; cnocr: 极简的中文OCR Python包 https://cnocr.readthedocs.io/zh/latest/ cnocr 主要针对的是排版简单的印刷体文字图片&#xff0c;如截图图片&#xff0c;扫描件等。目前内置的文字检测和分行模块无法处理复杂的文字排版定位。如果要用于场景…

《从零开始编写一个直播服务器》音视频封装FLV

流媒体服务系列文章 文章目录 流媒体服务系列文章前言一、FLV 封装格式解析二、实例分析总结 前言 一、FLV 封装格式解析 flv header flv body flv header previous size0 tag1 previous size1 tag2 … prvious sizen tagn1 flv header previous size0 tag1 header ta…

华为OD机试真题 Python 实现【获得完美走位】【2022Q4 200分】

一、题目描述 在第一人称射击游戏中&#xff0c;玩家通过键盘的 A、S、D、W 四个按键控制游戏人物分别向左、向后、向右、向前进行移动&#xff0c;从而完成走位假设玩家每按动一次键盘&#xff0c;游戏任务会向某个方向移动一步&#xff0c;如果玩家在操作一定次数的键盘并且…

经典文献阅读之--Wheel-SLAM(低成本轮式机器人定位算法)

0. 简介 最近随着越来越多的团队开始注重将SLAM应用在机器人和无人驾驶上&#xff0c;最近SLAM的顶刊顶会也开始想着多模态和低成本这两个方向开始发力。而本文讲的这个《Wheel-SLAM: Simultaneous Localization and Terrain Mapping Using One Wheel-mounted IMU》就是讲了如…