linux-011中休眠函数以及唤醒函数的分析(sleep_on,wake_up)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/u010383937/article/details/74380189

先看一下代码:

void sleep_on(struct task_struct **p)
{
	struct task_struct *tmp;

	if (!p)
		return;
	if (current == &(init_task.task))
		panic("task[0] trying to sleep");
	tmp = *p;
	*p = current;
	current->state = TASK_UNINTERRUPTIBLE;
	schedule();
	if (tmp)
		tmp->state=0;
}

void interruptible_sleep_on(struct task_struct **p)
{
	struct task_struct *tmp;

	if (!p)
		return;
	if (current == &(init_task.task))
		panic("task[0] trying to sleep");
	tmp=*p;
	*p=current;
repeat:	current->state = TASK_INTERRUPTIBLE;
	schedule();
	if (*p && *p != current) {
		(**p).state=0;
		goto repeat;
	}
	*p=NULL;
	if (tmp)
		tmp->state=0;
}

void wake_up(struct task_struct **p)
{
	if (p && *p) {
		(**p).state=0;
		*p=NULL;
	}
}
先看函数,函数实现很简单。原理有一些抽象,这里先说一下sleep_on函数的应用。
sleep_on函数中只要涉及了:*p,*tmp,current三个人物指针操作。
其中*p表示等待队列头指针,如文件系统i节点的i_wait指针,内存缓冲区操作中的buffer_wait指针;*tmp是临时指针,current代表当前任务指针。
sleep_on函数操作后就形成了一个队列:

tmp指向前一个任务,p指向当前等待队列头,而且每个任务的状态为可中断状态。

注意了,接下来就是我觉得抽象的地方了:
执行wake_up(buffer_wait)时,是怎么唤醒任务的呢?
看函数:
wake_up的操作:

	if (p && *p) {
		(**p).state=0;
	}
把任务状态设置为就绪,之后schedule()函数就会返回到sleep_on函数的最后部分,执行操作如下:
    if (tmp)
        tmp->state=0;
因为tmp为前一个任务的指针,而且,每次sleep任务时,都创建了tmp指针,所以只要tmp指针不为空,就会把tmp指针指向的任务状态置为就绪。这样就实现了任务的唤醒,从代码看来每次唤醒都是把一个队列中的所有任务唤醒。

interruptible_sleep_on函数类似:
repeat:	current->state = TASK_INTERRUPTIBLE;
	schedule();
	if (*p && *p != current) {
		(**p).state=0;
		goto repeat;
	}
	*p=tmp;
	if (tmp)
		tmp->state=0;



当任务唤醒时,*p指针中有等待任务并且不是当前任务,表示当当前任务放入队列后又有其他任务放入队列中,之后就把当前任务置为就绪,并重新调度。当是当前任务时,也把其他就绪任务也唤醒,同sleep_on函数。

以上就是自己看a代码整理出来了,有任何不对地方,还请留言指正。


展开阅读全文

【求助】6410休眠唤醒唤醒过程schedule函数出错的问题

06-30

最近在调试6410的休眠唤醒问题,在arch/arm/plat-samsung/pm.c最后一行加入arch_initcall(s3c_pm_init);之后可以进行休眠,唤醒的过程中发现凡是调用了schedule这个函数都会出错,比如msleep的log:rnBUG: scheduling while atomic: kworker/u:1/37/0x00000002rnModules linked in:rn[] (unwind_backtrace+0x0/0xf4) from [] (schedule+0x444/0x530)rn[] (schedule+0x444/0x530) from [] (schedule_timeout+0x168/0x2e4)rn[] (schedule_timeout+0x168/0x2e4) from [] (msleep+0x14/0x20)rn[] (msleep+0x14/0x20) from [] (mmc_power_up+0xd0/0x160)rn[] (mmc_power_up+0xd0/0x160) from [] (mmc_resume_host+0x12c/0x1a4)rnwakeup wake lock: gpio wakelockrn[] (mmc_resume_host+0x12c/0x1a4) from [] (sdhci_resume_host+0x84/0xc0)rn[] (sdhci_resume_host+0x84/0xc0) from [] (sdhci_s3c_resume+0x10/0x18)rn[] (sdhci_s3c_resume+0x10/0x18) from [] (platform_pm_resume+0x2c/0x4c)rn[] (platform_pm_resume+0x2c/0x4c) from [] (pm_op+0xa0/0xc0)rn[] (pm_op+0xa0/0xc0) from [] (device_resume+0x8c/0x1f0)rn[] (device_resume+0x8c/0x1f0) from [] (dpm_resume_end+0x100/0x3ac)rn[] (dpm_resume_end+0x100/0x3ac) from [] (suspend_devices_and_enter+0x10c/0x200)rn[] (suspend_devices_and_enter+0x10c/0x200) from [] (enter_state+0xe8/0x120)rn[] (enter_state+0xe8/0x120) from [] (suspend+0x60/0x140)rn[] (suspend+0x60/0x140) from [] (process_one_work+0x148/0x4d0)rn[] (process_one_work+0x148/0x4d0) from [] (worker_thread+0x15c/0x474)rn[] (worker_thread+0x15c/0x474) from [] (kthread+0x84/0x8c)rn[] (kthread+0x84/0x8c) from [] (kernel_thread_exit+0x0/0x8)rns3c6400_setup_sdhci_cfg_card: CTRL 2=c0004120, 3=80808080rnrnrn还有另一个比较典型的:rnBUG: scheduling while atomic: kworker/u:1/37/0x00000002rnModules linked in:rn[] (unwind_backtrace+0x0/0xf4) from [] (schedule+0x444/0x530)rn[] (schedule+0x444/0x530) from [] (schedule_timeout+0x1a0/0x2e4)rn[] (schedule_timeout+0x1a0/0x2e4) from [] (wait_for_common+0xd8/0x1a4)rn[] (wait_for_common+0xd8/0x1a4) from [] (mmc_wait_for_req+0x17c/0x244)rn[] (mmc_wait_for_req+0x17c/0x244) from [] (mmc_wait_for_cmd+0x58/0x78)rn[] (mmc_wait_for_cmd+0x58/0x78) from [] (mmc_app_cmd+0x3c/0xb4)rn[] (mmc_app_cmd+0x3c/0xb4) from [] (mmc_wait_for_app_cmd+0x64/0xd0)rn[] (mmc_wait_for_app_cmd+0x64/0xd0) from [] (mmc_send_app_op_cond+0x84/0xe4)rn[] (mmc_send_app_op_cond+0x84/0xe4) from [] (mmc_sd_get_cid+0x38/0x6c)rn[] (mmc_sd_get_cid+0x38/0x6c) from [] (mmc_sd_init_card+0x34/0x200)rn[] (mmc_sd_init_card+0x34/0x200) from [] (mmc_sd_resume+0x30/0x64)rn[] (mmc_sd_resume+0x30/0x64) from [] (mmc_resume_host+0x9c/0x1a4)rn[] (mmc_resume_host+0x9c/0x1a4) from [] (sdhci_resume_host+0x84/0xc0)rn[] (sdhci_resume_host+0x84/0xc0) from [] (sdhci_s3c_resume+0x10/0x18)rn。。。。。rnrnrn请问各位有何解决问题的思路,多谢啦~~~ 论坛

LDD3的 关于wake_up()函数的一个问题

08-24

下面这段代码是在ldd3 书上的一段代码 不是太明白代码中两个关于睡眠和唤醒的函数;rn有几个问题希望大家帮解答下,先行谢过!rnrn1. 看了下wait_even()的代码 感觉所谓的睡眠,就是判断条件不满足就一直无限for循环查询吧吧?rnrn2. wait_event_interruptible(dev->inq, (dev->rp != dev->wp)) 函数是让process 处于休眠状态;在while循环中感觉它可以自动唤 醒在(dev->rp != dev->wp) 成立的时候,如果是这样的话那么在wait_event_interruptible 休眠也就是无限for循环查询(dev->rp != dev->wp状态时候 是同时会有另外一个线程并行进行了写操作才会导致(dev->rp != dev->wp)成立然后 wait_event_interruptible()结束了休眠吗?rnrn3. wake_event_interruptible(); 必须和wake_event_interruptible();成对使用吗? 为什么下面代码中这两函数的wait_queue_head_t 变量不一样一个是inq 一个是outq呢?rnrnThe device driver uses a device structure that contains two wait queues and a buffer.rnThe size of the buffer is configurable in the usual ways (at compile time, load time, orrnruntime). rnrnstruct scull_pipe rn wait_queue_head_t inq, outq; /* read and write queues */rn char *buffer, *end; /* begin of buf, end of buf */rn int buffersize; /* used in pointer arithmetic */rn char *rp, *wp; /* where to read, where to write */rn int nreaders, nwriters; /* number of openings for r/w */rn struct fasync_struct *async_queue; /* asynchronous readers */rn struct semaphore sem; /* mutual exclusion semaphore */rn struct cdev cdev; /* Char device structure */rn;rnrnThe read implementation manages both blocking and nonblocking input and looksrnlike this:rnrn/*rn* Data management: read and writern */rnrnstatic ssize_t scull_p_read (struct file *filp, char __user *buf, size_t count,rn loff_t *f_pos)rnrn struct scull_pipe *dev = filp->private_data;rnrn if (down_interruptible(&dev->sem))rn return -ERESTARTSYS;rnrn while (dev->rp == dev->wp) /* nothing to read */rn up(&dev->sem); /* release the lock */rn if (filp->f_flags & O_NONBLOCK)rn return -EAGAIN;rn PDEBUG("\"%s\" reading: going to sleep\n", current->comm);rn if ([color=#FF0000]wait_event_interruptible(dev->inq, (dev->rp != dev->wp)))[/color]rn return -ERESTARTSYS; /* signal: tell the fs layer to handle it */rn /* otherwise loop, but first reacquire the lock */rn if (down_interruptible(&dev->sem))rn return -ERESTARTSYS;rn rn /* ok, data is there, return something */rn if (dev->wp > dev->rp)rn count = min(count, (size_t)(dev->wp - dev->rp));rn else /* the write pointer has wrapped, return data up to dev->end */rn count = min(count, (size_t)(dev->end - dev->rp));rn if (copy_to_user(buf, dev->rp, count)) rn up (&dev->sem);rn return -EFAULT;rn rn dev->rp += count;rn if (dev->rp == dev->end)rn dev->rp = dev->buffer; /* wrapped */rn up (&dev->sem);rnrn /* finally, awake any writers and return */rn [color=#FF0000]wake_up_interruptible(&dev->outq);[/color] ///////////////////////这里不是很明白rn PDEBUG("\"%s\" did read %li bytes\n",current->comm, (long)count);rn return count;rn 论坛

WINCE6.0+S3C2416 休眠唤醒BUG

04-17

平台:2416 系统:WINCE6.0rnBUG描述: 设备进入系统之后rn1如果拔掉与PC端连接的USB下在线,那么WINCE6设备则能正常的休眠唤醒。但是偶尔会自动休眠.rn2如果不拔掉,那么系统能休眠,但是上电第一次休眠唤醒正常之后,自动进入休眠一次,然后唤醒正常,之后也就是第三次休眠正常,但是唤醒之后,死机。此时PC上会提示 无法识别的USB设备...rnBUG 出现时的DEBUG信息:rn +++++ZSS OEMPowerOff_BSPPowerOnrn[FTL: IN] ++FTL_ReadReclaim()rn[FTL:OUT] --FTL_ReadReclaim()rn[OND:MSG] FTL_ReadReclaim [OK]rnWIFI_PowerUprnWCDMA_PowerUprnSCAN_PowerUprnGPS_PowerUprnBACKLED_PowerUprnVIBRATOR_PowerUprnLIGHT_PowerUprn>>++Liu wenlong-GPI_PowerUprnPCF:ZSS 20140416 HW_PowerUp rn[FTL: IN] ++FTL_ReadReclaim()rn[FTL:OUT] --FTL_ReadReclaim()rn[OND:MSG] FTL_ReadReclaim [OK]rn[HSMMC0] Power Up the HSMMC Host Controllerrn[HSMMC0] Power Up the HSMMC Host ControllerrnERROR: Power Handler function yield to low priority thread.rn[PLD_DEV] Init3G######################rn[HSMMC0] Card is Inserted!rn[HSMMC1] Card is Removed!rn[PLD_DEV] Init3G over#################rn[HSMMC0] Turn OFF the F/B delay control.rn经过分析测试后看出:正常唤醒时的输出信息如下rn +++++ZSS OEMPowerOff_BSPPowerOnrn[FTL: IN] ++FTL_ReadReclaim()rn[FTL:OUT] --FTL_ReadReclaim()rn[OND:MSG] FTL_ReadReclaim [OK]rnWIFI_PowerUprnWCDMA_PowerUprnSCAN_PowerUprnGPS_PowerUprnBACKLED_PowerUprnVIBRATOR_PowerUprnLIGHT_PowerUprn>>++Liu wenlong-GPI_PowerUprnPCF:ZSS 20140416 HW_PowerUp rn[FTL: IN] ++FTL_ReadReclaim()rn[FTL:OUT] --FTL_ReadReclaim()rn[OND:MSG] FTL_ReadReclaim [OK]rn[HSMMC0] Power Up the HSMMC Host Controllerrn[HSMMC0] Power Up the HSMMC Host ControllerrnERROR: Power Handler function yield to low priority thread.rn[PLD_DEV] Init3G######################rn[HSMMC0] Card is Inserted!rn[HSMMC1] Card is Removed!rn[PLD_DEV] Init3G over#################rn[color=#FF0000]+++InitCodec[/color]rn[HSMMC0] Turn OFF the F/B delay control.rn[color=#FF0000]---InitCodec[/color]rnZSS 2014-4-16 WAVEDEV: IOCTL_POWER_SET: D0 => D0 rn::Create key_button event end !!rnRASCS_Disconnected: Ecode=619rnImeSelectrnIME:Thread detachrnPosting WM_NETCONNECT(FALSE) message, ErrorCode = 619(0x26B)rnEntry outrn.......rn红色部分就是BUG出现时与正常唤醒时的区别。rn求各位大神指点 论坛

没有更多推荐了,返回首页