`
sunzixun
  • 浏览: 75967 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
社区版块
存档分类
最新评论

<Learn From Kernel> Mutex Subsystem

阅读更多

 

在我想办法弄懂supermirco 服务用的Super IO w83795的驱动的时候 ,我不幸又陷入了mutex_lock :

 

具体的设计文档见 document/mutex-design. 我这里只是摘录演义~

 

故事开始:

 

"为什么在这个地球上 ,我们需要一个新的mutex 子系统 ,

  原来的semaphore怎了么他不行了吗 "

 

   让我来帮大家怀恋一下他吧

struct semaphore {
	spinlock_t		lock;
	unsigned int		count;
	struct list_head	wait_list;
};

void down(struct semaphore *sem);//ldd上说 你是惹恼的用户的好方法
int down_interruptible(struct semaphore *sem);
int down_trylock(struct semaphore *sem);

void up(struct semaphore *sem); 

 其实,错不在semaphore . 而是我的心变了.

 

现在有一个简单的 mutex语义出现了,他完全满足我的代码需要, 而且semaphore 有下面的诱惑.

 

第一:

'struct mutex'  在大多数的平台上他更小 只有16字节 而你 'struct semaphore' 有20个字节

要知道更小的结构意味着 更少的 RAM空间 ,能更好的被CPU cache利用

 

第二:

紧凑的代码, 在x86上, .text的大小比较:

 

写道
text data bss dec hex filename
3280380 868188 396860 4545428 455b94 vmlinux-semaphore
3255329 865296 396732 4517357 44eded vmlinux-mutex

 

 

 

你看 25051字节的代码被节省了  小代码意味着更优越的指令高速缓冲存储器占用 ,这是linux 内核当前优化的主要目标

 

第三:

mutex 子系统 对于竞争带来的负载 表现的更轻盈更可扩展(想想长矛).  在一个8-way的 x86系统上,允许一个

基于mutex的内核测试 creat+unlink+close  在/tmp文件系统下 16个并行的任务:

 

写道
Semaphores: Mutexes:

$ ./test-mutex V 16 10 $ ./test-mutex V 16 10
8 CPUs, running 16 tasks. 8 CPUs, running 16 tasks.
checking VFS performance. checking VFS performance.
avg loops/sec: 34713 avg loops/sec: 84153
CPU utilization: 63% CPU utilization: 22%

 

 


结果显而易见 ~

 

第四:

 

没有快路径的开销(看下面) 只要2条汇编指令这和 semaphora是一样的

 

    c0377ccb <mutex_lock>:
    c0377ccb:       f0 ff 08                lock decl (%eax)
    c0377cce:       78 0e                   js     c0377cde <.text.lock.mutex>
    c0377cd0:       c3                      ret
 

 

 

 

不容忽视的好处:

 

 struct mutex 被很好的赋义 

 

* 一次只有一个任务可以拥有mutex

*   只有拥有者可以解锁

*  多次解锁是不允许的

*  递归加锁也是不可以的

*  一个mutex对象必须通过api初始化不能memset啥的

*  拥有mutex的任务不能exit

* 被锁控制的内存区域不能free

* mutex不能在软件中断或者硬件中断中

* 可以在tasklets软中断或者timers的context中

 

(ps 以上除了第3条当 mutexattr_init 为"PTHREAD_MUTEX_RECURSIVE_NP" 前几条大家其实和 pthread_mutex是一样一样的~)

 

 当编译内核的 CONFIG_DEBUG_MUTEXES  打开后会变得更强大

   * - uses symbolic names of mutexes, whenever they are printed in debug output
   * - point-of-acquire tracking, symbolic lookup of function names
   * - list of all locks held in the system, printout of them
   * - owner tracking
   * - detects self-recursing locks and prints out all relevant info
   * - detects multi-task circular deadlocks and prints out all affected
   *   locks and tasks (and only those tasks)

--------------------------------------------------------------------------------

当然他也有一些缺点

 

你不能用在中断上下文 也不能在不同的context中解锁 但是semaphore可以

 

 

 

下面来简单看一些函数

 

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);
}

 

这里有一个  might_sleep();
如果编译内核打开了 CONFIG_PREEMPT_VOLUNTARY 宏,那么在这里就如果需要就会面临 schedule();

 

__mutex_fastpath_lock(&lock->count, __mutex_lock_slowpath);

 

其实是把原子计数 conut 从1变成0 ,如果初始值不是1 ,那么这里就去调用 __mutex_lock_slowpath 函数

 

这样就进入了慢加锁的 路径(原来是不是很快呢,有的体系结构上是用汇编写的)

 

static __used noinline void __sched//__used gcc版本适应 __sched 
__mutex_lock_slowpath(atomic_t *lock_count)
{
	struct mutex *lock = container_of(lock_count, struct mutex, count);

	__mutex_lock_common(lock, TASK_UNINTERRUPTIBLE, 0, _RET_IP_);
}

 

 

首先container_of  获得对应原子数的 mutex,然后去调用不可中断的 __mutex_lock_common()

 

待续

 

分享到:
评论

相关推荐

    <<windows程序设计>>1-8章代码

    5. **线程编程**:多线程是现代程序设计的重要部分,Chap06的代码可能涵盖了线程的创建、同步和通信,如CreateThread、WaitForSingleObject和Mutex。 6. **GDI图形设备接口**:Chap07可能涉及Windows的GDI,讲解...

    宋宝华随书源代码

    《宋宝华&lt;Linux设备驱动&gt;随书源代码》是一份宝贵的资料,它为学习Linux设备驱动开发提供了实践平台。Linux作为一个开源操作系统,其设备驱动程序是系统与硬件交互的关键,理解和编写设备驱动是深入掌握Linux系统的...

    线程经典题目<生产-消费>

    #include &lt;windows.h&gt; #include &lt;iostream&gt; #define BUFFER_SIZE 10 HANDLE mutex = CreateMutex(NULL, FALSE, NULL); // 创建互斥量 HANDLE semaphore = CreateSemaphore(NULL, BUFFER_SIZE, BUFFER_SIZE, NULL);...

    Linux程序设计

    5. **头文件和库**:了解如何包含Linux系统头文件,如`&lt;unistd.h&gt;`、`&lt;stdlib.h&gt;`、`&lt;sys/types.h&gt;`等,使用系统调用接口。掌握动态链接和静态链接库的区别,如`-l`选项链接库。 6. **进程与线程**:理解进程...

    Windows多线程编程缺少pthread.h文件问题

    #include &lt;pthread.h&gt; pthread_t newThread; pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setscope(&attr, PTHREAD_SCOPE_PROCESS); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_...

    linux C和C++开发经典头文件整理.rar

    5. **C++11及以上版本的现代特性头文件**:如&lt;tuple&gt;(元组)、&lt;unordered_map&gt;(无序映射)、&lt;mutex&gt;(互斥锁)等,引入了更多高级特性。 此外,资源中还提到了其他技术领域如Python、GNU、ASM、Goom、Netatalk和...

    C++ 头文件大全

    - `&lt;mutex&gt;` 和 `&lt;condition_variable&gt;`:互斥锁和条件变量。 - `&lt;shared_ptr&gt;`,`&lt;unique_ptr&gt;` 和 `&lt;weak_ptr&gt;`:智能指针,自动管理内存。 - `&lt;tuple&gt;`:元组类型,存储多个不同类型的数据。 - `&lt;forward_...

    c语言常用头文件,头文件和包括的主要函数分类

    - **&lt;assert.h&gt;** - **功能**:提供了断言宏`assert()`,用于程序调试过程中检查假设条件是否成立。 - **示例**: ```c #include &lt;assert.h&gt; int main() { assert(2 + 2 == 4); return 0; } ``` - **...

    Linux下多线程计算圆周率 C语言

    #include &lt;pthread.h&gt; #include &lt;stdio.h&gt; #include &lt;stdlib.h&gt; #include &lt;sys/time.h&gt; #define N 50000//设定计算次数 #define NUM 2//设定线程数,经过反复实验,在装有1个双核CPU的机器上,两个线程最快 double ...

    UNIX头文件大全(.h文件压缩包)

    8. `&lt;pthread.h&gt;`:多线程编程,提供了线程创建、同步、互斥锁等函数,如`pthread_create`、`pthread_join`、`pthread_mutex_lock`等。 9. `&lt;dirent.h&gt;`:目录操作,如`opendir`、`readdir`用于读取目录内容。 10....

    linux c 函数库

    9. 多线程:`&lt;pthread.h&gt;`提供了多线程编程接口,包括创建线程`pthread_create`,同步机制如互斥锁`pthread_mutex_lock`和条件变量`pthread_cond_wait`。 10. 队列和堆栈:`&lt;queue.h&gt;`和`&lt;stack.h&gt;`提供了队列和...

    编写linux驱动时的头文件

    `&lt;linux/kernel.h&gt;`头文件提供了许多基本的内核功能,如日志记录(`printk`)、内存管理(`kmalloc`, `kfree`)、互斥锁(`mutex_lock`, `mutex_unlock`)等。这些功能对于驱动程序来说是非常基础且重要的。 ### 3. `...

    Visual C++.NET编程技术体验

    &lt;br&gt;8.4.6 示例——图像浏览器&lt;br&gt;第9章 多线程编程&lt;br&gt;9.6.1 示例——使用全局变量通信&lt;br&gt;9.6.2 示例——使用Windows消息通信&lt;br&gt;9.7.5 示例——使用CriticalSection对象&lt;br&gt;9.7.7 示例——使用Mutex对象&lt;br&gt;9.7.9...

    Visual C++.NET编程技术体验__实例源码

    &lt;br&gt;8.4.6 示例——图像浏览器&lt;br&gt;第9章 多线程编程&lt;br&gt;9.6.1 示例——使用全局变量通信&lt;br&gt;9.6.2 示例——使用Windows消息通信&lt;br&gt;9.7.5 示例——使用CriticalSection对象&lt;br&gt;9.7.7 示例——使用Mutex对象&lt;br&gt;9.7.9...

    C++头文件一览(Word格式)

    - `&lt;mutex&gt;`和`&lt;atomic&gt;`:线程同步和原子操作。 - `&lt;chrono&gt;`:时间点和持续时间的处理,替代了`&lt;ctime&gt;`。 6. **头文件的包含规则** - 尽量避免循环包含,即一个头文件不应直接或间接包含自身。 - 使用`#...

    C++ 简单的任务队列实例

    std::unique_lock&lt;std::mutex&gt; lock(mutex_); tasks_.push(task); condition_.notify_one(); } std::function&lt;void()&gt; pop() { std::unique_lock&lt;std::mutex&gt; lock(mutex_); while (tasks_.empty()) { ...

    GNU C Library Reference

    9. **网络编程**:`&lt;sys/socket.h&gt;`和`&lt;netinet/in.h&gt;`等头文件提供了网络编程接口,如`socket`创建套接字,`bind`绑定地址,`listen`监听连接,`accept`接收连接,`send`和`recv`发送接收数据。 10. **国际化与...

    Linux C常用库函数手册

    9. **&lt;pthread.h&gt;**:多线程库,允许程序员创建和管理线程,如pthread_create、pthread_join和pthread_mutex_*系列函数用于线程创建、同步和互斥锁。 以上只是Linux C库函数的一小部分,实际上还有更多针对特定任务...

    微软C++ 标准库参考20210513.pdf

    18. &lt;mutex&gt;、&lt;lock&gt; 等:互斥库,提供了线程同步机制的类和函数,如互斥锁、锁的使用等。 19. &lt;memory&gt;:内存管理库,提供了智能指针和内存分配函数,用于自动化内存管理。 20. &lt;functional&gt;:函数对象库,提供了...

    C语言多线程编程实例.pdf

    `&lt;pthread.h&gt;`是用于处理POSIX线程(pthread)的头文件,`&lt;stdio.h&gt;`和`&lt;string.h&gt;`是标准输入输出和字符串处理函数,而`&lt;sys/time.h&gt;`则包含时间相关的函数。 定义常量`MAX`为10,表示每个线程将执行的循环次数。...

Global site tag (gtag.js) - Google Analytics