From: Thadeu Lima de Souza Cascardo Date: Thu, 20 May 2010 20:14:13 +0000 (-0400) Subject: Use spinlock to busy wait. X-Git-Url: http://git.cascardo.eti.br/?p=cascardo%2Fkernel%2Fsamples%2Fchar2%2F.git;a=commitdiff_plain;h=37d2e76fba58bb46fc3578ef150681619a4adbe9 Use spinlock to busy wait. --- diff --git a/hellochar.c b/hellochar.c index 1b0c9f2..206b6d1 100644 --- a/hellochar.c +++ b/hellochar.c @@ -20,71 +20,36 @@ #include #include #include -#include -#include +#include MODULE_LICENSE("GPL"); -#define MAXLEN 4000 static dev_t devnum; static struct cdev *dev; static const char default_greeting[] = "Hello, World!\n"; -struct hello_buffer { - size_t len; - char buffer[0]; -}; -static struct hello_buffer *hello; -static DEFINE_MUTEX(hello_mtx); +static DEFINE_SPINLOCK(hello_lock); static int hello_open(struct inode *ino, struct file *fp) { - if (mutex_lock_interruptible(&hello_mtx)) - return -ERESTARTSYS; - if (fp->f_flags & O_TRUNC) { - memset(hello->buffer, 0, MAXLEN); - hello->len = 0; - } - if (fp->f_flags & O_APPEND) - fp->f_pos = hello->len; - mutex_unlock(&hello_mtx); return 0; } static ssize_t hello_read(struct file *fp, char __user *buf, size_t sz, loff_t *pos) { - int r; - if (mutex_lock_interruptible(&hello_mtx)) - return -ERESTARTSYS; - if (sz + *pos > hello->len) - sz = hello->len - *pos; - r = copy_to_user(buf, hello->buffer + *pos, sz); - mutex_unlock(&hello_mtx); - if (r) - return -EFAULT; - *pos += sz; - return sz; + int i = 1 << 28; + spin_lock(&hello_lock); + while (i--) + cpu_relax(); + spin_unlock(&hello_lock); + return 0; } static ssize_t hello_write(struct file *fp, const char __user *buf, size_t sz, loff_t *pos) { - int r; - if (mutex_lock_interruptible(&hello_mtx)) - return -ERESTARTSYS; - if (sz + *pos > MAXLEN) - sz = MAXLEN - *pos; - r = copy_from_user(hello->buffer + *pos, buf, sz); - if (r) { - mutex_unlock(&hello_mtx); - return -EFAULT; - } - *pos += sz; - if (hello->len < *pos) - hello->len = *pos; - mutex_unlock(&hello_mtx); - return sz; + return 0; } static int hello_release(struct inode *ino, struct file *fp) @@ -103,13 +68,6 @@ static const struct file_operations hello_fops = { static int __init ch_init(void) { int r = 0; - hello = kzalloc(sizeof(*hello) + MAXLEN, GFP_KERNEL); - if (!hello) { - r = -ENOMEM; - goto out; - } - memcpy(hello->buffer, default_greeting, sizeof(default_greeting)); - hello->len = sizeof(default_greeting); r = alloc_chrdev_region(&devnum, 0, 256, "hello"); if (r) goto reg_out; @@ -129,8 +87,6 @@ add_out: cdev_out: unregister_chrdev_region(devnum, 256); reg_out: - kfree(hello); -out: return r; } @@ -138,7 +94,6 @@ static void __exit ch_exit(void) { cdev_del(dev); unregister_chrdev_region(devnum, 256); - kfree(hello); } module_init(ch_init); diff --git a/usr.c b/usr.c index 0829125..d4d2aba 100644 --- a/usr.c +++ b/usr.c @@ -19,19 +19,18 @@ #include #include +#include int main(void) { int fd; char buffer[16]; - int r; fd = open("/dev/hello", O_RDONLY); if (fd < 0) return 1; - while (1) { - lseek(fd, 0, SEEK_SET); - r = read(fd, buffer, sizeof(buffer)); - write(1, buffer, r); - } + read(fd, buffer, sizeof(buffer)); + sleep(5); + write(fd, buffer, sizeof(buffer)); + close(fd); return 0; }