linux -信号量semphore分析

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--;elseresult = __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--;elseresult = __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--;elseresult = __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.hqwc.cn/news/700.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

壳牌小程序笔记

壳牌加油站 uni-app-基础-day01 概览 为什么要学uni-app&#xff1f; 现在很多中小型公司&#xff0c;都有自己的小程序项目&#xff0c;然后开发小程序就会用到uni-app。 uni-app没有诞生之前&#xff0c;怎么写小程序 使用原生微信小程序这个框架去开发&#xff1f; 只…

leetcode887. 鸡蛋掉落(动态规划-java)

鸡蛋掉落 leetcode887. 鸡蛋掉落题目描述暴力递归 二分查找代码演示 动态规划代码演示 动态规划专题 leetcode887. 鸡蛋掉落 来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 链接&#xff1a;https://leetcode.cn/problems/super-egg-drop 题目描述 给你 k 枚相同的鸡…

助力工业物联网,工业大数据之其他维度:组织机构【十五】

文章目录 01&#xff1a;其他维度&#xff1a;组织机构02&#xff1a;其他维度&#xff1a;仓库、物流附录一&#xff1a;常见问题1.错误&#xff1a;没有开启Cross Join2.错误&#xff1a;Unable to move source 01&#xff1a;其他维度&#xff1a;组织机构 目标&#xff1a;…

Linux 设备驱动程序(四)

系列文章目录 Linux 内核设计与实现 深入理解 Linux 内核 Linux 设备驱动程序&#xff08;一&#xff09; Linux 设备驱动程序&#xff08;二&#xff09; Linux 设备驱动程序&#xff08;三&#xff09; Linux 设备驱动程序&#xff08;四&#xff09; Linux设备驱动开发详解 …

IntelliJ IDEA如何自动生成serialVersionUID

IntelliJ IDEA如何自动生成serialVersionUID&#xff1f; 实体对象在流中传输时&#xff0c;需要将其序列化。 对象的类型实现Serializable接口public class ClassName implements java.io.Serializable { } 生成版本号serialVersionUID单击类名&#xff0c;按Alt Enter,在出…

【单目标优化算法】杂草优化算法(Matlab代码实现)

&#x1f4a5; &#x1f4a5; &#x1f49e; &#x1f49e; 欢迎来到本博客 ❤️ ❤️ &#x1f4a5; &#x1f4a5; &#x1f3c6; 博主优势&#xff1a; &#x1f31e; &#x1f31e; &#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 …

DragGAN开源:生成图像流形上的基于点的交互式操作

文旨在解决生成对抗网络&#xff08;GAN&#xff09;中控制生成图像的问题。通过“拖动”图像中的任意点&#xff0c;实现用户交互式精确控制生成图像的姿态、形状、表情和布局。 这个名叫DragGAN的模型&#xff0c;本质上是为各种GAN开发的一种交互式图像操作方法。论文以Sty…

软件外包开发在线监控工具

软件系统上线后需要实时监控&#xff0c;这样在系统出现问题后可以及时发现问题并解决问题。今天和大家分享常见的软件系统监控工具&#xff0c;这些工具功能强大且成熟稳定&#xff0c;熟练的应用可以帮助运维人员解决很多项目中的实际问题。北京木奇移动技术有限公司&#xf…

java面试高频面试题

文章目录 面向对象 什么是面向对象&#xff1f;封装继承多态 和equals比较hashCode与equals重载和重写的区别Final类加载器spring是什么AOP的理解谈谈你对IOC的理解零拷贝RocketMQ 架构设计RocketMq 事务消息原理RockeMq顺序消息消费原理简述RockerMQ持久化机制RocketMQ如何保…

Redis的简单使用 (实现Session持久化)

&#x1f389;&#x1f389;&#x1f389;点进来你就是我的人了博主主页&#xff1a;&#x1f648;&#x1f648;&#x1f648;戳一戳,欢迎大佬指点! 欢迎志同道合的朋友一起加油喔&#x1f93a;&#x1f93a;&#x1f93a; 目录 一、Redis数据类型的使用 1. 字符串&#xff…

“前端已死”

一、一些迹象 逛社区&#xff0c;偶然看到了这张图片&#xff1a; 嗯……我眉头一皱&#xff0c;久久不语&#xff0c;心想&#xff0c;有这么夸张吗&#xff0c;假的吧&#xff1f; 突然想到&#xff0c;最近我在社区发了个前端招聘的信息&#xff0c;结果简历漫天纷飞&…

并发-JMM-CPU缓存一致性协议MESI

回顾 指令重排 第一V读&#xff0c;都不能指令重排&#xff1b;第二个V写&#xff0c;都不能指令重排 普通读写&#xff0c;写读都会发生指令重排&#xff0c;V写普通读写会发生指令重排&#xff0c;普通读写V读会发生指令重排 CPU缓存一致性协议MESI java—》cpu的执行过程…