Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/external/bsd/common/linux Factor out waiting for current...
details: https://anonhg.NetBSD.org/src/rev/f72152128198
branches: trunk
changeset: 366363:f72152128198
user: riastradh <riastradh%NetBSD.org@localhost>
date: Mon Aug 27 15:04:32 2018 +0000
description:
Factor out waiting for current work.
diffstat:
sys/external/bsd/common/linux/linux_work.c | 44 +++++++++++++++++++----------
1 files changed, 29 insertions(+), 15 deletions(-)
diffs (93 lines):
diff -r 9d67bad4ebe4 -r f72152128198 sys/external/bsd/common/linux/linux_work.c
--- a/sys/external/bsd/common/linux/linux_work.c Mon Aug 27 15:04:19 2018 +0000
+++ b/sys/external/bsd/common/linux/linux_work.c Mon Aug 27 15:04:32 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: linux_work.c,v 1.32 2018/08/27 15:04:19 riastradh Exp $ */
+/* $NetBSD: linux_work.c,v 1.33 2018/08/27 15:04:32 riastradh Exp $ */
/*-
* Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: linux_work.c,v 1.32 2018/08/27 15:04:19 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: linux_work.c,v 1.33 2018/08/27 15:04:32 riastradh Exp $");
#include <sys/types.h>
#include <sys/atomic.h>
@@ -65,6 +65,8 @@
struct workqueue_struct *);
static void release_work(struct work_struct *,
struct workqueue_struct *);
+static void wait_for_current_work(struct work_struct *,
+ struct workqueue_struct *);
static void dw_callout_init(struct workqueue_struct *,
struct delayed_work *);
static void dw_callout_destroy(struct workqueue_struct *,
@@ -496,13 +498,9 @@
} else if (wq->wq_current_work == work) {
/*
* It has already begun execution, so it's too late to
- * cancel now. Wait for it to complete. Don't wait
- * more than one generation in case it gets requeued.
+ * cancel now. Wait for it to complete.
*/
- uint64_t gen = wq->wq_gen;
- do {
- cv_wait(&wq->wq_cv, &wq->wq_lock);
- } while (wq->wq_current_work == work && wq->wq_gen == gen);
+ wait_for_current_work(work, wq);
cancelled_p = false;
} else {
/*
@@ -516,6 +514,27 @@
out: return cancelled_p;
}
+
+/*
+ * wait_for_current_work(work, wq)
+ *
+ * wq must be currently executing work. Wait for it to finish.
+ */
+static void
+wait_for_current_work(struct work_struct *work, struct workqueue_struct *wq)
+{
+ uint64_t gen;
+
+ KASSERT(mutex_owned(&wq->wq_lock));
+ KASSERT(work->work_queue == wq);
+ KASSERT(wq->wq_current_work == work);
+
+ /* Wait only one generation in case it gets requeued quickly. */
+ gen = wq->wq_gen;
+ do {
+ cv_wait(&wq->wq_cv, &wq->wq_lock);
+ } while (wq->wq_current_work == work && wq->wq_gen == gen);
+}
/*
* Delayed work
@@ -993,19 +1012,14 @@
/*
* Too late, it's already running.
* First, make sure it's not requeued.
- * Then wait for it to complete, at
- * most one generation.
+ * Then wait for it to complete.
*/
- uint64_t gen = wq->wq_gen;
if (wq->wq_requeued) {
TAILQ_REMOVE(&wq->wq_queue, &dw->work,
work_entry);
wq->wq_requeued = false;
}
- do {
- cv_wait(&wq->wq_cv, &wq->wq_lock);
- } while (wq->wq_current_work == &dw->work &&
- wq->wq_gen == gen);
+ wait_for_current_work(&dw->work, wq);
cancelled_p = false;
} else {
/* Got in before it started. Remove it. */
Home |
Main Index |
Thread Index |
Old Index