关于信号量的静态、动态申明问题。大侠路过请进!

超低空MC 2014-11-30 08:49:21
各位大侠,再看LDD3的过程中会看到自旋锁、信号量等等变量的申明会有两种方式:


1、静态方式:DECLARE_MUTEX();
2、动态方式:void init_MUTEX();

我的理解是:第一种是用宏,第二种是用函数。为什么说第二种可以在运行时使用,宏就不行吗? 一直很疑惑,希望各位大侠路过可以给我解答一下。


不甚感激!
...全文
388 9 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
超低空MC 2014-12-02
  • 打赏
  • 举报
回复
引用 7 楼 micropentium6 的回复:
oops, both of them passed through!
Your wonderful answer make me understand a lot , thank you !
  • 打赏
  • 举报
回复
oops, both of them passed through!
  • 打赏
  • 举报
回复
引用 2 楼 MC_hust 的回复:
Thanks for your answer. Through your analysis. That is to say, the 2 methods have no difference in usage?
fucking csdn thought I am a web crawler! Screw u, Fucking CSDN!!! fact always speaks louder, let's explore the source a bit. Here is a version (2.6.31) of the implementation of semaphore

#ifndef __LINUX_SEMAPHORE_H
#define __LINUX_SEMAPHORE_H

 #include <linux/list.h>
#include <linux/spinlock.h>

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

 #define __SEMAPHORE_INITIALIZER(name, n)                                \
 {                                                                       \
         .lock           = __SPIN_LOCK_UNLOCKED((name).lock),            \
        .count          = n,                                            \
         .wait_list      = LIST_HEAD_INIT((name).wait_list),             \
}

#define DECLARE_MUTEX(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);
}

 #define init_MUTEX(sem)         sema_init(sem, 1)
#define init_MUTEX_LOCKED(sem)  sema_init(sem, 0)
u can tell both DECLARE_MUTEX and init_MUTEX are defined as macros, which is different than LDD3's description, probably because LDD3 was published in 2005. And you can also tell both of them eventually requires __SEMAPHORE_INITIALIZER to initialize the semaphore variable. Even the function sema_init is declared as "inline", which basically tells the compiler: don't make me as a function if you don't have to... so, I would say there is no difference at all. You may think there is a subtle difference: by calling init_MUTEX, you could though, manipulate the variable before or afterward since it's defined in your source. However, DECLARE_MUTEX allows you to do the same thing, but it's vague, since no declaration can be found in your source for this variable...
  • 打赏
  • 举报
回复
引用 3 楼 MC_hust 的回复:
[quote=引用 1 楼 micropentium6 的回复:] don't know the detail, but generally speaking, macro is processed by pre-processor during the compilation. Basically, macro referred in the source code will be replaced by (expanded to) its definition before any real "compiling" starts. Therefore, if you do a symbol lookup on the obj file, you will not be able to find it. function, on the other hand, will have its instructions preserved in the executable in the .text section. In this context, you can say that function call can be invoked at the run time. For your case, by putting DECLARE_MUTEX (assuming it's a macro), a mutex will be defined/initialized in .data section; by adding init_MUTEX() in your logic, the mutex will be created only when this function is invoked. just my 2cents...
Thanks for your answer. Through your analysis. That is to say, the 2 methods have no difference in usage? [/quote] well, I guess fact always speaks louder, huh?

struct semaphore {
         spinlock_t              lock;
         unsigned int            count;
          struct list_head        wait_list;
 };
 
#define __SEMAPHORE_INITIALIZER(name, n)                                \
 {                                                                       \
         .lock           = __SPIN_LOCK_UNLOCKED((name).lock),            \
          .count          = n,                                            \
         .wait_list      = LIST_HEAD_INIT((name).wait_list),             \
 }
 
#define DECLARE_MUTEX(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);
 }

#define init_MUTEX(sem)         sema_init(sem, 1)
#define init_MUTEX_LOCKED(sem)  sema_init(sem, 0)
in this version (kernel 2.6.31.13 ) of the implementation of semaphore, both DECLARE_MUTEX and init_MUTEX are actually macros and both of them refers the same macro "__SEMAPHORE_INITIALIZER" to initialize the semaphore variable. sema_init. as the function expanded by init_MUTEX is declared as inline, which basically tells the compiler: don't make me as a function call if you could... there is actually not much difference at all. One subtle difference though, is, by init_MUTEX, you could manipulate the semaphore variable by your own, since you define it and send its address to init_MUTEX for initialization. With DECLARE_MUTEX, you could do the same, but it's vague, since the reader can't find the declaration of this variable...
LouisScola 2014-12-01
  • 打赏
  • 举报
回复
字面意思就可以理解,静态方式是指在编译时就为mutex信号量分配了内存空间,应该是在data/bss段,动态方式是在程序运行时才分配的,应该是放在heap段,这样可以节省内存空间,不需要这个mutex时也可以free掉
超低空MC 2014-12-01
  • 打赏
  • 举报
回复
引用 1 楼 micropentium6 的回复:
don't know the detail, but generally speaking, macro is processed by pre-processor during the compilation. Basically, macro referred in the source code will be replaced by (expanded to) its definition before any real "compiling" starts. Therefore, if you do a symbol lookup on the obj file, you will not be able to find it. function, on the other hand, will have its instructions preserved in the executable in the .text section. In this context, you can say that function call can be invoked at the run time. For your case, by putting DECLARE_MUTEX (assuming it's a macro), a mutex will be defined/initialized in .data section; by adding init_MUTEX() in your logic, the mutex will be created only when this function is invoked. just my 2cents...
Thanks for your answer. Through your analysis. That is to say, the 2 methods have no difference in usage?
超低空MC 2014-12-01
  • 打赏
  • 举报
回复
Thanks for your answer. Through your analysis. That is to say, the 2 methods have no difference in usage?
超低空MC 2014-12-01
  • 打赏
  • 举报
回复
引用 4 楼 LouisScola 的回复:
字面意思就可以理解,静态方式是指在编译时就为mutex信号量分配了内存空间,应该是在data/bss段,动态方式是在程序运行时才分配的,应该是放在heap段,这样可以节省内存空间,不需要这个mutex时也可以free掉
但是用DECLARE_MUTEX()宏来定义一个信号量也可以放在代码里面,然后用if判断是否需要申明,那就和用函数申明没差别了吧?
  • 打赏
  • 举报
回复
don't know the detail, but generally speaking, macro is processed by pre-processor during the compilation. Basically, macro referred in the source code will be replaced by (expanded to) its definition before any real "compiling" starts. Therefore, if you do a symbol lookup on the obj file, you will not be able to find it. function, on the other hand, will have its instructions preserved in the executable in the .text section. In this context, you can say that function call can be invoked at the run time. For your case, by putting DECLARE_MUTEX (assuming it's a macro), a mutex will be defined/initialized in .data section; by adding init_MUTEX() in your logic, the mutex will be created only when this function is invoked. just my 2cents...

4,465

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 内核源代码研究区
社区管理员
  • 内核源代码研究区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧