免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 4125 | 回复: 17
打印 上一主题 下一主题

使用自旋锁的问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-08-27 21:38 |只看该作者 |倒序浏览
我在LINUX驱动程序的open列程中起了一个内核定时器2秒执行定时器函数,然后调用自旋锁锁住,按理说这样定时器的软中
断不应该有(也就不应该调用定时器函数),但是软中断还是有,有谁能解释一下吗???

论坛徽章:
59
2015年亚洲杯之约旦
日期:2015-01-27 21:27:392015年亚洲杯之日本
日期:2015-02-06 22:09:41拜羊年徽章
日期:2015-03-03 16:15:432015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:50:282015元宵节徽章
日期:2015-03-06 15:50:392015年亚洲杯之阿联酋
日期:2015-03-19 17:39:302015年亚洲杯之中国
日期:2015-03-23 18:52:23巳蛇
日期:2014-12-14 22:44:03双子座
日期:2014-12-10 21:39:16处女座
日期:2014-12-02 08:03:17天蝎座
日期:2014-07-21 19:08:47
2 [报告]
发表于 2007-08-27 23:17 |只看该作者
你锁了自已的代码,和定时器有什么关系。
要想锁住定时器,找Linus去

是这样的:

if(spinlock(var))
{
  .....
  //....do_timer();
......
}
else
{
return;
}
也就是说,发现锁了,自已空return就行了。

论坛徽章:
0
3 [报告]
发表于 2007-08-27 23:23 |只看该作者
贴代码看看.
.

论坛徽章:
0
4 [报告]
发表于 2007-08-29 21:09 |只看该作者

回复 #2 folklore 的帖子

但是调用spin_lock_irq应该屏蔽掉了硬中断和软中断,
应该定时器的软中断不会来才对啊!!

并且奇怪的是我在open列程中调用spin_lock_irq两次从来没有
释放锁,程序照常运行很好,因该把程序挂起才对啊?

论坛徽章:
59
2015年亚洲杯之约旦
日期:2015-01-27 21:27:392015年亚洲杯之日本
日期:2015-02-06 22:09:41拜羊年徽章
日期:2015-03-03 16:15:432015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:50:282015元宵节徽章
日期:2015-03-06 15:50:392015年亚洲杯之阿联酋
日期:2015-03-19 17:39:302015年亚洲杯之中国
日期:2015-03-23 18:52:23巳蛇
日期:2014-12-14 22:44:03双子座
日期:2014-12-10 21:39:16处女座
日期:2014-12-02 08:03:17天蝎座
日期:2014-07-21 19:08:47
5 [报告]
发表于 2007-08-30 00:18 |只看该作者
原帖由 zlinux123456 于 2007-8-29 21:09 发表
但是调用spin_lock_irq应该屏蔽掉了硬中断和软中断,
应该定时器的软中断不会来才对啊!!

并且奇怪的是我在open列程中调用spin_lock_irq两次从来没有
释放锁,程序照常运行很好,因该把程序挂起才对啊?


如果我没记混的话,定时器的中断不在屏蔽之列,
不然的话,使用了spin_lock,不就等于lock the kernel,也就是每一天spin lock都会锁了整个内核了吗?这样的话,代码在单CPU机器中可如何才能往下执行啊。

论坛徽章:
0
6 [报告]
发表于 2007-08-30 21:13 |只看该作者
并且奇怪的是我在open列程中调用spin_lock_irq两次从来没有
释放锁,程序照常运行很好,因该把程序挂起才对啊?
那么这个现象如何解释呢?

论坛徽章:
59
2015年亚洲杯之约旦
日期:2015-01-27 21:27:392015年亚洲杯之日本
日期:2015-02-06 22:09:41拜羊年徽章
日期:2015-03-03 16:15:432015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:50:282015元宵节徽章
日期:2015-03-06 15:50:392015年亚洲杯之阿联酋
日期:2015-03-19 17:39:302015年亚洲杯之中国
日期:2015-03-23 18:52:23巳蛇
日期:2014-12-14 22:44:03双子座
日期:2014-12-10 21:39:16处女座
日期:2014-12-02 08:03:17天蝎座
日期:2014-07-21 19:08:47
7 [报告]
发表于 2007-08-31 00:52 |只看该作者
原帖由 zlinux123456 于 2007-8-30 21:13 发表
并且奇怪的是我在open列程中调用spin_lock_irq两次从来没有
释放锁,程序照常运行很好,因该把程序挂起才对啊?
那么这个现象如何解释呢?

这下不懂了。只在代码中两次使用而不是二个线程,每个线程一次加起来两次的话(这时,可能你分配的spin是局部的),只好说:

贴上代码看看了。

如果代码不是这样的话:
if(spin_lock(&lockVar)==success)
{
     if(spin_lock(&lockvar)==success)
     {
         code touch here.
     }
}
else
return;
--------------------------------------------------------------------------------------------------------------------------------------------------
另,你使用的是什么版本?不会把spin实现为递归lock了吧

论坛徽章:
0
8 [报告]
发表于 2007-09-02 08:44 |只看该作者
代码很简单:如下:主要是看红色字体的部分:
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#include <asm/semaphore.h>

MODULE_LICENSE("GPL");

#define MAJOR_NUM 254

static ssize_t globalvar_read(struct file *, char *, size_t, loff_t*);
static ssize_t globalvar_write(struct file *, const char *, size_t, loff_t*);
static int globalvar_open(struct inode *inode, struct file *filp);
static int globalvar_release(struct inode *inode, struct file *filp);

struct file_operations globalvar_fops =
{
 open: globalvar_open,
};

static spinlock_t spin = SPIN_LOCK_UNLOCKED;

static int __init globalvar_init(void)
{
 int ret;
 ret = register_chrdev(MAJOR_NUM, "globalvar", &globalvar_fops);
 if (ret)
 {
  printk("globalvar register failure");
 }
 else
 {
  printk("globalvar register success");
  init_MUTEX(&sem);
 }
 return ret;
}

static void __exit globalvar_exit(void)
{
 int ret;
 ret = unregister_chrdev(MAJOR_NUM, "globalvar");
 if (ret)
 {
  printk("globalvar unregister failure");
 }
 else
 {
  printk("globalvar unregister success");
 }
}

static int globalvar_open(struct inode *inode, struct file *filp)
{
 //获得自选锁
 spin_lock_irq(&spin);

 spin_lock_irq(&spin);
 /*我觉得下面这句不应该打印出来才对啊,应该阻塞.*/
 printk("<0>111111111\n");

  return 0;
}

论坛徽章:
59
2015年亚洲杯之约旦
日期:2015-01-27 21:27:392015年亚洲杯之日本
日期:2015-02-06 22:09:41拜羊年徽章
日期:2015-03-03 16:15:432015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:50:282015元宵节徽章
日期:2015-03-06 15:50:392015年亚洲杯之阿联酋
日期:2015-03-19 17:39:302015年亚洲杯之中国
日期:2015-03-23 18:52:23巳蛇
日期:2014-12-14 22:44:03双子座
日期:2014-12-10 21:39:16处女座
日期:2014-12-02 08:03:17天蝎座
日期:2014-07-21 19:08:47
9 [报告]
发表于 2007-09-02 10:07 |只看该作者
原帖由 zlinux123456 于 2007-9-2 08:44 发表

spin_lock_irq(&spin);

spin_lock_irq(&spin);




现在说明为什么错:
1.spin=1。锁有效

spin_lock_irq(&spin);  //这句话,得到spinLock,并使得spin为0,并得到持有cpu,return 1,成功
相当于

  1. asm/
  2.   mov eax,0
  3.   lock xchg eax,spin  //交换eax和spin的值,这时spin为0,eax为1,返回1,成功
  4. /
复制代码

if(spin_lock_irq(&spin); //这句话失败,

相当于:

  1. mov eax,0
  2. lock xchg eax,spin ;同上,0和0换:(,返回eax,为0,失败
复制代码

你不管成功失败,都print,当然能print出来了。

你要用:


  1. if(spin_lock_irq(&spin)==1)

  2.  if(spin_lock_irq(&spin)==1)

  3.      print("message!!");

复制代码

论坛徽章:
59
2015年亚洲杯之约旦
日期:2015-01-27 21:27:392015年亚洲杯之日本
日期:2015-02-06 22:09:41拜羊年徽章
日期:2015-03-03 16:15:432015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:50:282015元宵节徽章
日期:2015-03-06 15:50:392015年亚洲杯之阿联酋
日期:2015-03-19 17:39:302015年亚洲杯之中国
日期:2015-03-23 18:52:23巳蛇
日期:2014-12-14 22:44:03双子座
日期:2014-12-10 21:39:16处女座
日期:2014-12-02 08:03:17天蝎座
日期:2014-07-21 19:08:47
10 [报告]
发表于 2007-09-02 10:10 |只看该作者
LZ的错误有两个:
1.得到spin后是不会阻塞的;
2.避免dead_lock是应用程序的duty.
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP