[4/4] kevent: poll/select() notifications. Timer notifications.

2006-07-26 Thread Evgeniy Polyakov

This patch includes generic poll/select and timer notifications.

kevent_poll works simialr to epoll and has the same issues (callback
is invoked not from internal state machine of the caller, but through
process awake).

Timer notifications can be used for fine grained per-process time 
management, since iteractive timers are very inconveniently to use, 
and they are limited.

Signed-off-by: Evgeniy Polyakov <[EMAIL PROTECTED]>

diff --git a/kernel/kevent/kevent_poll.c b/kernel/kevent/kevent_poll.c
new file mode 100644
index 000..4950e7c
--- /dev/null
+++ b/kernel/kevent/kevent_poll.c
@@ -0,0 +1,223 @@
+/*
+ * kevent_poll.c
+ * 
+ * 2006 Copyright (c) Evgeniy Polyakov <[EMAIL PROTECTED]>
+ * All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static kmem_cache_t *kevent_poll_container_cache;
+static kmem_cache_t *kevent_poll_priv_cache;
+
+struct kevent_poll_ctl
+{
+   struct poll_table_structpt;
+   struct kevent   *k;
+};
+
+struct kevent_poll_wait_container
+{
+   struct list_headcontainer_entry;
+   wait_queue_head_t   *whead;
+   wait_queue_twait;
+   struct kevent   *k;
+};
+
+struct kevent_poll_private
+{
+   struct list_headcontainer_list;
+   spinlock_t  container_lock;
+};
+
+static int kevent_poll_enqueue(struct kevent *k);
+static int kevent_poll_dequeue(struct kevent *k);
+static int kevent_poll_callback(struct kevent *k);
+
+static int kevent_poll_wait_callback(wait_queue_t *wait, 
+   unsigned mode, int sync, void *key)
+{
+   struct kevent_poll_wait_container *cont = 
+   container_of(wait, struct kevent_poll_wait_container, wait);
+   struct kevent *k = cont->k;
+   struct file *file = k->st->origin;
+   unsigned long flags;
+   u32 revents, event;
+
+   revents = file->f_op->poll(file, NULL);
+   spin_lock_irqsave(&k->lock, flags);
+   event = k->event.event;
+   spin_unlock_irqrestore(&k->lock, flags);
+
+   kevent_storage_ready(k->st, NULL, revents);
+
+   return 0;
+}
+
+static void kevent_poll_qproc(struct file *file, wait_queue_head_t *whead, 
+   struct poll_table_struct *poll_table)
+{
+   struct kevent *k = 
+   container_of(poll_table, struct kevent_poll_ctl, pt)->k;
+   struct kevent_poll_private *priv = k->priv;
+   struct kevent_poll_wait_container *cont;
+   unsigned long flags;
+
+   cont = kmem_cache_alloc(kevent_poll_container_cache, SLAB_KERNEL);
+   if (!cont) {
+   kevent_break(k);
+   return;
+   }
+   
+   cont->k = k;
+   init_waitqueue_func_entry(&cont->wait, kevent_poll_wait_callback);
+   cont->whead = whead;
+
+   spin_lock_irqsave(&priv->container_lock, flags);
+   list_add_tail(&cont->container_entry, &priv->container_list);
+   spin_unlock_irqrestore(&priv->container_lock, flags);
+
+   add_wait_queue(whead, &cont->wait);
+}
+
+static int kevent_poll_enqueue(struct kevent *k)
+{
+   struct file *file;
+   int err, ready = 0;
+   unsigned int revents;
+   struct kevent_poll_ctl ctl;
+   struct kevent_poll_private *priv;
+
+   file = fget(k->event.id.raw[0]);
+   if (!file)
+   return -ENODEV;
+
+   err = -EINVAL;
+   if (!file->f_op || !file->f_op->poll)
+   goto err_out_fput;
+
+   err = -ENOMEM;
+   priv = kmem_cache_alloc(kevent_poll_priv_cache, SLAB_KERNEL);
+   if (!priv)
+   goto err_out_fput;
+
+   spin_lock_init(&priv->container_lock);
+   INIT_LIST_HEAD(&priv->container_list);
+
+   k->priv = priv;
+
+   ctl.k = k;
+   init_poll_funcptr(&ctl.pt, &kevent_poll_qproc);
+
+   err = kevent_storage_enqueue(&file->st, k);
+   if (err)
+   goto err_out_free;
+
+   revents = file->f_op->poll(file, &ctl.pt);
+   if (revents & k->event.event) {
+   ready = 1;
+   kevent_poll_dequeue(k);
+   }
+   
+   return ready;
+
+err_out_free:
+   kmem_cache_free(kevent_poll_priv_cache, priv);
+err_out_fput:
+   fput(file);
+   return err;
+}
+
+static int kevent_poll_dequeue(struct kevent *k)
+{
+   struct file *file = k->st->origin;
+   struct kevent_po

[take2 4/4] kevent: poll/select() notifications. Timer notifications.

2006-08-01 Thread Evgeniy Polyakov

This patch includes generic poll/select and timer notifications.

kevent_poll works simialr to epoll and has the same issues (callback
is invoked not from internal state machine of the caller, but through
process awake).

Timer notifications can be used for fine grained per-process time 
management, since iteractive timers are very inconveniently to use, 
and they are limited.

Signed-off-by: Evgeniy Polyakov <[EMAIL PROTECTED]>

diff --git a/kernel/kevent/kevent_poll.c b/kernel/kevent/kevent_poll.c
new file mode 100644
index 000..4950e7c
--- /dev/null
+++ b/kernel/kevent/kevent_poll.c
@@ -0,0 +1,223 @@
+/*
+ * kevent_poll.c
+ * 
+ * 2006 Copyright (c) Evgeniy Polyakov <[EMAIL PROTECTED]>
+ * All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static kmem_cache_t *kevent_poll_container_cache;
+static kmem_cache_t *kevent_poll_priv_cache;
+
+struct kevent_poll_ctl
+{
+   struct poll_table_structpt;
+   struct kevent   *k;
+};
+
+struct kevent_poll_wait_container
+{
+   struct list_headcontainer_entry;
+   wait_queue_head_t   *whead;
+   wait_queue_twait;
+   struct kevent   *k;
+};
+
+struct kevent_poll_private
+{
+   struct list_headcontainer_list;
+   spinlock_t  container_lock;
+};
+
+static int kevent_poll_enqueue(struct kevent *k);
+static int kevent_poll_dequeue(struct kevent *k);
+static int kevent_poll_callback(struct kevent *k);
+
+static int kevent_poll_wait_callback(wait_queue_t *wait, 
+   unsigned mode, int sync, void *key)
+{
+   struct kevent_poll_wait_container *cont = 
+   container_of(wait, struct kevent_poll_wait_container, wait);
+   struct kevent *k = cont->k;
+   struct file *file = k->st->origin;
+   unsigned long flags;
+   u32 revents, event;
+
+   revents = file->f_op->poll(file, NULL);
+   spin_lock_irqsave(&k->lock, flags);
+   event = k->event.event;
+   spin_unlock_irqrestore(&k->lock, flags);
+
+   kevent_storage_ready(k->st, NULL, revents);
+
+   return 0;
+}
+
+static void kevent_poll_qproc(struct file *file, wait_queue_head_t *whead, 
+   struct poll_table_struct *poll_table)
+{
+   struct kevent *k = 
+   container_of(poll_table, struct kevent_poll_ctl, pt)->k;
+   struct kevent_poll_private *priv = k->priv;
+   struct kevent_poll_wait_container *cont;
+   unsigned long flags;
+
+   cont = kmem_cache_alloc(kevent_poll_container_cache, SLAB_KERNEL);
+   if (!cont) {
+   kevent_break(k);
+   return;
+   }
+   
+   cont->k = k;
+   init_waitqueue_func_entry(&cont->wait, kevent_poll_wait_callback);
+   cont->whead = whead;
+
+   spin_lock_irqsave(&priv->container_lock, flags);
+   list_add_tail(&cont->container_entry, &priv->container_list);
+   spin_unlock_irqrestore(&priv->container_lock, flags);
+
+   add_wait_queue(whead, &cont->wait);
+}
+
+static int kevent_poll_enqueue(struct kevent *k)
+{
+   struct file *file;
+   int err, ready = 0;
+   unsigned int revents;
+   struct kevent_poll_ctl ctl;
+   struct kevent_poll_private *priv;
+
+   file = fget(k->event.id.raw[0]);
+   if (!file)
+   return -ENODEV;
+
+   err = -EINVAL;
+   if (!file->f_op || !file->f_op->poll)
+   goto err_out_fput;
+
+   err = -ENOMEM;
+   priv = kmem_cache_alloc(kevent_poll_priv_cache, SLAB_KERNEL);
+   if (!priv)
+   goto err_out_fput;
+
+   spin_lock_init(&priv->container_lock);
+   INIT_LIST_HEAD(&priv->container_list);
+
+   k->priv = priv;
+
+   ctl.k = k;
+   init_poll_funcptr(&ctl.pt, &kevent_poll_qproc);
+
+   err = kevent_storage_enqueue(&file->st, k);
+   if (err)
+   goto err_out_free;
+
+   revents = file->f_op->poll(file, &ctl.pt);
+   if (revents & k->event.event) {
+   ready = 1;
+   kevent_poll_dequeue(k);
+   }
+   
+   return ready;
+
+err_out_free:
+   kmem_cache_free(kevent_poll_priv_cache, priv);
+err_out_fput:
+   fput(file);
+   return err;
+}
+
+static int kevent_poll_dequeue(struct kevent *k)
+{
+   struct file *file = k->st->origin;
+   struct kevent_po

[take3 4/4] kevent: poll/select() notifications. Timer notifications.

2006-08-03 Thread Evgeniy Polyakov

poll/select() notifications. Timer notifications.

This patch includes generic poll/select and timer notifications.

kevent_poll works simialr to epoll and has the same issues (callback
is invoked not from internal state machine of the caller, but through
process awake).

Timer notifications can be used for fine grained per-process time 
management, since iteractive timers are very inconveniently to use, 
and they are limited.

Signed-off-by: Evgeniy Polyakov <[EMAIL PROTECTED]>

diff --git a/kernel/kevent/kevent_poll.c b/kernel/kevent/kevent_poll.c
new file mode 100644
index 000..46cc8f0
--- /dev/null
+++ b/kernel/kevent/kevent_poll.c
@@ -0,0 +1,217 @@
+/*
+ * kevent_poll.c
+ * 
+ * 2006 Copyright (c) Evgeniy Polyakov <[EMAIL PROTECTED]>
+ * All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static kmem_cache_t *kevent_poll_container_cache;
+static kmem_cache_t *kevent_poll_priv_cache;
+
+struct kevent_poll_ctl
+{
+   struct poll_table_structpt;
+   struct kevent   *k;
+};
+
+struct kevent_poll_wait_container
+{
+   struct list_headcontainer_entry;
+   wait_queue_head_t   *whead;
+   wait_queue_twait;
+   struct kevent   *k;
+};
+
+struct kevent_poll_private
+{
+   struct list_headcontainer_list;
+   spinlock_t  container_lock;
+};
+
+static int kevent_poll_enqueue(struct kevent *k);
+static int kevent_poll_dequeue(struct kevent *k);
+static int kevent_poll_callback(struct kevent *k);
+
+static int kevent_poll_wait_callback(wait_queue_t *wait, 
+   unsigned mode, int sync, void *key)
+{
+   struct kevent_poll_wait_container *cont = 
+   container_of(wait, struct kevent_poll_wait_container, wait);
+   struct kevent *k = cont->k;
+   struct file *file = k->st->origin;
+   unsigned long flags;
+   u32 revents, event;
+
+   revents = file->f_op->poll(file, NULL);
+   spin_lock_irqsave(&k->ulock, flags);
+   event = k->event.event;
+   spin_unlock_irqrestore(&k->ulock, flags);
+
+   kevent_storage_ready(k->st, NULL, revents);
+
+   return 0;
+}
+
+static void kevent_poll_qproc(struct file *file, wait_queue_head_t *whead, 
+   struct poll_table_struct *poll_table)
+{
+   struct kevent *k = 
+   container_of(poll_table, struct kevent_poll_ctl, pt)->k;
+   struct kevent_poll_private *priv = k->priv;
+   struct kevent_poll_wait_container *cont;
+   unsigned long flags;
+
+   cont = kmem_cache_alloc(kevent_poll_container_cache, SLAB_KERNEL);
+   if (!cont) {
+   kevent_break(k);
+   return;
+   }
+   
+   cont->k = k;
+   init_waitqueue_func_entry(&cont->wait, kevent_poll_wait_callback);
+   cont->whead = whead;
+
+   spin_lock_irqsave(&priv->container_lock, flags);
+   list_add_tail(&cont->container_entry, &priv->container_list);
+   spin_unlock_irqrestore(&priv->container_lock, flags);
+
+   add_wait_queue(whead, &cont->wait);
+}
+
+static int kevent_poll_enqueue(struct kevent *k)
+{
+   struct file *file;
+   int err, ready = 0;
+   unsigned int revents;
+   struct kevent_poll_ctl ctl;
+   struct kevent_poll_private *priv;
+
+   file = fget(k->event.id.raw[0]);
+   if (!file)
+   return -ENODEV;
+
+   err = -EINVAL;
+   if (!file->f_op || !file->f_op->poll)
+   goto err_out_fput;
+
+   err = -ENOMEM;
+   priv = kmem_cache_alloc(kevent_poll_priv_cache, SLAB_KERNEL);
+   if (!priv)
+   goto err_out_fput;
+
+   spin_lock_init(&priv->container_lock);
+   INIT_LIST_HEAD(&priv->container_list);
+
+   k->priv = priv;
+
+   ctl.k = k;
+   init_poll_funcptr(&ctl.pt, &kevent_poll_qproc);
+
+   err = kevent_storage_enqueue(&file->st, k);
+   if (err)
+   goto err_out_free;
+
+   revents = file->f_op->poll(file, &ctl.pt);
+   if (revents & k->event.event) {
+   ready = 1;
+   kevent_poll_dequeue(k);
+   }
+   
+   return ready;
+
+err_out_free:
+   kmem_cache_free(kevent_poll_priv_cache, priv);
+err_out_fput:
+   fput(file);
+   return err;
+}
+
+static int kevent_poll_dequeue(struct kevent *k)
+{
+   struct

[take4 4/4] kevent: poll/select() notifications. Timer notifications.

2006-08-05 Thread Evgeniy Polyakov

poll/select() notifications. Timer notifications.

This patch includes generic poll/select and timer notifications.

kevent_poll works simialr to epoll and has the same issues (callback
is invoked not from internal state machine of the caller, but through
process awake).

Timer notifications can be used for fine grained per-process time 
management, since iteractive timers are very inconveniently to use, 
and they are limited.

Signed-off-by: Evgeniy Polyakov <[EMAIL PROTECTED]>

diff --git a/kernel/kevent/kevent_poll.c b/kernel/kevent/kevent_poll.c
new file mode 100644
index 000..8a4f863
--- /dev/null
+++ b/kernel/kevent/kevent_poll.c
@@ -0,0 +1,220 @@
+/*
+ * kevent_poll.c
+ * 
+ * 2006 Copyright (c) Evgeniy Polyakov <[EMAIL PROTECTED]>
+ * All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static kmem_cache_t *kevent_poll_container_cache;
+static kmem_cache_t *kevent_poll_priv_cache;
+
+struct kevent_poll_ctl
+{
+   struct poll_table_structpt;
+   struct kevent   *k;
+};
+
+struct kevent_poll_wait_container
+{
+   struct list_headcontainer_entry;
+   wait_queue_head_t   *whead;
+   wait_queue_twait;
+   struct kevent   *k;
+};
+
+struct kevent_poll_private
+{
+   struct list_headcontainer_list;
+   spinlock_t  container_lock;
+};
+
+static int kevent_poll_enqueue(struct kevent *k);
+static int kevent_poll_dequeue(struct kevent *k);
+static int kevent_poll_callback(struct kevent *k);
+
+static int kevent_poll_wait_callback(wait_queue_t *wait, 
+   unsigned mode, int sync, void *key)
+{
+   struct kevent_poll_wait_container *cont = 
+   container_of(wait, struct kevent_poll_wait_container, wait);
+   struct kevent *k = cont->k;
+   struct file *file = k->st->origin;
+   u32 revents;
+
+   revents = file->f_op->poll(file, NULL);
+
+   kevent_storage_ready(k->st, NULL, revents);
+
+   return 0;
+}
+
+static void kevent_poll_qproc(struct file *file, wait_queue_head_t *whead, 
+   struct poll_table_struct *poll_table)
+{
+   struct kevent *k = 
+   container_of(poll_table, struct kevent_poll_ctl, pt)->k;
+   struct kevent_poll_private *priv = k->priv;
+   struct kevent_poll_wait_container *cont;
+   unsigned long flags;
+
+   cont = kmem_cache_alloc(kevent_poll_container_cache, SLAB_KERNEL);
+   if (!cont) {
+   kevent_break(k);
+   return;
+   }
+   
+   cont->k = k;
+   init_waitqueue_func_entry(&cont->wait, kevent_poll_wait_callback);
+   cont->whead = whead;
+
+   spin_lock_irqsave(&priv->container_lock, flags);
+   list_add_tail(&cont->container_entry, &priv->container_list);
+   spin_unlock_irqrestore(&priv->container_lock, flags);
+
+   add_wait_queue(whead, &cont->wait);
+}
+
+static int kevent_poll_enqueue(struct kevent *k)
+{
+   struct file *file;
+   int err, ready = 0;
+   unsigned int revents;
+   struct kevent_poll_ctl ctl;
+   struct kevent_poll_private *priv;
+
+   file = fget(k->event.id.raw[0]);
+   if (!file)
+   return -ENODEV;
+
+   err = -EINVAL;
+   if (!file->f_op || !file->f_op->poll)
+   goto err_out_fput;
+
+   err = -ENOMEM;
+   priv = kmem_cache_alloc(kevent_poll_priv_cache, SLAB_KERNEL);
+   if (!priv)
+   goto err_out_fput;
+
+   spin_lock_init(&priv->container_lock);
+   INIT_LIST_HEAD(&priv->container_list);
+
+   k->priv = priv;
+
+   ctl.k = k;
+   init_poll_funcptr(&ctl.pt, &kevent_poll_qproc);
+
+   err = kevent_storage_enqueue(&file->st, k);
+   if (err)
+   goto err_out_free;
+
+   revents = file->f_op->poll(file, &ctl.pt);
+   if (revents & k->event.event) {
+   ready = 1;
+   kevent_poll_dequeue(k);
+   }
+   
+   return ready;
+
+err_out_free:
+   kmem_cache_free(kevent_poll_priv_cache, priv);
+err_out_fput:
+   fput(file);
+   return err;
+}
+
+static int kevent_poll_dequeue(struct kevent *k)
+{
+   struct file *file = k->st->origin;
+   struct kevent_poll_private *priv = k->priv;
+   struct kevent_poll_wait_container *w, *n;
+   unsigned long flags;
+
+

[take5 4/4] kevent: poll/select() notifications. Timer notifications.

2006-08-08 Thread Evgeniy Polyakov

poll/select() notifications. Timer notifications.

This patch includes generic poll/select and timer notifications.

kevent_poll works simialr to epoll and has the same issues (callback
is invoked not from internal state machine of the caller, but through
process awake).

Timer notifications can be used for fine grained per-process time 
management, since interval timers are very inconvenient to use, 
and they are limited.

Signed-off-by: Evgeniy Polyakov <[EMAIL PROTECTED]>

diff --git a/kernel/kevent/kevent_poll.c b/kernel/kevent/kevent_poll.c
new file mode 100644
index 000..8a4f863
--- /dev/null
+++ b/kernel/kevent/kevent_poll.c
@@ -0,0 +1,220 @@
+/*
+ * kevent_poll.c
+ * 
+ * 2006 Copyright (c) Evgeniy Polyakov <[EMAIL PROTECTED]>
+ * All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static kmem_cache_t *kevent_poll_container_cache;
+static kmem_cache_t *kevent_poll_priv_cache;
+
+struct kevent_poll_ctl
+{
+   struct poll_table_structpt;
+   struct kevent   *k;
+};
+
+struct kevent_poll_wait_container
+{
+   struct list_headcontainer_entry;
+   wait_queue_head_t   *whead;
+   wait_queue_twait;
+   struct kevent   *k;
+};
+
+struct kevent_poll_private
+{
+   struct list_headcontainer_list;
+   spinlock_t  container_lock;
+};
+
+static int kevent_poll_enqueue(struct kevent *k);
+static int kevent_poll_dequeue(struct kevent *k);
+static int kevent_poll_callback(struct kevent *k);
+
+static int kevent_poll_wait_callback(wait_queue_t *wait, 
+   unsigned mode, int sync, void *key)
+{
+   struct kevent_poll_wait_container *cont = 
+   container_of(wait, struct kevent_poll_wait_container, wait);
+   struct kevent *k = cont->k;
+   struct file *file = k->st->origin;
+   u32 revents;
+
+   revents = file->f_op->poll(file, NULL);
+
+   kevent_storage_ready(k->st, NULL, revents);
+
+   return 0;
+}
+
+static void kevent_poll_qproc(struct file *file, wait_queue_head_t *whead, 
+   struct poll_table_struct *poll_table)
+{
+   struct kevent *k = 
+   container_of(poll_table, struct kevent_poll_ctl, pt)->k;
+   struct kevent_poll_private *priv = k->priv;
+   struct kevent_poll_wait_container *cont;
+   unsigned long flags;
+
+   cont = kmem_cache_alloc(kevent_poll_container_cache, SLAB_KERNEL);
+   if (!cont) {
+   kevent_break(k);
+   return;
+   }
+   
+   cont->k = k;
+   init_waitqueue_func_entry(&cont->wait, kevent_poll_wait_callback);
+   cont->whead = whead;
+
+   spin_lock_irqsave(&priv->container_lock, flags);
+   list_add_tail(&cont->container_entry, &priv->container_list);
+   spin_unlock_irqrestore(&priv->container_lock, flags);
+
+   add_wait_queue(whead, &cont->wait);
+}
+
+static int kevent_poll_enqueue(struct kevent *k)
+{
+   struct file *file;
+   int err, ready = 0;
+   unsigned int revents;
+   struct kevent_poll_ctl ctl;
+   struct kevent_poll_private *priv;
+
+   file = fget(k->event.id.raw[0]);
+   if (!file)
+   return -ENODEV;
+
+   err = -EINVAL;
+   if (!file->f_op || !file->f_op->poll)
+   goto err_out_fput;
+
+   err = -ENOMEM;
+   priv = kmem_cache_alloc(kevent_poll_priv_cache, SLAB_KERNEL);
+   if (!priv)
+   goto err_out_fput;
+
+   spin_lock_init(&priv->container_lock);
+   INIT_LIST_HEAD(&priv->container_list);
+
+   k->priv = priv;
+
+   ctl.k = k;
+   init_poll_funcptr(&ctl.pt, &kevent_poll_qproc);
+
+   err = kevent_storage_enqueue(&file->st, k);
+   if (err)
+   goto err_out_free;
+
+   revents = file->f_op->poll(file, &ctl.pt);
+   if (revents & k->event.event) {
+   ready = 1;
+   kevent_poll_dequeue(k);
+   }
+   
+   return ready;
+
+err_out_free:
+   kmem_cache_free(kevent_poll_priv_cache, priv);
+err_out_fput:
+   fput(file);
+   return err;
+}
+
+static int kevent_poll_dequeue(struct kevent *k)
+{
+   struct file *file = k->st->origin;
+   struct kevent_poll_private *priv = k->priv;
+   struct kevent_poll_wait_container *w, *n;
+   unsigned long flags;
+
+

Re: [take3 4/4] kevent: poll/select() notifications. Timer notifications.

2006-08-03 Thread Eric Dumazet
On Thursday 03 August 2006 11:46, Evgeniy Polyakov wrote:
> poll/select() notifications. Timer notifications.
>
> +++ b/kernel/kevent/kevent_poll.c

> +static int kevent_poll_wait_callback(wait_queue_t *wait,
> + unsigned mode, int sync, void *key)
> +{
> + struct kevent_poll_wait_container *cont =
> + container_of(wait, struct kevent_poll_wait_container, wait);
> + struct kevent *k = cont->k;
> + struct file *file = k->st->origin;
> + unsigned long flags;
> + u32 revents, event;
> +
> + revents = file->f_op->poll(file, NULL);
> + spin_lock_irqsave(&k->ulock, flags);
> + event = k->event.event;
> + spin_unlock_irqrestore(&k->ulock, flags);

Not sure why you take a spinlock just to read a u32

Eric
-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [take3 4/4] kevent: poll/select() notifications. Timer notifications.

2006-08-03 Thread Evgeniy Polyakov
On Thu, Aug 03, 2006 at 11:43:02AM +0200, Eric Dumazet ([EMAIL PROTECTED]) 
wrote:
> On Thursday 03 August 2006 11:46, Evgeniy Polyakov wrote:
> > poll/select() notifications. Timer notifications.
> >
> > +++ b/kernel/kevent/kevent_poll.c
> 
> > +static int kevent_poll_wait_callback(wait_queue_t *wait,
> > +   unsigned mode, int sync, void *key)
> > +{
> > +   struct kevent_poll_wait_container *cont =
> > +   container_of(wait, struct kevent_poll_wait_container, wait);
> > +   struct kevent *k = cont->k;
> > +   struct file *file = k->st->origin;
> > +   unsigned long flags;
> > +   u32 revents, event;
> > +
> > +   revents = file->f_op->poll(file, NULL);
> > +   spin_lock_irqsave(&k->ulock, flags);
> > +   event = k->event.event;
> > +   spin_unlock_irqrestore(&k->ulock, flags);
> 
> Not sure why you take a spinlock just to read a u32

You are right, it is not needed there.
Thank you.

> Eric

-- 
Evgeniy Polyakov
-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html