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

Chen Jie chenj at lemote.com
Thu Jan 12 18:51:00 PST 2012


Hi,

The second version of the patch, changes since V1:
1. Handle barrier workitem without leaving lock protected area
   to avoid some race conditions with work_queue_flush
2. Add a cancel method of WorkItem. The cancel method if set
   will be invoked in the main thread when the head WorkItem
   needs to be freed in work_queue_add_rewind()(when the queue is full).

Also I wonder whether it can find its path to libabc -- with the
patch, the client doesn't need to deal with pthread stuff, just
operates on queues.

2012/1/8 Chen Jie <chenj at lemote.com>
>
> 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: Add-work-queue-a-queue-based-Multi-Threads-framework-V2.patch
Type: text/x-patch
Size: 44591 bytes
Desc: not available
URL: <http://lists.freedesktop.org/archives/systemd-devel/attachments/20120113/4fae8b79/attachment-0001.bin>


More information about the systemd-devel mailing list