[systemd-devel] [RFC]Introduce workqueue: a queue-based MT framework

Chen Jie chenj at lemote.com
Sat Jan 7 22:10:23 PST 2012


Hi all,

The patch is aimed to introduce a MultiThread framework into systemd,
to overcome some situations like:
http://cgit.freedesktop.org/systemd/systemd/commit/?id=cbd37330bcd039587121a767280fc9fee597af6e
(http://lists.freedesktop.org/archives/systemd-devel/2011-December/004098.html)

IMHO, since some syscall can't be made asynchronously, put these block
calls in separated threads will make sense.
I guess it could be used in init 1(limitedly), and in varies utilities
shipped with systemd.

The basic idea was borrowed from libdispatch: submit works to proper
queues, the library will initiate proper threads to process works
automatically.

Here, the patch introduce three kinds of workqueue:
* global concurrent queue:
At most DEFAULT_WORK_QUEUE_WIDTH threads will work on the queue, each
thread will drain and process one work from concurrent_queue each
time.

* global main queue:
The main thread handles works in this queue, its typical usage will be like:
        /* In main thread */
        while (true) {
                r = work_queue_run_main_queue(0 /* timeout */);
                if (r)
                        break;
        }

* private queues: these queues are created by work_queue_new(), and
each one is backed by one thread of its own.

A work can be submitted to a queue though: work_queue_add():
int work_queue_add(WorkQueue *q, WorkFunc work, void *data,
WorkDoneNotify notify);

WorkFunc will be invoked in the thread, when it's done, the work will
be sent to main queue -- notify will be invoked there, in other words,
notify will run in main thread.

To avoid one concurrent job occupies too many threads(submit lots of
works to concurrent queue) and starve other jobs, 'bucket' is
introduced:
* bucket is a queue-like object, most queue methods also work for it
(e.g. work_queue_add...)
* works submitted to buckets will then be redirected to concurrent queue.
* bucket is created by WorkQueue *work_bucket_new(const char *name,

        int maxsize, int width);
  -- @width specifies the max num of threads that can be occupied by the bucket

To simulate a ring buffer like behavior(which can be useful in log
application), work_queue_add_rewind() is introduced -- when the queue
is full, it will drop the 'oldest work' and then append a new one.

To make things simple, all public functions should be called in main thread.

Any idea? please comment.



Regards,
-- Chen Jie
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-Add-work-queue-a-queue-based-Multi-Threads-framework.patch
Type: text/x-patch
Size: 43224 bytes
Desc: not available
URL: <http://lists.freedesktop.org/archives/systemd-devel/attachments/20120108/e70dffbb/attachment-0001.bin>


More information about the systemd-devel mailing list