Opened 14 years ago

Last modified 14 years ago

#37 new enhancement

Add a Worker thread API

Reported by: anonymous Owned by: becoulet
Priority: minor Milestone: Preemptive scheduler usage
Component: mutek Keywords:
Cc:

Description (last modified by 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:

/**
 @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

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:

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);
}

Change History (6)

comment:1 Changed 14 years ago by Nicolas Pouillon

Component: Build systemmutek
Description: modified (diff)
Owner: changed from Nicolas Pouillon to becoulet
Priority: majorminor
Type: defectenhancement

comment:2 Changed 14 years ago by Nicolas Pouillon

Who does the allocation of stack space ? Probably we must pass it to the creation...

comment:3 Changed 14 years ago by Nicolas Pouillon

Milestone: Preempt merge

comment:4 in reply to:  description Changed 14 years ago by gut

Why not include an API to delay some work from irq handlers ? It could be helpful for RT purposes.

comment:5 Changed 14 years ago by Nicolas Pouillon

Description: modified (diff)

comment:6 Changed 14 years ago by becoulet

Description: modified (diff)
Note: See TracTickets for help on using tickets.