﻿id	summary	reporter	owner	description	type	status	priority	milestone	component	resolution	keywords	cc
37	Add a Worker thread API	anonymous	becoulet	"We sometimes use a worker-thread-like service. Each time it is recreated from scratch. Let's add an API for this.

Here is such a proposal:

worker.h header:

{{{
#!c

/**
 @this is an item pushable to a worker queue.
 */
typedef CONTAINER_ENTRY_TYPE(CLIST) worker_entry_t;

/**
 @this is a worker function prototype macro.
 @csee worker_func_t
*/
#define WORKER_FUNC(n) void (n)(struct worker_thread_s *worker, \
                                worker_entry_t *entry, \
                                void *priv)

/**
 @this is a worker function type definition.

 Function must return once it handled the reason of wakeup.

 @param worker Worker thread context, may be used to stop self
 @param entry Item to work on
 @param priv Private data passed on init
 */
typedef WORKER_FUNC(worker_func_t);

void worker_thread_init(struct worker_thread_s*,
                        void *stack,
                        size_t stack_size,
                        worker_func_t *func,
                        void *func_priv);

/**
 @this runs a context, i.e. this makes the worker ready for wake
 up. This waits until a work is pushed.
 */
void worker_thread_start(struct worker_thread_s*);

/**
 @this kills the context, but waits for completion of all actions
 pending.
 */
void worker_thread_stop(struct worker_thread_s*);

/**
 @this makes the worker function to be called once. Multiple
 calls to this function yields multiple consecutive calls to
 the worker function.

 @param item The item to pass to the woken-up function
 @returns -EAGAIN if the thread is not started yet, -EINVAL if the
          thread already got killed, 0 if OK.
 */
error_t worker_thread_wakeup(struct worker_thread_s*, worker_entry_t *entry);
}}}

worker.c file content

{{{
#!c

struct worker_base_s {
  worker_entry_t entry;
};

CONTAINER_TYPE(worker_queue, CLIST, struct worker_base_s, entry);
CONTAINER_FUNC(...)

struct worker_thread_s
{
    worker_queue_root_t queue;
    
    struct sched_context_s context;
    bool_t killed;
    lock_t lock;
    worker_func_t *func;
    void *func_priv;
};

...
{
  worker_queue_push(&wt.queue, (worker_queue_item_t*)entry)
}

}}}

Usage example:

{{{
#!c

struct myjob_s
{
  ... my stuff ...
  worker_entry_t entry;
};

CONTAINER_TYPE(myworker_queue, CLIST, struct myjob_s, entry);

void foo()
{
  static struct myjob_s job;

  worker_thread_wakeup(worker, &job.entry);
}

static WORKER_FUNC(myfunc)
{
  struct myjob_s *job = myworker_queue_item(entry);
}
}}}
"	enhancement	new	minor	Preemptive scheduler usage	mutek			
