diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2016-12-09 14:19:03 +0100 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2017-01-10 09:53:34 +0100 |
commit | 75b706fde4cbf82bcd41a1cec319778aa0f8eb2d (patch) | |
tree | ea39a351a1f6337b5a5dd6036314693adef5ffe6 /freebsd/sys/kern/subr_taskqueue.c | |
parent | VMSTAT(8): Port to RTEMS (diff) | |
download | rtems-libbsd-75b706fde4cbf82bcd41a1cec319778aa0f8eb2d.tar.bz2 |
Update to FreeBSD head 2016-12-10
Git mirror commit 80c55f08a05ab3b26a73b226ccb56adc3122a55c.
Diffstat (limited to 'freebsd/sys/kern/subr_taskqueue.c')
-rw-r--r-- | freebsd/sys/kern/subr_taskqueue.c | 28 |
1 files changed, 27 insertions, 1 deletions
diff --git a/freebsd/sys/kern/subr_taskqueue.c b/freebsd/sys/kern/subr_taskqueue.c index 8580e8fc..5ef8683c 100644 --- a/freebsd/sys/kern/subr_taskqueue.c +++ b/freebsd/sys/kern/subr_taskqueue.c @@ -89,6 +89,7 @@ struct taskqueue { #define TQ_FLAGS_UNLOCKED_ENQUEUE (1 << 2) #define DT_CALLOUT_ARMED (1 << 0) +#define DT_DRAIN_IN_PROGRESS (1 << 1) #ifndef __rtems__ #define TQ_LOCK(tq) \ @@ -334,7 +335,11 @@ taskqueue_enqueue_timeout(struct taskqueue *queue, #endif /* __rtems__ */ timeout_task->q = queue; res = timeout_task->t.ta_pending; - if (ticks == 0) { + if (timeout_task->f & DT_DRAIN_IN_PROGRESS) { + /* Do nothing */ + TQ_UNLOCK(queue); + res = -1; + } else if (ticks == 0) { taskqueue_enqueue_locked(queue, &timeout_task->t); /* The lock is released inside. */ } else { @@ -598,8 +603,24 @@ taskqueue_drain_timeout(struct taskqueue *queue, struct timeout_task *timeout_task) { + /* + * Set flag to prevent timer from re-starting during drain: + */ + TQ_LOCK(queue); + KASSERT((timeout_task->f & DT_DRAIN_IN_PROGRESS) == 0, + ("Drain already in progress")); + timeout_task->f |= DT_DRAIN_IN_PROGRESS; + TQ_UNLOCK(queue); + callout_drain(&timeout_task->c); taskqueue_drain(queue, &timeout_task->t); + + /* + * Clear flag to allow timer to re-start: + */ + TQ_LOCK(queue); + timeout_task->f &= ~DT_DRAIN_IN_PROGRESS; + TQ_UNLOCK(queue); } static void @@ -666,6 +687,11 @@ _taskqueue_start_threads(struct taskqueue **tqp, int count, int pri, } else tq->tq_tcount++; } + if (tq->tq_tcount == 0) { + free(tq->tq_threads, M_TASKQUEUE); + tq->tq_threads = NULL; + return (ENOMEM); + } #ifndef __rtems__ for (i = 0; i < count; i++) { if (tq->tq_threads[i] == NULL) |