Skip to content

Latest commit

 

History

History
318 lines (225 loc) · 7.16 KB

api.md

File metadata and controls

318 lines (225 loc) · 7.16 KB

Features

mthpc supports the following features.

Thread framework

#include <mthpc/thread.h>

Declaration

Write your thread initialization and body functions with the following prototype . And, delcare the thread group with the MTHPC_DECLARE_THREAD_GROUP macro.

void func(struct mthpc_thread_group *th);
MTHPC_DECLARE_THREAD_GROUP(name, number_of_thread, init_func, body_func, args);

After that, with mutiple thread groups, you can also put it all together with the macro, MTHPC_DECLARE_THREAD_CLUSTER.

MTHPC_DECLARE_THREAD_CLUSTER(name, &groupA, &groupB, ...);

Note that all the object declarations are static size, which means they are not runtime-sized.

APIs

Run the thread group/cluster with the blocking until all the threads finished. Before executing the body function, all of the threads will wait until all the initializations have been done. This kind of synchronization is cluster-level. Moreover, to let the object become async (non-blocking, auto-join) you can use _async_ function.

void mthpc_thread_run(&threads /* group or cluster */);
void mthpc_thread_async_run(&threads /* group or cluster */);
void mthpc_thread_async_wait(&threads /* group or cluster */);

Examples

Workqueue

#include <mthpc/workqueue.h>

Declaration

void work_func(struct mthpc_work *work);
MTHPC_DECLARE_WORK(name, work_func, args);

APIs

To queue the work, use the following functions.

MTHPC_INIT_WORK(struct mthpc_work *work, name, work_func, private);
int mthpc_schedule_work_on(int cpu, struct mthpc_work *work);
int mthpc_queue_work(struct mthpc_work *work);

You can also print out the information of the work.

void mthpc_dump_work(struct mthpc_work *work)

Examples

Centralized barrier

#include <mthpc/centralized_barrier.h>

Declaration

MTHPC_DEFINE_BARRIER(name);
struct mthpc_barrier name = MTHPC_BARRIER_INIT;

APIs

Add the barrier to the location you want with the number of the thread will be blocked by this barrier.

void mthpc_barrier_init(struct mthpc_barrier *b);
void mthpc_centralized_barrier(struct mthpc_barrier *b, size_t n);

Wait for completion

#include <mthpc/completion.h>

Declaration

MTHPC_DECLARE_COMPLETION(name, nr);
struct completion name = MTHPC_COMPLETION_INIT(nr);

APIs

void mthpc_completion_init(struct mthpc_completion *completion,
                           unsigned long nr);
void mthpc_complete(struct mthpc_completion *completion);
void mthpc_wait_for_completion(struct mthpc_completion *completion);

Read-Copy Update (RCU)

#include <mthpc/rcu.h>
#include <mthpc/rculist.h>

APIs

Before requiring the RCU read lock you can first initalize the RCU with void mthpc_rcu_thread_init(void). In sometime, if you make sure that the thread will never use the RCU again, you can call void mthpc_rcu_thread_exit(void) to release RCU resource of that thread.

void mthpc_rcu_read_lock(void);
void mthpc_rcu_read_unlock(void);

mthpc_rcu_replace_pointer(p, new);
mthpc_rcu_dereference(p);

void mthpc_synchronize_rcu(void);
void mthpc_synchronize_rcu_all(void);

Examples

Scoped lock

#include <mthpc/scoped_lock.h>

APIs

/* For lock_type, see the following description. */
void mthpc_scoped_lock(lock_type);
void mthpc_scoped_lock(lock_type, lock_ptr);

Scoped lock support following lock types:

  • spinlock
  • rcu

Examples

Safe pointer

#include <mthpc/safe_ptr.h>

It is an atomic shared_ptr. Support the Sparse checking.

Declaration

/* Create the safe ptr with raw pointer and their dtor function */
MTHPC_DEFINE_SAFE_PTR(name, new_data, dtor);
/* Create the empty safe ptr */
MTHPC_DECLARE_SAFE_PTR(name);
/* Create the safe ptr from the borrow/move opeations */
MTHPC_DECLARE_SAFE_PTR_FROM_BORROW(type, name, struct mthpc_safe_ptr __mthpc_brw *brw_sp);
MTHPC_DECLARE_SAFE_PTR_FROM_MOVE(type, name, struct mthpc_safe_ptr __mthpc_move *move_sp);

APIs

/* Store the new pointer to this safe pointer */
void mthpc_safe_ptr_store(struct mthpc_safe_ptr *sp, void *new_data,
                          void (*dtor)(void *));
/* Load the context of the protected pointer */
void *mthpc_safe_ptr_load(struct mthpc_safe_ptr *sp);
/* cmpxchg the context of the protected pointer */
int mthpc_safe_ptr_cmpxhg(struct mthpc_safe_ptr *sp, void *expected,
                          void *desired);

/* Debug */
void mthpc_dump_safe_ptr(struct mthpc_safe_ptr *sp);

To borrow the safe data to another function, use the borrow methods. Every borrowed safe pointer has the __mthpc_brw attribute. This means that the user cannot directly dereference the borrowed safe pointer.

/* borrow the safe pointer to other function. */
function(mthpc_borrow_safe_ptr(safe_ptr));

void function(struct mthpc_safe_ptr __mthpc_brw *borrow_ptr)
{
    MTHPC_DECLARE_SAFE_PTR_FROM_BORROW(name, borrow_ptr);

    ...
}

However, if you want to transfer the ownership of safe pointer to other function, use the move methods.

function(mthpc_move_safe_ptr(safe_ptr));

void function(struct mthpc_safe_ptr __mthpc_move *move_ptr)
{
    MTHPC_DECLARE_SAFE_PTR_FROM_MOVE(name, move_ptr);

    ...
}

Examples

Taskflow

#include <mthpc/taskflow.h>

Declaration

Use mthpc_taskflow_create() to create the task framework. And, use mthpc_task_create() to add the new task.

struct mthpc_taskflow *mthpc_taskflow_create(void);
struct mthpc_task *mthpc_task_create(struct mthpc_taskflow *tf,
                                     void (*func)(void *arg), void *arg);

struct mthpc_task *mthpc_sub_task_create(struct mthpc_task *task,
                                         void (*func)(void *arg), void *arg);

APIs

Use precede() and succeed() functions to decide which task run first. After that, use await() to run all the tasks in the framework.

void mthpc_taskflow_precede(task, forward_tasks...);
void mthpc_taskflow_succeed(task, backward_tasks...);
int mthpc_taskflow_await(struct mthpc_taskflow *tf);

Examples


Other features

#include <mthpc/spinlock.h>
#include <mthpc/util.h>
#include <mthpc/list.h>
#include <mthpc/debug.h>
#include <mthpc/print.h>
#include <mthpc/guards.h>

Future works

  • hash table
  • mlrcu