From owner-svn-src-all@freebsd.org Wed Nov 28 16:52:43 2018 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id B0EBB1136060; Wed, 28 Nov 2018 16:52:43 +0000 (UTC) (envelope-from markj@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 574037CA83; Wed, 28 Nov 2018 16:52:43 +0000 (UTC) (envelope-from markj@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 38F91532E; Wed, 28 Nov 2018 16:52:43 +0000 (UTC) (envelope-from markj@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id wASGqh0b093943; Wed, 28 Nov 2018 16:52:43 GMT (envelope-from markj@FreeBSD.org) Received: (from markj@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id wASGqg2O093935; Wed, 28 Nov 2018 16:52:42 GMT (envelope-from markj@FreeBSD.org) Message-Id: <201811281652.wASGqg2O093935@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: markj set sender to markj@FreeBSD.org using -f From: Mark Johnston Date: Wed, 28 Nov 2018 16:52:42 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org Subject: svn commit: r341152 - in stable/12: share/man/man9 sys/cddl/compat/opensolaris/kern sys/kern sys/sys X-SVN-Group: stable-12 X-SVN-Commit-Author: markj X-SVN-Commit-Paths: in stable/12: share/man/man9 sys/cddl/compat/opensolaris/kern sys/kern sys/sys X-SVN-Commit-Revision: 341152 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Rspamd-Queue-Id: 574037CA83 X-Spamd-Result: default: False [1.25 / 15.00]; local_wl_from(0.00)[FreeBSD.org]; NEURAL_SPAM_LONG(0.49)[0.488,0]; NEURAL_SPAM_MEDIUM(0.25)[0.254,0]; ASN(0.00)[asn:11403, ipnet:2610:1c1:1::/48, country:US]; NEURAL_SPAM_SHORT(0.50)[0.504,0] X-Rspamd-Server: mx1.freebsd.org X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 28 Nov 2018 16:52:43 -0000 Author: markj Date: Wed Nov 28 16:52:41 2018 New Revision: 341152 URL: https://svnweb.freebsd.org/changeset/base/341152 Log: MFC r340730, r340731: Add taskqueue_quiesce(9) and use it to implement taskq_wait(). PR: 227784 Modified: stable/12/share/man/man9/Makefile stable/12/share/man/man9/taskqueue.9 stable/12/sys/cddl/compat/opensolaris/kern/opensolaris_taskq.c stable/12/sys/kern/subr_taskqueue.c stable/12/sys/sys/taskqueue.h Directory Properties: stable/12/ (props changed) Modified: stable/12/share/man/man9/Makefile ============================================================================== --- stable/12/share/man/man9/Makefile Wed Nov 28 16:51:11 2018 (r341151) +++ stable/12/share/man/man9/Makefile Wed Nov 28 16:52:41 2018 (r341152) @@ -2053,6 +2053,7 @@ MLINKS+=taskqueue.9 TASK_INIT.9 \ taskqueue.9 TASKQUEUE_FAST_DEFINE_THREAD.9 \ taskqueue.9 taskqueue_free.9 \ taskqueue.9 taskqueue_member.9 \ + taskqueue.9 taskqueue_quiesce.9 \ taskqueue.9 taskqueue_run.9 \ taskqueue.9 taskqueue_set_callback.9 \ taskqueue.9 taskqueue_start_threads.9 \ Modified: stable/12/share/man/man9/taskqueue.9 ============================================================================== --- stable/12/share/man/man9/taskqueue.9 Wed Nov 28 16:51:11 2018 (r341151) +++ stable/12/share/man/man9/taskqueue.9 Wed Nov 28 16:52:41 2018 (r341152) @@ -28,7 +28,7 @@ .\" .\" $FreeBSD$ .\" -.Dd July 30, 2017 +.Dd November 21, 2018 .Dt TASKQUEUE 9 .Os .Sh NAME @@ -94,6 +94,8 @@ struct timeout_task; .Ft void .Fn taskqueue_drain_all "struct taskqueue *queue" .Ft void +.Fn taskqueue_quiesce "struct taskqueue *queue" +.Ft void .Fn taskqueue_block "struct taskqueue *queue" .Ft void .Fn taskqueue_unblock "struct taskqueue *queue" @@ -298,6 +300,12 @@ do not extend the wait time of and may complete after .Fn taskqueue_drain_all returns. +The +.Fn taskqueue_quiesce +function is used to wait for the queue to become empty and for all +running tasks to finish. +To avoid blocking indefinitely, the caller must ensure by some mechanism +that tasks will eventually stop being posted to the queue. .Pp The .Fn taskqueue_block Modified: stable/12/sys/cddl/compat/opensolaris/kern/opensolaris_taskq.c ============================================================================== --- stable/12/sys/cddl/compat/opensolaris/kern/opensolaris_taskq.c Wed Nov 28 16:51:11 2018 (r341151) +++ stable/12/sys/cddl/compat/opensolaris/kern/opensolaris_taskq.c Wed Nov 28 16:52:41 2018 (r341152) @@ -171,11 +171,11 @@ taskq_dispatch_ent(taskq_t *tq, task_func_t func, void void taskq_wait(taskq_t *tq) { - taskqueue_drain_all(tq->tq_queue); + taskqueue_quiesce(tq->tq_queue); } void taskq_wait_id(taskq_t *tq, taskqid_t id) { - taskq_wait(tq); + taskqueue_drain_all(tq->tq_queue); } Modified: stable/12/sys/kern/subr_taskqueue.c ============================================================================== --- stable/12/sys/kern/subr_taskqueue.c Wed Nov 28 16:51:11 2018 (r341151) +++ stable/12/sys/kern/subr_taskqueue.c Wed Nov 28 16:52:41 2018 (r341152) @@ -346,13 +346,13 @@ taskqueue_task_nop_fn(void *context, int pending) * have begun execution. Tasks queued during execution of * this function are ignored. */ -static void +static int taskqueue_drain_tq_queue(struct taskqueue *queue) { struct task t_barrier; if (STAILQ_EMPTY(&queue->tq_queue)) - return; + return (0); /* * Enqueue our barrier after all current tasks, but with @@ -372,6 +372,7 @@ taskqueue_drain_tq_queue(struct taskqueue *queue) */ while (t_barrier.ta_pending != 0) TQ_SLEEP(queue, &t_barrier, &queue->tq_mutex, PWAIT, "-", 0); + return (1); } /* @@ -379,13 +380,13 @@ taskqueue_drain_tq_queue(struct taskqueue *queue) * complete. Tasks that begin execution during the execution * of this function are ignored. */ -static void +static int taskqueue_drain_tq_active(struct taskqueue *queue) { struct taskqueue_busy tb_marker, *tb_first; if (TAILQ_EMPTY(&queue->tq_active)) - return; + return (0); /* Block taskq_terminate().*/ queue->tq_callouts++; @@ -412,6 +413,7 @@ taskqueue_drain_tq_active(struct taskqueue *queue) queue->tq_callouts--; if ((queue->tq_flags & TQ_FLAGS_ACTIVE) == 0) wakeup_one(queue->tq_threads); + return (1); } void @@ -582,8 +584,8 @@ taskqueue_drain_all(struct taskqueue *queue) WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL, __func__); TQ_LOCK(queue); - taskqueue_drain_tq_queue(queue); - taskqueue_drain_tq_active(queue); + (void)taskqueue_drain_tq_queue(queue); + (void)taskqueue_drain_tq_active(queue); TQ_UNLOCK(queue); } @@ -609,6 +611,20 @@ taskqueue_drain_timeout(struct taskqueue *queue, */ TQ_LOCK(queue); timeout_task->f &= ~DT_DRAIN_IN_PROGRESS; + TQ_UNLOCK(queue); +} + +void +taskqueue_quiesce(struct taskqueue *queue) +{ + int ret; + + TQ_LOCK(queue); + do { + ret = taskqueue_drain_tq_queue(queue); + if (ret == 0) + ret = taskqueue_drain_tq_active(queue); + } while (ret != 0); TQ_UNLOCK(queue); } Modified: stable/12/sys/sys/taskqueue.h ============================================================================== --- stable/12/sys/sys/taskqueue.h Wed Nov 28 16:51:11 2018 (r341151) +++ stable/12/sys/sys/taskqueue.h Wed Nov 28 16:52:41 2018 (r341152) @@ -93,6 +93,7 @@ void taskqueue_drain(struct taskqueue *queue, struct t void taskqueue_drain_timeout(struct taskqueue *queue, struct timeout_task *timeout_task); void taskqueue_drain_all(struct taskqueue *queue); +void taskqueue_quiesce(struct taskqueue *queue); void taskqueue_free(struct taskqueue *queue); void taskqueue_run(struct taskqueue *queue); void taskqueue_block(struct taskqueue *queue);