On Fri, 01 Oct 2004, Jeff Garzik wrote:
> I would rather see an msleep implementation in 2.4.x...
thanks for Domen Puncer at helping out.
msleep() and msleep_interruptible() as found in current 2.6 to 2.4.
therefor also adds the helper functions ssleep(), jiffies_to_msecs(),
jiffies_to_usecs(), msecs_to_jiffies().
compile and boot tested.
Signed-off-by: Maximilian Attems <[email protected]>
---
include/linux/delay.h | 8 ++++++
include/linux/time.h | 41 +++++++++++++++++++++++++++++++++
kernel/Makefile | 3 +-
kernel/timer.c | 33 ++++++++++++++++++++++++++
4 files changed, 84 insertions(+), 1 deletion(-)
diff -puN kernel/Makefile~add-msleep-2.4 kernel/Makefile
--- a/kernel/Makefile~add-msleep-2.4 2004-10-30 22:48:46.000000000 +0200
+++ b/kernel/Makefile 2004-10-30 22:50:45.000000000 +0200
@@ -9,7 +9,8 @@
O_TARGET := kernel.o
-export-objs = signal.o sys.o kmod.o context.o ksyms.o pm.o exec_domain.o printk.o
+export-objs = signal.o sys.o kmod.o context.o ksyms.o pm.o exec_domain.o \
+ printk.o timer.o
obj-y = sched.o dma.o fork.o exec_domain.o panic.o printk.o \
module.o exit.o itimer.o info.o time.o softirq.o resource.o \
diff -puN kernel/timer.c~add-msleep-2.4 kernel/timer.c
--- a/kernel/timer.c~add-msleep-2.4 2004-10-30 22:48:46.000000000 +0200
+++ b/kernel/timer.c 2004-10-30 22:50:09.000000000 +0200
@@ -22,6 +22,7 @@
#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/kernel_stat.h>
+#include <linux/module.h>
#include <asm/uaccess.h>
@@ -874,3 +875,35 @@ asmlinkage long sys_nanosleep(struct tim
return 0;
}
+/**
+ * msleep - sleep safely even with waitqueue interruptions
+ * @msecs: Time in milliseconds to sleep for
+ */
+void msleep(unsigned int msecs)
+{
+ unsigned long timeout = msecs_to_jiffies(msecs) + 1;
+
+ while (timeout) {
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ timeout = schedule_timeout(timeout);
+ }
+}
+
+EXPORT_SYMBOL(msleep);
+
+/**
+ * msleep_interruptible - sleep waiting for waitqueue interruptions
+ * @msecs: Time in milliseconds to sleep for
+ */
+unsigned long msleep_interruptible(unsigned int msecs)
+{
+ unsigned long timeout = msecs_to_jiffies(msecs) + 1;
+
+ while (timeout && !signal_pending(current)) {
+ set_current_state(TASK_INTERRUPTIBLE);
+ timeout = schedule_timeout(timeout);
+ }
+ return jiffies_to_msecs(timeout);
+}
+
+EXPORT_SYMBOL(msleep_interruptible);
diff -puN include/linux/delay.h~add-msleep-2.4 include/linux/delay.h
--- a/include/linux/delay.h~add-msleep-2.4 2004-10-30 22:48:46.000000000 +0200
+++ b/include/linux/delay.h 2004-10-30 22:48:46.000000000 +0200
@@ -34,4 +34,12 @@ extern unsigned long loops_per_jiffy;
({unsigned long msec=(n); while (msec--) udelay(1000);}))
#endif
+void msleep(unsigned int msecs);
+unsigned long msleep_interruptible(unsigned int msecs);
+
+static inline void ssleep(unsigned int seconds)
+{
+ msleep(seconds * 1000);
+}
+
#endif /* defined(_LINUX_DELAY_H) */
diff -puN include/linux/time.h~add-msleep-2.4 include/linux/time.h
--- a/include/linux/time.h~add-msleep-2.4 2004-10-30 22:48:46.000000000 +0200
+++ b/include/linux/time.h 2004-10-30 22:48:46.000000000 +0200
@@ -126,4 +126,45 @@ struct itimerval {
struct timeval it_value; /* current value */
};
+/*
+ * Convert jiffies to milliseconds and back.
+ *
+ * Avoid unnecessary multiplications/divisions in the
+ * two most common HZ cases:
+ */
+static inline unsigned int jiffies_to_msecs(const unsigned long j)
+{
+#if HZ <= 1000 && !(1000 % HZ)
+ return (1000 / HZ) * j;
+#elif HZ > 1000 && !(HZ % 1000)
+ return (j + (HZ / 1000) - 1)/(HZ / 1000);
+#else
+ return (j * 1000) / HZ;
+#endif
+}
+
+static inline unsigned int jiffies_to_usecs(const unsigned long j)
+{
+#if HZ <= 1000 && !(1000 % HZ)
+ return (1000000 / HZ) * j;
+#elif HZ > 1000 && !(HZ % 1000)
+ return (j*1000 + (HZ - 1000))/(HZ / 1000);
+#else
+ return (j * 1000000) / HZ;
+#endif
+}
+
+static inline unsigned long msecs_to_jiffies(const unsigned int m)
+{
+ if (m > jiffies_to_msecs(MAX_JIFFY_OFFSET))
+ return MAX_JIFFY_OFFSET;
+#if HZ <= 1000 && !(1000 % HZ)
+ return (m + (1000 / HZ) - 1) / (1000 / HZ);
+#elif HZ > 1000 && !(HZ % 1000)
+ return m * (HZ / 1000);
+#else
+ return (m * HZ + 999) / 1000;
+#endif
+}
+
#endif
maximilian attems wrote:
> diff -puN include/linux/delay.h~add-msleep-2.4 include/linux/delay.h
> --- a/include/linux/delay.h~add-msleep-2.4 2004-10-30 22:48:46.000000000 +0200
> +++ b/include/linux/delay.h 2004-10-30 22:48:46.000000000 +0200
> @@ -34,4 +34,12 @@ extern unsigned long loops_per_jiffy;
> ({unsigned long msec=(n); while (msec--) udelay(1000);}))
> #endif
>
> +void msleep(unsigned int msecs);
> +unsigned long msleep_interruptible(unsigned int msecs);
> +
> +static inline void ssleep(unsigned int seconds)
[...]
> +static inline unsigned int jiffies_to_msecs(const unsigned long j)
> +static inline unsigned int jiffies_to_usecs(const unsigned long j)
> +static inline unsigned long msecs_to_jiffies(const unsigned int m)
I'm pretty sure more than one of these symbols clashes with a symbol
defined locally in a driver. I like the patch but we can't apply it
until the impact on existing code is evaluated.
Jeff
On Sat, 30 Oct 2004 18:41:10 -0400, Jeff Garzik <[email protected]> wrote:
> maximilian attems wrote:
> > diff -puN include/linux/delay.h~add-msleep-2.4 include/linux/delay.h
> > --- a/include/linux/delay.h~add-msleep-2.4 2004-10-30 22:48:46.000000000 +0200
> > +++ b/include/linux/delay.h 2004-10-30 22:48:46.000000000 +0200
> > @@ -34,4 +34,12 @@ extern unsigned long loops_per_jiffy;
> > ({unsigned long msec=(n); while (msec--) udelay(1000);}))
> > #endif
> >
> > +void msleep(unsigned int msecs);
> > +unsigned long msleep_interruptible(unsigned int msecs);
> > +
> > +static inline void ssleep(unsigned int seconds)
> [...]
> > +static inline unsigned int jiffies_to_msecs(const unsigned long j)
>
> > +static inline unsigned int jiffies_to_usecs(const unsigned long j)
>
> > +static inline unsigned long msecs_to_jiffies(const unsigned int m)
>
>
> I'm pretty sure more than one of these symbols clashes with a symbol
> defined locally in a driver. I like the patch but we can't apply it
> until the impact on existing code is evaluated.
More than likely much of the code cleanup that was done before I began
my patches, like removing custom msleep()s from drivers will need to
be done again, as Jeff points out.
-Nish
On Sat, 30 Oct 2004, Nish Aravamudan wrote:
> On Sat, 30 Oct 2004 18:41:10 -0400, Jeff Garzik <[email protected]> wrote:
> > maximilian attems wrote:
> > > diff -puN include/linux/delay.h~add-msleep-2.4 include/linux/delay.h
> > > --- a/include/linux/delay.h~add-msleep-2.4 2004-10-30 22:48:46.000000000 +0200
> > > +++ b/include/linux/delay.h 2004-10-30 22:48:46.000000000 +0200
> > > @@ -34,4 +34,12 @@ extern unsigned long loops_per_jiffy;
> > > ({unsigned long msec=(n); while (msec--) udelay(1000);}))
> > > #endif
> > >
> > > +void msleep(unsigned int msecs);
> > > +unsigned long msleep_interruptible(unsigned int msecs);
> > > +
> > > +static inline void ssleep(unsigned int seconds)
> > [...]
> > > +static inline unsigned int jiffies_to_msecs(const unsigned long j)
> >
> > > +static inline unsigned int jiffies_to_usecs(const unsigned long j)
> >
> > > +static inline unsigned long msecs_to_jiffies(const unsigned int m)
> >
> >
> > I'm pretty sure more than one of these symbols clashes with a symbol
> > defined locally in a driver. I like the patch but we can't apply it
> > until the impact on existing code is evaluated.
>
> More than likely much of the code cleanup that was done before I began
> my patches, like removing custom msleep()s from drivers will need to
> be done again, as Jeff points out.
>
> -Nish
thanks Jeff for your quick response,
ooh i seee libata is defining an msleep().
so there seems to be need for it.
ok we'll come up with tougher patchset.
--
maks
kernel janitor http://janitor.kernelnewbies.org/
On Sat, 30 Oct 2004, Jeff Garzik wrote:
> I'm pretty sure more than one of these symbols clashes with a symbol
> defined locally in a driver. I like the patch but we can't apply it
> until the impact on existing code is evaluated.
>
> Jeff
current 2.4 has no ssleep() nor jiffies_to_usecs() nor jiffies_to_msecs()
users. so no namespace conflicts on them.
i found a strange unsupported "msleep" syscall in
./arch/parisc/hpux/sys_hpux.c
left this one appart, i resend the msleep patch + 5 cleanup patches.
they remove duplicate msleep() or msecs_to_jiffies() definitions.
they are all compile tested, but the one touching drivers/char/shwdt.c
please show me if i forgot something.
--
maks
kernel janitor http://janitor.kernelnewbies.org/
ps dropped [email protected] from cc as this ml rejects my mails.
Backport suggested by prism54 folks. idea acked by Jeff.
thanks for Domen Puncer at helping out.
Belows patch adds msleep() and msleep_interruptible() as found
in current 2.6 to 2.4.
therefor adds the helper functions ssleep(), jiffies_to_msecs(),
jiffies_to_usecs(), msecs_to_jiffies().
The namespace clashes for msleep() and msecs_to_jiffies()
are cleanup by the next 5 patches.
Signed-off-by: Maximilian Attems <[email protected]>
---
linux-2.4.28-rc1-max/include/linux/delay.h | 8 +++++
linux-2.4.28-rc1-max/include/linux/time.h | 41 +++++++++++++++++++++++++++++
linux-2.4.28-rc1-max/kernel/Makefile | 3 +-
linux-2.4.28-rc1-max/kernel/timer.c | 33 +++++++++++++++++++++++
4 files changed, 84 insertions(+), 1 deletion(-)
diff -puN kernel/Makefile~add-msleep-2.4 kernel/Makefile
--- linux-2.4.28-rc1/kernel/Makefile~add-msleep-2.4 2004-10-30 22:48:46.000000000 +0200
+++ linux-2.4.28-rc1-max/kernel/Makefile 2004-10-30 22:50:45.000000000 +0200
@@ -9,7 +9,8 @@
O_TARGET := kernel.o
-export-objs = signal.o sys.o kmod.o context.o ksyms.o pm.o exec_domain.o printk.o
+export-objs = signal.o sys.o kmod.o context.o ksyms.o pm.o exec_domain.o \
+ printk.o timer.o
obj-y = sched.o dma.o fork.o exec_domain.o panic.o printk.o \
module.o exit.o itimer.o info.o time.o softirq.o resource.o \
diff -puN kernel/timer.c~add-msleep-2.4 kernel/timer.c
--- linux-2.4.28-rc1/kernel/timer.c~add-msleep-2.4 2004-10-30 22:48:46.000000000 +0200
+++ linux-2.4.28-rc1-max/kernel/timer.c 2004-10-30 22:50:09.000000000 +0200
@@ -22,6 +22,7 @@
#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/kernel_stat.h>
+#include <linux/module.h>
#include <asm/uaccess.h>
@@ -874,3 +875,35 @@ asmlinkage long sys_nanosleep(struct tim
return 0;
}
+/**
+ * msleep - sleep safely even with waitqueue interruptions
+ * @msecs: Time in milliseconds to sleep for
+ */
+void msleep(unsigned int msecs)
+{
+ unsigned long timeout = msecs_to_jiffies(msecs) + 1;
+
+ while (timeout) {
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ timeout = schedule_timeout(timeout);
+ }
+}
+
+EXPORT_SYMBOL(msleep);
+
+/**
+ * msleep_interruptible - sleep waiting for waitqueue interruptions
+ * @msecs: Time in milliseconds to sleep for
+ */
+unsigned long msleep_interruptible(unsigned int msecs)
+{
+ unsigned long timeout = msecs_to_jiffies(msecs) + 1;
+
+ while (timeout && !signal_pending(current)) {
+ set_current_state(TASK_INTERRUPTIBLE);
+ timeout = schedule_timeout(timeout);
+ }
+ return jiffies_to_msecs(timeout);
+}
+
+EXPORT_SYMBOL(msleep_interruptible);
diff -puN include/linux/delay.h~add-msleep-2.4 include/linux/delay.h
--- linux-2.4.28-rc1/include/linux/delay.h~add-msleep-2.4 2004-10-30 22:48:46.000000000 +0200
+++ linux-2.4.28-rc1-max/include/linux/delay.h 2004-10-30 22:48:46.000000000 +0200
@@ -34,4 +34,12 @@ extern unsigned long loops_per_jiffy;
({unsigned long msec=(n); while (msec--) udelay(1000);}))
#endif
+void msleep(unsigned int msecs);
+unsigned long msleep_interruptible(unsigned int msecs);
+
+static inline void ssleep(unsigned int seconds)
+{
+ msleep(seconds * 1000);
+}
+
#endif /* defined(_LINUX_DELAY_H) */
diff -puN include/linux/time.h~add-msleep-2.4 include/linux/time.h
--- linux-2.4.28-rc1/include/linux/time.h~add-msleep-2.4 2004-10-30 22:48:46.000000000 +0200
+++ linux-2.4.28-rc1-max/include/linux/time.h 2004-10-30 22:57:44.000000000 +0200
@@ -126,4 +126,45 @@ struct itimerval {
struct timeval it_value; /* current value */
};
+/*
+ * Convert jiffies to milliseconds and back.
+ *
+ * Avoid unnecessary multiplications/divisions in the
+ * two most common HZ cases:
+ */
+static inline unsigned int jiffies_to_msecs(const unsigned long j)
+{
+#if HZ <= 1000 && !(1000 % HZ)
+ return (1000 / HZ) * j;
+#elif HZ > 1000 && !(HZ % 1000)
+ return (j + (HZ / 1000) - 1)/(HZ / 1000);
+#else
+ return (j * 1000) / HZ;
+#endif
+}
+
+static inline unsigned int jiffies_to_usecs(const unsigned long j)
+{
+#if HZ <= 1000 && !(1000 % HZ)
+ return (1000000 / HZ) * j;
+#elif HZ > 1000 && !(HZ % 1000)
+ return (j*1000 + (HZ - 1000))/(HZ / 1000);
+#else
+ return (j * 1000000) / HZ;
+#endif
+}
+
+static inline unsigned long msecs_to_jiffies(const unsigned int m)
+{
+ if (m > jiffies_to_msecs(MAX_JIFFY_OFFSET))
+ return MAX_JIFFY_OFFSET;
+#if HZ <= 1000 && !(1000 % HZ)
+ return (m + (1000 / HZ) - 1) / (1000 / HZ);
+#elif HZ > 1000 && !(HZ % 1000)
+ return m * (HZ / 1000);
+#else
+ return (m * HZ + 999) / 1000;
+#endif
+}
+
#endif
_
remove duplicate definition of msecs_to_jiffies().
already includes delay.h
Signed-off-by: Maximilian Attems <[email protected]>
---
linux-2.4.28-rc1-max/include/linux/libata.h | 5 -----
1 files changed, 5 deletions(-)
diff -puN include/linux/libata.h~remove-msecs_to_jiffies-libata.h include/linux/libata.h
--- linux-2.4.28-rc1/include/linux/libata.h~remove-msecs_to_jiffies-libata.h 2004-10-31 13:33:52.000000000 +0100
+++ linux-2.4.28-rc1-max/include/linux/libata.h 2004-10-31 13:36:16.000000000 +0100
@@ -419,11 +419,6 @@ extern int ata_std_bios_param(Disk * dis
extern void libata_msleep(unsigned long msecs);
-static inline unsigned long msecs_to_jiffies(unsigned long msecs)
-{
- return ((HZ * msecs + 999) / 1000);
-}
-
static inline unsigned int ata_tag_valid(unsigned int tag)
{
return (tag < ATA_MAX_QUEUE) ? 1 : 0;
_
remove msleep_libata(), now that msleep() is backported.
also remove duplicate msleep() definition.
delay.h is already included.
Signed-off-by: Maximilian Attems <[email protected]>
---
linux-2.4.28-rc1-max/drivers/scsi/libata-core.c | 23 -----------------------
linux-2.4.28-rc1-max/include/linux/libata.h | 1 -
2 files changed, 24 deletions(-)
diff -puN drivers/scsi/libata-core.c~remove-libata_msleep drivers/scsi/libata-core.c
--- linux-2.4.28-rc1/drivers/scsi/libata-core.c~remove-libata_msleep 2004-10-31 14:06:49.000000000 +0100
+++ linux-2.4.28-rc1-max/drivers/scsi/libata-core.c 2004-10-31 14:08:41.000000000 +0100
@@ -67,28 +67,6 @@ MODULE_DESCRIPTION("Library module for A
MODULE_LICENSE("GPL");
/**
- * msleep - sleep for a number of milliseconds
- * @msecs: number of milliseconds to sleep
- *
- * Issues schedule_timeout call for the specified number
- * of milliseconds.
- *
- * LOCKING:
- * None.
- */
-
-static void msleep(unsigned long msecs)
-{
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(msecs_to_jiffies(msecs) + 1);
-}
-
-void libata_msleep(unsigned long msecs)
-{
- msleep(msecs);
-}
-
-/**
* ata_tf_load - send taskfile registers to host controller
* @ap: Port to which output is sent
* @tf: ATA taskfile register set
@@ -3697,7 +3675,6 @@ EXPORT_SYMBOL_GPL(ata_scsi_queuecmd);
EXPORT_SYMBOL_GPL(ata_scsi_error);
EXPORT_SYMBOL_GPL(ata_scsi_detect);
EXPORT_SYMBOL_GPL(ata_add_to_probe_list);
-EXPORT_SYMBOL_GPL(libata_msleep);
EXPORT_SYMBOL_GPL(ata_scsi_release);
EXPORT_SYMBOL_GPL(ata_host_intr);
EXPORT_SYMBOL_GPL(ata_dev_classify);
diff -puN include/linux/libata.h~remove-libata_msleep include/linux/libata.h
--- linux-2.4.28-rc1/include/linux/libata.h~remove-libata_msleep 2004-10-31 14:06:49.000000000 +0100
+++ linux-2.4.28-rc1-max/include/linux/libata.h 2004-10-31 14:09:08.000000000 +0100
@@ -416,7 +416,6 @@ extern void ata_qc_complete(struct ata_q
extern void ata_eng_timeout(struct ata_port *ap);
extern void ata_add_to_probe_list (struct ata_probe_ent *probe_ent);
extern int ata_std_bios_param(Disk * disk, kdev_t dev, int *ip);
-extern void libata_msleep(unsigned long msecs);
static inline unsigned int ata_tag_valid(unsigned int tag)
_
remove duplicate msecs_to_jiffies() definition.
add include <delay.h>.
Signed-off-by: Maximilian Attems <[email protected]>
---
linux-2.4.28-rc1-max/drivers/char/shwdt.c | 2 +-
1 files changed, 1 insertion(+), 1 deletion(-)
diff -puN drivers/char/shwdt.c~remove-msecs_to_jiffies-drivers_char_shwdt drivers/char/shwdt.c
--- linux-2.4.28-rc1/drivers/char/shwdt.c~remove-msecs_to_jiffies-drivers_char_shwdt 2004-10-31 13:40:49.000000000 +0100
+++ linux-2.4.28-rc1-max/drivers/char/shwdt.c 2004-10-31 13:42:05.000000000 +0100
@@ -27,6 +27,7 @@
#include <linux/reboot.h>
#include <linux/notifier.h>
#include <linux/ioport.h>
+#include <linux/delay.h>
#include <asm/io.h>
#include <asm/uaccess.h>
@@ -113,7 +114,6 @@
*/
static int clock_division_ratio = WTCSR_CKS_4096;
-#define msecs_to_jiffies(msecs) (jiffies + (HZ * msecs + 9999) / 10000)
#define next_ping_period(cks) msecs_to_jiffies(cks - 4)
static unsigned long shwdt_is_open;
_
remove duplicate definition msleep(), msecs_to_jiffies().
delay.h already included.
Signed-off-by: Maximilian Attems <[email protected]>
---
linux-2.4.28-rc1-max/drivers/block/sx8.c | 11 -----------
1 files changed, 11 deletions(-)
diff -puN drivers/block/sx8.c~remove-msleep+msecs_to_jiffies-drivers_block_sx8 drivers/block/sx8.c
--- linux-2.4.28-rc1/drivers/block/sx8.c~remove-msleep+msecs_to_jiffies-drivers_block_sx8 2004-10-31 13:37:56.000000000 +0100
+++ linux-2.4.28-rc1-max/drivers/block/sx8.c 2004-10-31 13:38:56.000000000 +0100
@@ -548,17 +548,6 @@ static int carm_bdev_ioctl(struct inode
return -EOPNOTSUPP;
}
-static inline unsigned long msecs_to_jiffies(unsigned long msecs)
-{
- return ((HZ * msecs + 999) / 1000);
-}
-
-static void msleep(unsigned long msecs)
-{
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(msecs_to_jiffies(msecs) + 1);
-}
-
static const u32 msg_sizes[] = { 32, 64, 128, CARM_MSG_SIZE };
static inline int carm_lookup_bucket(u32 msg_size)
_
remove now duplicate define.
driver already includes delay.
Signed-off-by: Maximilian Attems <[email protected]>
---
linux-2.4.28-rc1-max/drivers/scsi/sata_promise.c | 2 --
1 files changed, 2 deletions(-)
diff -puN drivers/scsi/sata_promise.c~remove-msleep-drivers_scsi_sata_promise drivers/scsi/sata_promise.c
--- linux-2.4.28-rc1/drivers/scsi/sata_promise.c~remove-msleep-drivers_scsi_sata_promise 2004-10-31 13:59:39.000000000 +0100
+++ linux-2.4.28-rc1-max/drivers/scsi/sata_promise.c 2004-10-31 14:00:12.000000000 +0100
@@ -42,8 +42,6 @@
#define DRV_NAME "sata_promise"
#define DRV_VERSION "1.00"
-#define msleep libata_msleep /* 2.4-specific */
-
enum {
PDC_PKT_SUBMIT = 0x40, /* Command packet pointer addr */
PDC_INT_SEQMASK = 0x40, /* Mask of asserted SEQ INTs */
_