svn commit: r221059 - in head/sys: kern sys

2011-04-26 Thread Konstantin Belousov
Author: kib
Date: Tue Apr 26 11:39:56 2011
New Revision: 221059
URL: http://svn.freebsd.org/changeset/base/221059

Log:
  Implement the delayed task execution extension to the taskqueue
  mechanism. The caller may specify a timeout in ticks after which the
  task will be scheduled.
  
  Sponsored by: The FreeBSD Foundation
  Reviewed by:  jeff, jhb
  MFC after:1 month

Added:
  head/sys/sys/_callout.h
 - copied, changed from r221058, head/sys/sys/callout.h
Modified:
  head/sys/kern/subr_taskqueue.c
  head/sys/sys/callout.h
  head/sys/sys/taskqueue.h

Modified: head/sys/kern/subr_taskqueue.c
==
--- head/sys/kern/subr_taskqueue.c  Tue Apr 26 10:02:15 2011
(r221058)
+++ head/sys/kern/subr_taskqueue.c  Tue Apr 26 11:39:56 2011
(r221059)
@@ -61,12 +61,15 @@ struct taskqueue {
int tq_tcount;
int tq_spin;
int tq_flags;
+   int tq_callouts;
 };
 
 #defineTQ_FLAGS_ACTIVE (1  0)
 #defineTQ_FLAGS_BLOCKED(1  1)
 #defineTQ_FLAGS_PENDING(1  2)
 
+#defineDT_CALLOUT_ARMED(1  0)
+
 #defineTQ_LOCK(tq) 
\
do {\
if ((tq)-tq_spin)  \
@@ -83,6 +86,17 @@ struct taskqueue {
mtx_unlock((tq)-tq_mutex);\
} while (0)
 
+void
+_timeout_task_init(struct taskqueue *queue, struct timeout_task *timeout_task,
+int priority, task_fn_t func, void *context)
+{
+
+   TASK_INIT(timeout_task-t, priority, func, context);
+   callout_init_mtx(timeout_task-c, queue-tq_mutex, 0);
+   timeout_task-q = queue;
+   timeout_task-f = 0;
+}
+
 static __inline int
 TQ_SLEEP(struct taskqueue *tq, void *p, struct mtx *m, int pri, const char *wm,
 int t)
@@ -129,7 +143,7 @@ static void
 taskqueue_terminate(struct thread **pp, struct taskqueue *tq)
 {
 
-   while (tq-tq_tcount  0) {
+   while (tq-tq_tcount  0 || tq-tq_callouts  0) {
wakeup(tq);
TQ_SLEEP(tq, pp, tq-tq_mutex, PWAIT, taskqueue_destroy, 0);
}
@@ -143,26 +157,24 @@ taskqueue_free(struct taskqueue *queue)
queue-tq_flags = ~TQ_FLAGS_ACTIVE;
taskqueue_terminate(queue-tq_threads, queue);
KASSERT(TAILQ_EMPTY(queue-tq_active), (Tasks still running?));
+   KASSERT(queue-tq_callouts == 0, (Armed timeout tasks));
mtx_destroy(queue-tq_mutex);
free(queue-tq_threads, M_TASKQUEUE);
free(queue, M_TASKQUEUE);
 }
 
-int
-taskqueue_enqueue(struct taskqueue *queue, struct task *task)
+static int
+taskqueue_enqueue_locked(struct taskqueue *queue, struct task *task)
 {
struct task *ins;
struct task *prev;
 
-   TQ_LOCK(queue);
-
/*
 * Count multiple enqueues.
 */
if (task-ta_pending) {
task-ta_pending++;
-   TQ_UNLOCK(queue);
-   return 0;
+   return (0);
}
 
/*
@@ -190,9 +202,60 @@ taskqueue_enqueue(struct taskqueue *queu
else
queue-tq_flags |= TQ_FLAGS_PENDING;
 
+   return (0);
+}
+int
+taskqueue_enqueue(struct taskqueue *queue, struct task *task)
+{
+   int res;
+
+   TQ_LOCK(queue);
+   res = taskqueue_enqueue_locked(queue, task);
TQ_UNLOCK(queue);
 
-   return 0;
+   return (res);
+}
+
+static void
+taskqueue_timeout_func(void *arg)
+{
+   struct taskqueue *queue;
+   struct timeout_task *timeout_task;
+
+   timeout_task = arg;
+   queue = timeout_task-q;
+   KASSERT((timeout_task-f  DT_CALLOUT_ARMED) != 0, (Stray timeout));
+   timeout_task-f = ~DT_CALLOUT_ARMED;
+   queue-tq_callouts--;
+   taskqueue_enqueue_locked(timeout_task-q, timeout_task-t);
+}
+
+int
+taskqueue_enqueue_timeout(struct taskqueue *queue,
+struct timeout_task *timeout_task, int ticks)
+{
+   int res;
+
+   TQ_LOCK(queue);
+   KASSERT(timeout_task-q == NULL || timeout_task-q == queue,
+   (Migrated queue));
+   KASSERT(!queue-tq_spin, (Timeout for spin-queue));
+   timeout_task-q = queue;
+   res = timeout_task-t.ta_pending;
+   if (ticks == 0) {
+   taskqueue_enqueue_locked(queue, timeout_task-t);
+   } else {
+   if ((timeout_task-f  DT_CALLOUT_ARMED) != 0) {
+   res++;
+   } else {
+   queue-tq_callouts++;
+   timeout_task-f |= DT_CALLOUT_ARMED;
+   }
+   callout_reset(timeout_task-c, ticks, taskqueue_timeout_func,
+   timeout_task);
+   }
+   TQ_UNLOCK(queue);
+   return (res);
 }
 
 void
@@ -271,6 +334,19 @@ 

Re: svn commit: r221059 - in head/sys: kern sys

2011-04-26 Thread Hans Petter Selasky
On Tuesday 26 April 2011 13:39:56 Konstantin Belousov wrote:
 +   pending = !!callout_stop(timeout_task-c);

pending = (callout_stop(timeout_task-c) != 0);

?

--HPS
___
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to svn-src-all-unsubscr...@freebsd.org


Re: svn commit: r221059 - in head/sys: kern sys

2011-04-26 Thread Kostik Belousov
On Tue, Apr 26, 2011 at 01:44:00PM +0200, Hans Petter Selasky wrote:
 On Tuesday 26 April 2011 13:39:56 Konstantin Belousov wrote:
  +   pending = !!callout_stop(timeout_task-c);
 
 pending = (callout_stop(timeout_task-c) != 0);
 
 ?

This line is about conversion from a boolean value to {0, 1} value set.
If !! construct does not look stylish, then wouldn't we need to go
with
pending = (callout_stop(timeout_task-c) != 0) ? 1 : 0;
instead ?

Feel free to adjust whatever variant you prefer and commit it.


pgpNKu48OtZcN.pgp
Description: PGP signature


Re: svn commit: r221059 - in head/sys: kern sys

2011-04-26 Thread Hans Petter Selasky
On Tuesday 26 April 2011 13:53:33 Kostik Belousov wrote:
 On Tue, Apr 26, 2011 at 01:44:00PM +0200, Hans Petter Selasky wrote:
  On Tuesday 26 April 2011 13:39:56 Konstantin Belousov wrote:
   +   pending = !!callout_stop(timeout_task-c);
  
  pending = (callout_stop(timeout_task-c) != 0);
  
  ?

Hi,

This is just a nit I noticed.

 
 This line is about conversion from a boolean value to {0, 1} value set.
 If !! construct does not look stylish, then wouldn't we need to go
 with
   pending = (callout_stop(timeout_task-c) != 0) ? 1 : 0;
 instead ?

The output from ! is already a boolean and pending is a u_int, so to be 
correct it should be similar to what you suggest. I'm not sure what case 
produce the less amount of code and which the compiler understands the best. 
Probably it does not matter that much.

I was thinking that !! is depreceated, but man style is silent about it.

 Feel free to adjust whatever variant you prefer and commit it.

Ok.

--HPS
___
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to svn-src-all-unsubscr...@freebsd.org