Skip to contentSkip to conversation

Add msleep_interruptible() function to kernel/timer.c

PATCH maximilian attems 5 participants 6 messages Aug 15, 2004 – Aug 16, 2004

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

while doing kernel-janitor msleep conversion of drivers own (incorrect), functions, some places would need msleep_interruptible().

this function is equivalent to:

        current->state = TASK_INTERRUPTIBLE;
	schedule_timeout(timeout);

idea from Ingo Molnar:
well, aboves is not 100% equivalent because msleep() is uninterruptible so stoppage of the md thread (upon shutdown) will occur with only a 250 msec delay. Someone should add a msleep_interruptible() function to kernel/timer.c.

---

 linux-2.6.8-max/kernel/timer.c |   15 +++++++++++++++
 1 files changed, 15 insertions(+)
kernel/timer.c renamed from kernel/timer.c~add-msleep_interruptible +15 -0
diff -puN kernel/timer.c~add-msleep_interruptible kernel/timer.c
@@ -1503,3 +1503,18 @@ void msleep(unsigned int msecs)
 
 EXPORT_SYMBOL(msleep);
 
+/**
+ * msleep_interruptible - sleep waiting for waitqueue interruptions
+ * @msecs: Time in milliseconds to sleep for
+ */
+void msleep_interruptible(unsigned int msecs)
+{
+	unsigned long timeout = msecs_to_jiffies(msecs);
+
+	while (timeout) {
+		set_current_state(TASK_INTERRUPTIBLE);
+		timeout = schedule_timeout(timeout);
+	}
+}
+
+EXPORT_SYMBOL(msleep_interruptible);

_

_______________________________________________
Kernel-janitors mailing list
[email protected]
http://lists.osdl.org/mailman/listinfo/kernel-janitors

#1 lore raw

kernel/timer.c void msleep(unsigned int msecs) · line 1514

Quoted 8 lines · maximilian attems

+ * msleep_interruptible - sleep waiting for waitqueue interruptions
+ * @msecs: Time in milliseconds to sleep for
+ */

kernel/timer.c renamed from kernel/timer.c~add-msleep_interruptible +5 -0
+void msleep_interruptible(unsigned int msecs)
+{
+	unsigned long timeout = msecs_to_jiffies(msecs);
+
+	while (timeout) {

You want to have while(timeout && !signal_pending(current))

A signal will wake the timeout which will then loop. It might also be good to add

kernel/timer.c void msleep(unsigned int msecs) · line 1517

Quoted 3 lines
kernel/timer.c renamed from kernel/timer.c~add-msleep_interruptible +3 -0
+		set_current_state(TASK_INTERRUPTIBLE);
+		timeout = schedule_timeout(timeout);
+	}

return timeout;

so that the caller knows more about how long the timer ran for before the interrupt and if it was interrupted.

_______________________________________________
Kernel-janitors mailing list
[email protected]
http://lists.osdl.org/mailman/listinfo/kernel-janitors

#2 lore raw
Quoted 15 lines · Alan Cox

Review

Quoted 8 lines · maximilian attems

+ * msleep_interruptible - sleep waiting for waitqueue interruptions
+ * @msecs: Time in milliseconds to sleep for
+ */

(quoted diff) +5 -0
+void msleep_interruptible(unsigned int msecs)
+{
+	unsigned long timeout = msecs_to_jiffies(msecs);
+
+	while (timeout) {

You want to have while(timeout && !signal_pending(current))

A signal will wake the timeout which will then loop. It might also be good to add

Quoted 8 lines

Review

Quoted 3 lines
(quoted diff) +3 -0
+		set_current_state(TASK_INTERRUPTIBLE);
+		timeout = schedule_timeout(timeout);
+	}

return timeout;

so that the caller knows more about how long the timer ran for before the interrupt and if it was interrupted.

belows patches returns timeout in msecs
as the function is also called with that unit,
added definition in include/linux/delay.h

this function is equivalent to:

	current->state = TASK_INTERRUPTIBLE;
	schedule_timeout(timeout);

idea from Ingo Molnar:
well, aboves is not 100% equivalent because msleep() is uninterruptible so stoppage of the md thread (upon shutdown) will occur with only a 250 msec delay. Someone should add a msleep_interruptible() function to kernel/timer.c.

---

 linux-2.6.8-max/kernel/timer.c |   17 +++++++++++++++++
 1 files changed, 17 insertions(+)

this function is equivalent to:

	current->state = TASK_INTERRUPTIBLE;
	schedule_timeout(timeout);

idea from Ingo Molnar:
well, aboves is not 100% equivalent because msleep() is uninterruptible so stoppage of the md thread (upon shutdown) will occur with only a 250 msec delay. Someone should add a msleep_interruptible() function to kernel/timer.c.

---

 linux-2.6.8-max/include/linux/delay.h |    1 +
 linux-2.6.8-max/kernel/timer.c        |   16 ++++++++++++++++
 2 files changed, 17 insertions(+)
kernel/timer.c renamed from kernel/timer.c~add-msleep_interruptible +16 -0
diff -puN kernel/timer.c~add-msleep_interruptible kernel/timer.c
@@ -1503,3 +1503,19 @@ void msleep(unsigned int msecs)
 
 EXPORT_SYMBOL(msleep);
 
+/**
+ * msleep_interruptible - sleep waiting for waitqueue interruptions
+ * @msecs: Time in milliseconds to sleep for
+ */
+unsigned int msleep_interruptible(unsigned int msecs)
+{
+       unsigned long timeout = msecs_to_jiffies(msecs);
+
+       while (timeout && !signal_pending(current)) {
+               set_current_state(TASK_INTERRUPTIBLE);
+               timeout = schedule_timeout(timeout);
+       }
+       return jiffies_to_msecs(timeout);
+}
+
+EXPORT_SYMBOL(msleep_interruptible);
include/linux/delay.h renamed from include/linux/delay.h~add-msleep_interruptible +1 -0
diff -puN include/linux/delay.h~add-msleep_interruptible include/linux/delay.h
@@ -39,5 +39,6 @@ extern unsigned long loops_per_jiffy;
 #endif
 
 void msleep(unsigned int msecs);
+unsigned int msleep_interruptible(unsigned int msecs);
 
 #endif /* defined(_LINUX_DELAY_H) */

_

_______________________________________________
Kernel-janitors mailing list
[email protected]
http://lists.osdl.org/mailman/listinfo/kernel-janitors

#3 lore raw
Quoted 4 lines · maximilian attems
kernel/timer.c renamed from kernel/timer.c~add-msleep_interruptible +4 -0
+/**
+ * msleep_interruptible - sleep waiting for waitqueue interruptions
+ * @msecs: Time in milliseconds to sleep for
+ */

kernel/timer.c void msleep(unsigned int msecs) · line 1519

Quoted 10 lines
kernel/timer.c renamed from kernel/timer.c~add-msleep_interruptible +10 -0
+unsigned int msleep_interruptible(unsigned int msecs)
+{
+       unsigned long timeout = msecs_to_jiffies(msecs);
+
+       while (timeout && !signal_pending(current)) {
+               set_current_state(TASK_INTERRUPTIBLE);
+               timeout = schedule_timeout(timeout);
+       }
+       return jiffies_to_msecs(timeout);
+}

looks good to me.

Ingo

#4 lore raw
In reply to maximilian attems
Quoted 23 lines · maximilian attems
Quoted 21 lines · Alan Cox

kernel/timer.c void msleep(unsigned int msecs)

Quoted 8 lines · maximilian attems

+ * msleep_interruptible - sleep waiting for waitqueue interruptions
+ * @msecs: Time in milliseconds to sleep for
+ */

kernel/timer.c renamed from kernel/timer.c~add-msleep_interruptible +5 -0
+void msleep_interruptible(unsigned int msecs)
+{
+	unsigned long timeout = msecs_to_jiffies(msecs);
+
+	while (timeout) {

You want to have while(timeout && !signal_pending(current))

A signal will wake the timeout which will then loop. It might also be good to add

kernel/timer.c void msleep(unsigned int msecs) · line 1517

Quoted 3 lines
kernel/timer.c renamed from kernel/timer.c~add-msleep_interruptible +3 -0
+		set_current_state(TASK_INTERRUPTIBLE);
+		timeout = schedule_timeout(timeout);
+	}

return timeout;

Quoted 6 lines
Quoted 2 lines

so that the caller knows more about how long the timer ran for before the interrupt and if it was interrupted.

belows patches returns timeout in msecs
as the function is also called with that unit,
added definition in include/linux/delay.h

<snip>

An entry could be added to the TODO to do what I had done but with long delays in TASK_INTERRUPTIBLE (which there probably should not be many of). It would also probably be useful to verify that any drivers sleeping for times measurable in msecs while INTERRUPTIBLE actually intend to do so (as I tried to do in some cases).

-Nish

_______________________________________________
Kernel-janitors mailing list
[email protected]
http://lists.osdl.org/mailman/listinfo/kernel-janitors

#5 lore raw
In reply to maximilian attems

Am Sonntag, 15. August 2004 14:18 schrieb maximilian attems:

Quoted 11 lines

while doing kernel-janitor msleep conversion of drivers own (incorrect), functions, some places would need msleep_interruptible().

this function is equivalent to:

        current->state = TASK_INTERRUPTIBLE;
	schedule_timeout(timeout);

idea from Ingo Molnar:
well, aboves is not 100% equivalent because msleep() is uninterruptible so stoppage of the md thread (upon shutdown) will occur with only a 250 msec delay. Someone should add a msleep_interruptible() function to kernel/timer.c.

[..]

kernel/timer.c void msleep(unsigned int msecs) · line 1517

Quoted 12 lines
kernel/timer.c renamed from kernel/timer.c~add-msleep_interruptible +12 -0
+/**
+ * msleep_interruptible - sleep waiting for waitqueue interruptions
+ * @msecs: Time in milliseconds to sleep for
+ */
+void msleep_interruptible(unsigned int msecs)
+{
+	unsigned long timeout = msecs_to_jiffies(msecs);
+
+	while (timeout) {
+		set_current_state(TASK_INTERRUPTIBLE);
+		timeout = schedule_timeout(timeout);
+	}

This is not really interruptible sleep because it is missing a check for pending signals.

Regards
Oliver