Thread (33 messages) 33 messages, 4 authors, 2021-07-22

Re: [RFC PATCH 06/10] perf workqueue: introduce workqueue struct

From: Riccardo Mancini <hidden>
Date: 2021-07-15 16:50:03
Also in: lkml

Hi Arnaldo,
thanks again for having a look at this patchset!

On Wed, 2021-07-14 at 12:22 -0300, Arnaldo Carvalho de Melo wrote:
Em Tue, Jul 13, 2021 at 02:11:17PM +0200, Riccardo Mancini escreveu:
quoted
This patch adds the workqueue definition, along with simple creation and
destruction functions.
Furthermore, a simple subtest is added.

A workqueue is attached to a pool, on which it executes its workers.
Next patches will introduce workers.

Signed-off-by: Riccardo Mancini <redacted>
<SNIP>
quoted
+
+/**
+ * create_workqueue - create a workqueue associated to @pool
+ *
+ * Only one workqueue can execute on a pool at a time.
+ */
+struct workqueue_struct *create_workqueue(struct threadpool_struct *pool)
I wonder if we should use the exact same kernel signature and not pass a
threadpool, essentially having just one threadpool in tools/perf/ that
is used by create_workqueue(void)?
I wondered the same thing, but I thought that we'd need it to be dynamically
created to prevent spawning threads at the beginning that might not even be
used.
I think this could be a follow-up patch.

Thanks,
Riccardo
quoted
+{
+       int err;
+       struct workqueue_struct *wq = malloc(sizeof(struct
workqueue_struct));
+
+
+       err = pthread_mutex_init(&wq->lock, NULL);
+       if (err)
+               goto out_free_wq;
+
+       err = pthread_cond_init(&wq->idle_cond, NULL);
+       if (err)
+               goto out_destroy_mutex;
+
+       wq->pool = NULL;
+       INIT_LIST_HEAD(&wq->busy_list);
+       INIT_LIST_HEAD(&wq->idle_list);
+
+       INIT_LIST_HEAD(&wq->pending);
+
+       err = pipe(wq->msg_pipe);
+       if (err)
+               goto out_destroy_cond;
+
+       wq->task.fn = worker_thread;
+
+       err = attach_threadpool_to_workqueue(wq, pool);
+       if (err)
+               goto out_destroy_cond;
+
+       wq->status = WORKQUEUE_STATUS__READY;
+
+       return wq;
+
+out_destroy_cond:
+       pthread_cond_destroy(&wq->idle_cond);
+out_destroy_mutex:
+       pthread_mutex_destroy(&wq->lock);
+out_free_wq:
+       free(wq);
+       return NULL;
+}
+
+/**
+ * destroy_workqueue - stop @wq workers and destroy @wq
+ */
+int destroy_workqueue(struct workqueue_struct *wq)
+{
+       int err = 0, ret;
+
+       ret = detach_threadpool_from_workqueue(wq);
+       if (ret) {
+               pr_err("workqueue: error detaching from threadpool.\n");
+               err = -1;
+       }
+
+       ret = pthread_mutex_destroy(&wq->lock);
+       if (ret) {
+               err = -1;
+               pr_err("workqueue: error pthread_mutex_destroy: %s\n",
+                       strerror(errno));
+       }
+
+       ret = pthread_cond_destroy(&wq->idle_cond);
+       if (ret) {
+               err = -1;
+               pr_err("workqueue: error pthread_cond_destroy: %s\n",
+                       strerror(errno));
+       }
+
+       ret = close(wq->msg_pipe[0]);
+       if (ret) {
+               err = -1;
+               pr_err("workqueue: error close msg_pipe[0]: %s\n",
+                       strerror(errno));
+       }
+
+       ret = close(wq->msg_pipe[1]);
+       if (ret) {
+               err = -1;
+               pr_err("workqueue: error close msg_pipe[1]: %s\n",
+                       strerror(errno));
+       }
+
+       free(wq);
+
+       return err;
+}
+
+/**
+ * workqueue_nr_threads - get size of threadpool underlying @wq
+ */
+int workqueue_nr_threads(struct workqueue_struct *wq)
+{
+       return threadpool_size(wq->pool);
+}
diff --git a/tools/perf/util/workqueue/workqueue.h
b/tools/perf/util/workqueue/workqueue.h
new file mode 100644
index 0000000000000000..86ec1d69274f41db
--- /dev/null
+++ b/tools/perf/util/workqueue/workqueue.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __WORKQUEUE_WORKQUEUE_H
+#define __WORKQUEUE_WORKQUEUE_H
+
+#include <stdlib.h>
+#include <sys/types.h>
+#include <linux/list.h>
+#include "threadpool.h"
+
+struct work_struct;
+typedef void (*work_func_t)(struct work_struct *work);
+
+struct work_struct {
+       struct list_head entry;
+       work_func_t func;
+};
+
+struct workqueue_struct;
+
+extern struct workqueue_struct *create_workqueue(struct threadpool_struct
*pool);
+extern int destroy_workqueue(struct workqueue_struct *wq);
+
+extern int workqueue_nr_threads(struct workqueue_struct *wq);
+#endif /* __WORKQUEUE_WORKQUEUE_H */
-- 
2.31.1
  
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help