On Thu, 2008-06-12 at 21:44 +0400, Oleg Nesterov wrote:
Speedups are always nice ;-), but the below also gets us there.
Yes, along those lines.
you can call xxx a flush_context and create an interface like:
int queue_work_contex(struct workqueue_struct *wq,
struct flush_context *fc, struct work_struct *work)
{
work->context = fc;
return queue_work(wq, work);
}
void flush_workqueue_context(struct workqueue_strucy *wq, t
struct flush_context *fc)
{
if (atomic_read(&context->count))
wait_for_completion(&fc->completion);
/* except that the above is racy, wait_event() comes to mind */
}
of course run_workqueue() would then need to be augmented with something
like:
context = work->context;
...
f(work);
...
if (context && atomic_dec_and_test(&context->count))
complete(&context->done);
making all this PI savvy for -rt is going to be fun though.. I guess we
can just queue a normal barrier of the flusher's priority, and cancel it
once we complete.. hey - that doesn't sound hard at all :-)
also, I seem to have quitely ignored the fact that struct work doesn't
have the context pointer, and growing it unconditionally like this isn't
nice - hummm,. perhaps we have a bit left in data and can signify a
larger struct work_struct.. ?
--