CNDP  22.08.0
cthread_api.h File Reference
#include <sys/socket.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <cne_cycles.h>
#include <cne_log.h>
#include <cne_branch_prediction.h>

Go to the source code of this file.

Data Structures

struct  cthread_semaattr
 
struct  cthread_mutexattr
 

Macros

#define MUTEX_RECURSIVE_ATTR   0x00000001
 
#define CTHREAD_MAX_KEYS   256
 
#define CTHREAD_DESTRUCTOR_ITERATIONS   4
 
#define CTHREAD_MAX_THREADS   CNE_MAX_THREADS
 
#define CTHREAD_PREALLOC   64
 
#define CNE_DECLARE_PER_CTHREAD(type, name)    extern __typeof__(type) __attribute((section("per_dt"))) per_dt_##name
 
#define CNE_PER_CTHREAD(name)
 

Typedefs

typedef void(* cthread_func_t) (void *)
 
typedef void(* tls_destructor_func) (void *)
 
typedef int(* cthread_cb_t) (struct cthread *c, void *arg, int idx)
 
typedef int(* sched_cb_t) (struct cthread_sched *s, void *arg, int idx)
 

Functions

CNDP_API int cthread_num_schedulers_set (int num)
 
CNDP_API int cthread_active_schedulers (void)
 
CNDP_API void cthread_scheduler_shutdown (int thread)
 
CNDP_API void cthread_scheduler_shutdown_all (void)
 
CNDP_API void cthread_run (void)
 
CNDP_API void cthread_sched_stack_size_set (size_t stack_size)
 
CNDP_API size_t cthread_sched_stack_size (void)
 
CNDP_API int cthread_sched_create (size_t stack_size)
 
CNDP_API struct cthreadcthread_create (const char *name, cthread_func_t func, void *arg)
 
CNDP_API int cthread_cancel (struct cthread *ct)
 
CNDP_API int cthread_join (struct cthread *ct, void **ptr)
 
CNDP_API void cthread_detach (void)
 
CNDP_API void cthread_exit (void *val)
 
CNDP_API void cthread_sleep (uint64_t nsecs)
 
CNDP_API void cthread_sleep_msec (uint64_t ms)
 
CNDP_API void cthread_sleep_clks (uint64_t clks)
 
CNDP_API void cthread_sleep_nsecs (uint64_t nsecs)
 
CNDP_API int cthread_timer_expired (struct cthread *ct)
 
CNDP_API void cthread_yield (void)
 
CNDP_API int cthread_set_affinity (int thread)
 
CNDP_API struct cthreadcthread_current (void)
 
CNDP_API void cthread_set_name (const char *f)
 
CNDP_API const char * cthread_get_name (struct cthread *ct)
 
CNDP_API void cthread_set_data (void *data)
 
CNDP_API void * cthread_get_data (void)
 
CNDP_API int cthread_key_create (unsigned int *key, tls_destructor_func destructor)
 
CNDP_API int cthread_key_delete (unsigned int key)
 
CNDP_API void * cthread_getspecific (unsigned int key)
 
CNDP_API int cthread_setspecific (unsigned int key, const void *value)
 
CNDP_API int cthread_mutex_init (const char *name, struct cthread_mutex **mutex, const struct cthread_mutexattr *attr)
 
CNDP_API int cthread_mutex_destroy (struct cthread_mutex *mutex)
 
CNDP_API int cthread_mutex_lock (struct cthread_mutex *mutex)
 
CNDP_API int cthread_mutex_trylock (struct cthread_mutex *mutex)
 
CNDP_API int cthread_mutex_unlock (struct cthread_mutex *mutex)
 
CNDP_API int cthread_mutex_state (struct cthread_mutex *m)
 
CNDP_API int cthread_barrier_init (const char *name, struct cthread_barrier **barr, unsigned count)
 
CNDP_API int cthread_barrier_destroy (struct cthread_barrier *b)
 
CNDP_API int cthread_barrier_wait (struct cthread_barrier *b)
 
CNDP_API int cthread_cond_init (const char *name, struct cthread_cond **c, const struct cthread_condattr *attr)
 
CNDP_API int cthread_cond_destroy (struct cthread_cond *cond)
 
CNDP_API int cthread_cond_reset (struct cthread_cond *cond)
 
CNDP_API int cthread_cond_wait (struct cthread_cond *c, struct cthread_mutex *m)
 
CNDP_API int cthread_cond_timedwait (struct cthread_cond *c, struct cthread_mutex *m, const struct timespec *abstime)
 
CNDP_API int cthread_cond_signal (struct cthread_cond *c)
 
CNDP_API int cthread_cond_broadcast (struct cthread_cond *c)
 
CNDP_API int cthread_cond_broadcast_no_sched (struct cthread_cond *c)
 
CNDP_API int cthread_sema_init (const char *name, struct cthread_sema **s, const struct cthread_semaattr *attr)
 
CNDP_API int cthread_sema_destroy (struct cthread_sema *sema)
 
CNDP_API int cthread_sema_reset (struct cthread_sema *sema)
 
CNDP_API int cthread_sema_wait (struct cthread_sema *s, struct cthread_mutex *m)
 
CNDP_API int cthread_sema_timedwait (struct cthread_sema *s, struct cthread_mutex *m, const struct timespec *abstime)
 
CNDP_API int cthread_sema_signal (struct cthread_sema *s)
 
CNDP_API int cthread_sema_flush (struct cthread_sema *s)
 
CNDP_API int cthread_sema_flush_no_sched (struct cthread_sema *s)
 
CNDP_API int is_cthread_running (void)
 
CNDP_API struct cthreadcthread_find (struct cthread_sched *s, int threadid)
 
CNDP_API int cthread_foreach (struct cthread_sched *s, cthread_cb_t func, void *arg)
 
CNDP_API struct cthread_schedcthread_get_sched (struct cthread *c)
 
CNDP_API int cthread_sched_id (struct cthread_sched *s)
 
CNDP_API struct cthread_schedcthread_sched_find (int schedid)
 
CNDP_API int cthread_sched_foreach (sched_cb_t func, void *arg)
 
CNDP_API void * cthread_thread_private (struct cthread *c)
 
CNDP_API int cthread_set_thread_private (struct cthread *c, void *arg)
 
CNDP_API int cthread_once_init (struct cthread_once **once)
 
CNDP_API int cthread_once_destroy (struct cthread_once *once)
 
CNDP_API int cthread_once_reset (struct cthread_once *once)
 
CNDP_API int cthread_once (struct cthread_once *once, int(*func)(void *), void *arg)
 

Variables

char __start_per_dt
 

Detailed Description

This file contains the public API for the D-thread subsystem

The L_thread subsystem provides a simple cooperative scheduler to enable arbitrary functions to run as cooperative threads within a single P-thread.

The subsystem provides a P-thread like API that is intended to assist in reuse of legacy code written for POSIX p_threads.

The D-thread subsystem relies on cooperative multitasking, as such an D-thread must possess frequent rescheduling points. Often these rescheduling points are provided transparently when the application invokes an D-thread API.

In some applications it is possible that the program may enter a loop the exit condition for which depends on the action of another thread or a response from hardware. In such a case it is necessary to yield the thread periodically in the loop body, to allow other threads an opportunity to run. This can be done by inserting a call to cthread_yield() or cthread_sleep(n) in the body of the loop.

If the application makes expensive / blocking system calls or does other work that would take an inordinate amount of time to complete, this will stall the cooperative scheduler resulting in very poor performance.

In such cases an D-thread can be migrated temporarily to another scheduler running in a different P-thread on another core. When the expensive or blocking operation is completed it can be migrated back to the original scheduler. In this way other threads can continue to run on the original scheduler and will be completely unaffected by the blocking behaviour. To migrate an D-thread to another scheduler the API cthread_set_affinity() is provided.

If D-threads that share data are running on the same core it is possible to design programs where mutual exclusion mechanisms to protect shared data can be avoided. This is due to the fact that the cooperative threads cannot preempt each other.

There are two cases where mutual exclusion mechanisms are necessary.

a) Where the D-threads sharing data are running on different cores. b) Where code must yield while updating data shared with another thread.

The D-thread subsystem provides a set of mutex APIs to help with such scenarios, however excessive reliance on on these will impact performance and is best avoided if possible.

D-threads can synchronise using a fast condition variable implementation that supports signal and broadcast. An D-thread running on any core can wait on a condition.

D-threads can have D-thread local storage with an API modelled on either the P-thread get/set specific API or using PER_CTHREAD macros modelled on the CNE_PER_THREAD macros. Alternatively a simple user data pointer may be set and retrieved from a thread.

Definition in file cthread_api.h.

Macro Definition Documentation

◆ MUTEX_RECURSIVE_ATTR

#define MUTEX_RECURSIVE_ATTR   0x00000001

Mutex recursive flag

Definition at line 130 of file cthread_api.h.

◆ CTHREAD_MAX_KEYS

#define CTHREAD_MAX_KEYS   256

Define the maximum number of TLS keys that can be created

Definition at line 148 of file cthread_api.h.

◆ CTHREAD_DESTRUCTOR_ITERATIONS

#define CTHREAD_DESTRUCTOR_ITERATIONS   4

Define the maximum number of attempts to destroy an cthread's TLS data on thread exit

Definition at line 154 of file cthread_api.h.

◆ CTHREAD_MAX_THREADS

#define CTHREAD_MAX_THREADS   CNE_MAX_THREADS

Define the maximum number of threads that will support cthreads

Definition at line 159 of file cthread_api.h.

◆ CTHREAD_PREALLOC

#define CTHREAD_PREALLOC   64

How many cthread objects to pre-allocate as the system grows applies to cthreads + stacks, TLS, mutexes, cond vars.

See also
_cthread_alloc()
_cond_alloc()
_sema_alloc()
_mutex_alloc()

Definition at line 171 of file cthread_api.h.

◆ CNE_DECLARE_PER_CTHREAD

#define CNE_DECLARE_PER_CTHREAD (   type,
  name 
)     extern __typeof__(type) __attribute((section("per_dt"))) per_dt_##name

Macro to declare an er cthread variable "var" of type "type"

Definition at line 665 of file cthread_api.h.

◆ CNE_PER_CTHREAD

#define CNE_PER_CTHREAD (   name)
Value:
((typeof(per_dt_##name) *)((char *)cthread_get_data() + \
((char *)&per_dt_##name - &__start_per_dt)))
char __start_per_dt
CNDP_API void * cthread_get_data(void)

Read/write the per-thread variable value

Definition at line 670 of file cthread_api.h.

Typedef Documentation

◆ cthread_func_t

typedef void(* cthread_func_t) (void *)

Typedef for any cthread function called from cthread_create()

Examples
examples/phil/main.c.

Definition at line 135 of file cthread_api.h.

◆ tls_destructor_func

typedef void(* tls_destructor_func) (void *)

Destructor function pointer

Definition at line 522 of file cthread_api.h.

◆ cthread_cb_t

typedef int(* cthread_cb_t) (struct cthread *c, void *arg, int idx)

cthread callback function pointer for the foreach type APIs

Definition at line 1128 of file cthread_api.h.

◆ sched_cb_t

typedef int(* sched_cb_t) (struct cthread_sched *s, void *arg, int idx)

The callback for the cthread_sched_foreach() callback.

Definition at line 1169 of file cthread_api.h.

Function Documentation

◆ cthread_num_schedulers_set()

CNDP_API int cthread_num_schedulers_set ( int  num)

Set the number of schedulers in the system.

This function may optionally be called before starting schedulers.

If the number of schedulers is not set, or set to 0 then each scheduler will begin scheduling cthreads immediately when it is started.

If the number of schedulers is set to greater than 0, then each scheduler will wait until all schedulers have started before beginning to schedule cthreads.

If an application wishes to have threads migrate between cores using cthread_set_affinity(), or join threads running on other cores using cthread_join(), then it is prudent to set the number of schedulers to ensure that all schedulers are initialised beforehand.

Parameters
numthe number of schedulers in the system
Returns
the number of schedulers in the system

◆ cthread_active_schedulers()

CNDP_API int cthread_active_schedulers ( void  )

Return the number of schedulers currently running

Returns
the number of schedulers in the system

◆ cthread_scheduler_shutdown()

CNDP_API void cthread_scheduler_shutdown ( int  thread)

Shutdown the specified scheduler

This function tells the specified scheduler to exit if/when there is no more work to do.

Note that although the scheduler will stop resources are not freed.

Parameters
threadThe thread of the scheduler to shutdown
Returns
none

◆ cthread_scheduler_shutdown_all()

CNDP_API void cthread_scheduler_shutdown_all ( void  )

Shutdown all schedulers

This function tells all schedulers including the current scheduler to exit if/when there is no more work to do.

Note that although the schedulers will stop resources are not freed.

Returns
none

◆ cthread_run()

CNDP_API void cthread_run ( void  )

Run the cthread scheduler

Runs the cthread scheduler. This function returns only if/when all cthreads have exited. This function must be the main loop of an CNE thread.

Returns
none
Examples
examples/phil/main.c.

◆ cthread_sched_stack_size_set()

CNDP_API void cthread_sched_stack_size_set ( size_t  stack_size)

Set the scheduler stack size all threads on the scheduler.

Must be called before the scheduler is started and will become the default stack size for all schedulers created after this call.

Parameters
stack_sizeSize in bytes of the scheduler stack, can be zero to use the default size.

◆ cthread_sched_stack_size()

CNDP_API size_t cthread_sched_stack_size ( void  )

Get the scheduler default stack size.

Returns
The number of default bytes in a scheduler stack.

◆ cthread_sched_create()

CNDP_API int cthread_sched_create ( size_t  stack_size)

Start a scehduler on the current thread.

Parameters
stack_sizeThe number of bytes to allocate for a stack for all threads in a scheduler.
Returns
The scheduler ID value or -1 on error
Examples
examples/phil/main.c.

◆ cthread_create()

CNDP_API struct cthread* cthread_create ( const char *  name,
cthread_func_t  func,
void *  arg 
)

Create an cthread

Creates an cthread and places it in the ready queue on a particular thread.

Parameters
nameThe name of the thread to be created, can be NULL
funcPointer to the function the for the thread to run
argPointer to args that will be passed to the thread
Returns
0 success EAGAIN no resources available EINVAL NULL thread or function pointer
Examples
examples/phil/main.c, and examples/phil/phil.c.

◆ cthread_cancel()

CNDP_API int cthread_cancel ( struct cthread ct)

Cancel an cthread

Cancels an cthread and causes it to be terminated If the cthread is detached it will be freed immediately otherwise its resources will not be released until it is joined.

Parameters
ctPointer to an cthread that will be cancelled
Returns
0 success EINVAL thread was NULL

◆ cthread_join()

CNDP_API int cthread_join ( struct cthread ct,
void **  ptr 
)

Join an cthread

Joins the current thread with the specified cthread, and waits for that thread to exit. Passes an optional pointer to collect returned data.

Parameters
ctPointer to the cthread to be joined
ptrPointer to pointer to collect returned data
Returns
0 success EINVAL cthread could not be joined.

◆ cthread_detach()

CNDP_API void cthread_detach ( void  )

Detach an cthread

Detaches the current thread On exit a detached cthread will be freed immediately and will not wait to be joined. The default state for a thread is not detached.

Returns
none

◆ cthread_exit()

CNDP_API void cthread_exit ( void *  val)

Exit an cthread

Terminate the current thread, optionally return data. The data may be collected by cthread_join()

After calling this function the cthread will be suspended until it is joined. After it is joined then its resources will be freed.

Parameters
valPointer to pointer to data to be returned
Returns
none

◆ cthread_sleep()

CNDP_API void cthread_sleep ( uint64_t  nsecs)

Cause the current cthread to sleep for n nanoseconds

The current thread will be suspended until the specified time has elapsed or has been exceeded.

Execution will switch to the next cthread that is ready to run

Parameters
nsecsNumber of nanoseconds to sleep
Returns
none

◆ cthread_sleep_msec()

CNDP_API void cthread_sleep_msec ( uint64_t  ms)

Cause the current cthread to sleep for n milliseconds

The current thread will be suspended until the specified time has elapsed or has been exceeded.

Execution will switch to the next cthread that is ready to run

Parameters
msNumber of milliseconds to sleep
Returns
none
Examples
examples/phil/phil.c.

◆ cthread_sleep_clks()

CNDP_API void cthread_sleep_clks ( uint64_t  clks)

Cause the current cthread to sleep for n cpu clock ticks

The current thread will be suspended until the specified time has elapsed or has been exceeded.

Execution will switch to the next cthread that is ready to run

Parameters
clksNumber of clock ticks to sleep
Returns
none

◆ cthread_sleep_nsecs()

CNDP_API void cthread_sleep_nsecs ( uint64_t  nsecs)

Cause the current cthread to sleep for n nsecs

The current thread will be suspended until the specified time has elapsed or has been exceeded.

Execution will switch to the next cthread that is ready to run

Parameters
nsecsNumber of nsecs to sleep
Returns
none

◆ cthread_timer_expired()

CNDP_API int cthread_timer_expired ( struct cthread ct)

Return the state of the expired flag

Parameters
ctIf ct is null then use THIS_CTHREAD
Returns
True if ct has expired a timer

◆ cthread_yield()

CNDP_API void cthread_yield ( void  )

Yield the current cthread

The current thread will yield and execution will switch to the next cthread that is ready to run

Returns
none

◆ cthread_set_affinity()

CNDP_API int cthread_set_affinity ( int  thread)

Migrate the current thread to another scheduler

This function migrates the current thread to another scheduler. Execution will switch to the next cthread that is ready to run on the current scheduler. The current thread will be resumed on the new scheduler.

Parameters
threadThe thread to migrate to
Returns
0 success we are now running on the specified core EINVAL the destination thread was not valid

◆ cthread_current()

CNDP_API struct cthread* cthread_current ( void  )

Return the current cthread

Returns the current cthread

Returns
pointer to the current cthread

◆ cthread_set_name()

CNDP_API void cthread_set_name ( const char *  f)

Set the current thread name

Parameters
fThe name of the thread

◆ cthread_get_name()

CNDP_API const char* cthread_get_name ( struct cthread ct)

Get the thread name string

Parameters
ctThe cthread pointer
Returns
The string pointer the name of thread or NULL on error
Examples
examples/phil/main.c.

◆ cthread_set_data()

CNDP_API void cthread_set_data ( void *  data)

Associate user data with an cthread

This function sets a user data pointer in the current cthread The pointer can be retrieved with cthread_get_data() It is the users responsibility to allocate and free any data referenced by the user pointer.

Parameters
datapointer to user data
Returns
none

◆ cthread_get_data()

CNDP_API void* cthread_get_data ( void  )

Get user data for the current cthread

This function returns a user data pointer for the current cthread The pointer must first be set with cthread_set_data() It is the users responsibility to allocate and free any data referenced by the user pointer.

Returns
pointer to user data

◆ cthread_key_create()

CNDP_API int cthread_key_create ( unsigned int *  key,
tls_destructor_func  destructor 
)

Create a key for cthread TLS

This function is modelled on pthread_key_create It creates a thread-specific data key visible to all cthreads on the current scheduler.

Key values may be used to locate thread-specific data. The same key value may be used by different threads, the values bound to the key by cthread_setspecific() are maintained on a per-thread basis and persist for the life of the calling thread.

An optional destructor function may be associated with each key value. At thread exit, if a key value has a non-NULL destructor pointer, and the thread has a non-NULL value associated with the key, the function pointed to is called with the current associated value as its sole argument.

Parameters
keyPointer to the key to be created
destructorPointer to destructor function
Returns
0 success EINVAL the key ptr was NULL EAGAIN no resources available

◆ cthread_key_delete()

CNDP_API int cthread_key_delete ( unsigned int  key)

Delete key for cthread TLS

This function is modelled on pthread_key_delete(). It deletes a thread-specific data key previously returned by cthread_key_create(). The thread-specific data values associated with the key need not be NULL at the time that cthread_key_delete is called. It is the responsibility of the application to free any application storage or perform any cleanup actions for data structures related to the deleted key. This cleanup can be done either before or after cthread_key_delete is called.

Parameters
keyThe key to be deleted
Returns
0 Success EINVAL the key was invalid

◆ cthread_getspecific()

CNDP_API void* cthread_getspecific ( unsigned int  key)

Get cthread TLS

This function is modelled on pthread_get_specific(). It returns the value currently bound to the specified key on behalf of the calling thread. Calling cthread_getspecific() with a key value not obtained from cthread_key_create() or after key has been deleted with cthread_key_delete() will result in undefined behaviour. cthread_getspecific() may be called from a thread-specific data destructor function.

Parameters
keyThe key for which data is requested
Returns
Pointer to the thread specific data associated with that key or NULL if no data has been set.

◆ cthread_setspecific()

CNDP_API int cthread_setspecific ( unsigned int  key,
const void *  value 
)

Set cthread TLS

This function is modelled on pthread_set_specific() It associates a thread-specific value with a key obtained via a previous call to cthread_key_create(). Different threads may bind different values to the same key. These values are typically pointers to dynamically allocated memory that have been reserved by the calling thread. Calling cthread_setspecific with a key value not obtained from cthread_key_create or after the key has been deleted with cthread_key_delete will result in undefined behaviour.

Parameters
keyThe key for which data is to be set
valuePointer to the user data
Returns
0 success EINVAL the key was invalid

◆ cthread_mutex_init()

CNDP_API int cthread_mutex_init ( const char *  name,
struct cthread_mutex **  mutex,
const struct cthread_mutexattr attr 
)

Initialize a mutex

This function provides a mutual exclusion device, the need for which can normally be avoided in a cooperative multitasking environment. It is provided to aid porting of legacy code originally written for preemptive multitasking environments such as pthreads.

A mutex may be unlocked (not owned by any thread), or locked (owned by one thread).

A mutex can never be owned by more than one thread simultaneously. A thread attempting to lock a mutex that is already locked by another thread is suspended until the owning thread unlocks the mutex.

cthread_mutex_init() initializes the mutex object pointed to by mutex Optional mutex attributes specified in mutexattr, are reserved for future use and are currently ignored.

If a thread calls cthread_mutex_lock() on the mutex, then if the mutex is currently unlocked, it becomes locked and owned by the calling thread, and cthread_mutex_lock returns immediately. If the mutex is already locked by another thread, cthread_mutex_lock suspends the calling thread until the mutex is unlocked.

cthread_mutex_trylock behaves identically to cthread_mutex_lock, except that it does not block the calling thread if the mutex is already locked by another thread.

cthread_mutex_unlock() unlocks the specified mutex. The mutex is assumed to be locked and owned by the calling thread.

cthread_mutex_destroy() destroys a mutex object, freeing its resources. The mutex must be unlocked with nothing blocked on it before calling cthread_mutex_destroy.

Parameters
nameOptional pointer to string describing the mutex
mutexPointer to pointer to the mutex to be initialized
attrPointer to attribute - unused reserved
Returns
0 success EINVAL mutex was not a valid pointer EAGAIN insufficient resources
Examples
examples/phil/phil.c.

◆ cthread_mutex_destroy()

CNDP_API int cthread_mutex_destroy ( struct cthread_mutex *  mutex)

Destroy a mutex

This function destroys the specified mutex freeing its resources. The mutex must be unlocked before calling cthread_mutex_destroy.

See also
cthread_mutex_init()
Parameters
mutexPointer to pointer to the mutex to be initialized
Returns
0 success EINVAL mutex was not an initialized mutex EBUSY mutex was still in use
Examples
examples/phil/phil.c.

◆ cthread_mutex_lock()

CNDP_API int cthread_mutex_lock ( struct cthread_mutex *  mutex)

Lock a mutex

This function attempts to lock a mutex. If a thread calls cthread_mutex_lock() on the mutex, then if the mutex is currently unlocked, it becomes locked and owned by the calling thread, and cthread_mutex_lock returns immediately. If the mutex is already locked by another thread, cthread_mutex_lock suspends the calling thread until the mutex is unlocked.

See also
cthread_mutex_init()
Parameters
mutexPointer to pointer to the mutex to be initialized
Returns
0 success EINVAL mutex was not an initialized mutex EDEADLOCK the mutex was already owned by the calling thread
Examples
examples/phil/phil.c.

◆ cthread_mutex_trylock()

CNDP_API int cthread_mutex_trylock ( struct cthread_mutex *  mutex)

Try to lock a mutex

This function attempts to lock a mutex. cthread_mutex_trylock behaves identically to cthread_mutex_lock, except that it does not block the calling thread if the mutex is already locked by another thread.

See also
cthread_mutex_init()
Parameters
mutexPointer to pointer to the mutex to be initialized
Returns
0 success EINVAL mutex was not an initialized mutex EBUSY the mutex was already locked by another thread

◆ cthread_mutex_unlock()

CNDP_API int cthread_mutex_unlock ( struct cthread_mutex *  mutex)

Unlock a mutex

This function attempts to unlock the specified mutex. The mutex is assumed to be locked and owned by the calling thread.

The oldest of any threads blocked on the mutex is made ready and may compete with any other running thread to gain the mutex, it fails it will be blocked again.

Parameters
mutexPointer to pointer to the mutex to be initialized
Returns
0 mutex was unlocked EINVAL mutex was not an initialized mutex EPERM the mutex was not owned by the calling thread
Examples
examples/phil/phil.c.

◆ cthread_mutex_state()

CNDP_API int cthread_mutex_state ( struct cthread_mutex *  m)

Get the mutex state value

Parameters
mThe mutex structure pointer
Returns
The state value

◆ cthread_barrier_init()

CNDP_API int cthread_barrier_init ( const char *  name,
struct cthread_barrier **  barr,
unsigned  count 
)

Initialize a barrier structure

Parameters
nameThe name of the barrier
barrPointer to a pointer of the cthread_barrier structure
countThe number of times cthread_barrier_wait() needs to be called.
Returns
0 on success or -1 on error
Examples
examples/phil/phil.c.

◆ cthread_barrier_destroy()

CNDP_API int cthread_barrier_destroy ( struct cthread_barrier *  b)

Destroy a barrier structure

Parameters
bThe cthread_barrier pointer
Returns
0 on success or -1 on error
Examples
examples/phil/phil.c.

◆ cthread_barrier_wait()

CNDP_API int cthread_barrier_wait ( struct cthread_barrier *  b)

Wait on a barrier counter to be decremented to zero before returning.

Parameters
bThe barrier pointer to wait on
Returns
0 on success or -1 on error
Examples
examples/phil/phil.c.

◆ cthread_cond_init()

CNDP_API int cthread_cond_init ( const char *  name,
struct cthread_cond **  c,
const struct cthread_condattr *  attr 
)

Initialize a condition variable

This function initializes a condition variable.

Condition variables can be used to communicate changes in the state of data shared between threads.

See also
cthread_cond_wait()
Parameters
namePointer to optional string describing the condition variable
cPointer to pointer to the condition variable to be initialized
attrPointer to optional attribute reserved for future use, currently ignored
Returns
0 success EINVAL cond was not a valid pointer EAGAIN insufficient resources

◆ cthread_cond_destroy()

CNDP_API int cthread_cond_destroy ( struct cthread_cond *  cond)

Destroy a condition variable

This function destroys a condition variable that was created with cthread_cond_init() and releases its resources.

Parameters
condPointer to pointer to the condition variable to be destroyed
Returns
0 Success EBUSY condition variable was still in use EINVAL was not an initialised condition variable

◆ cthread_cond_reset()

CNDP_API int cthread_cond_reset ( struct cthread_cond *  cond)

Reset a condition variable to initialized state.

Parameters
condPointer to pointer to the condition variable to be destroyed
Returns
0 Success EBUSY condition variable was still in use EINVAL was not an initialised condition variable

◆ cthread_cond_wait()

CNDP_API int cthread_cond_wait ( struct cthread_cond *  c,
struct cthread_mutex *  m 
)

Wait on a condition variable

The function blocks the current thread waiting on the condition variable specified by cond. The waiting thread unblocks only after another thread calls cthread_cond_signal, or cthread_cond_broadcast, specifying the same condition variable.

Parameters
cPointer to pointer to the condition variable to be waited on
mMutex to release or NULL if no mutex. (Currently not supported)
Returns
0 The condition was signalled ( Success ) EINVAL was not a an initialised condition variable

◆ cthread_cond_timedwait()

CNDP_API int cthread_cond_timedwait ( struct cthread_cond *  c,
struct cthread_mutex *  m,
const struct timespec *  abstime 
)

Wait on a condition variable with timeout

The function blocks the current thread waiting on the condition variable specified by cond. The waiting thread unblocks only after another thread calls cthread_cond_signal, or cthread_cond_broadcast, specifying the same condition variable.

Parameters
cPointer to pointer to the condition variable to be waited on
mMutex to release or NULL if no mutex. (Currently not supported)
abstimeTimespec used for timeout value. (Currently not supported)
Returns
0 The condition was signalled ( Success ) EINVAL was not a an initialised condition variable

◆ cthread_cond_signal()

CNDP_API int cthread_cond_signal ( struct cthread_cond *  c)

Signal a condition variable

The function unblocks one thread waiting for the condition variable cond. If no threads are waiting on cond, the cthread_cond_signal() function has no effect.

Parameters
cPointer to pointer to the condition variable to be signalled
Returns
0 The condition was signalled ( Success ) EINVAL was not a an initialised condition variable

◆ cthread_cond_broadcast()

CNDP_API int cthread_cond_broadcast ( struct cthread_cond *  c)

Broadcast a condition variable

The function unblocks all threads waiting for the condition variable cond. If no threads are waiting on cond, the cthread_cond_broadcast() function has no effect.

Parameters
cPointer to pointer to the condition variable to be signalled
Returns
0 The condition was signalled ( Success ) EINVAL was not a an initialised condition variable

◆ cthread_cond_broadcast_no_sched()

CNDP_API int cthread_cond_broadcast_no_sched ( struct cthread_cond *  c)

Same as cthread_cond_broadcast(), but does not reschedule the threads

Parameters
cPointer to pointer to the condition variable to be signalled
Returns
0 The condition was signalled ( Success ) EINVAL was not a an initialised condition variable

◆ cthread_sema_init()

CNDP_API int cthread_sema_init ( const char *  name,
struct cthread_sema **  s,
const struct cthread_semaattr attr 
)

Initialize a semaphore

The semaphore can be used to communicate changes in the state of data shared between threads.

See also
cthread_sema_wait()
Parameters
namePointer to optional string describing the semaphore
sPointer to pointer to the semaphore to be initialized
attrPointer to optional attribute used to set the initial semaphore count
Returns
0 success EINVAL s is not a valid pointer EAGAIN insufficient resources

◆ cthread_sema_destroy()

CNDP_API int cthread_sema_destroy ( struct cthread_sema *  sema)

Destroy a semaphore

This function destroys a semaphore that was created with cthread_sema_init() and releases its resources.

Parameters
semaPointer to the semaphore to be destroyed
Returns
0 Success EBUSY sema is still in use EINVAL sema is not an initialised semaphore

◆ cthread_sema_reset()

CNDP_API int cthread_sema_reset ( struct cthread_sema *  sema)

Reset a semaphore to initialized state.

Parameters
semaPointer to the semaphore to be reset
Returns
0 Success EINVAL sema is not an initialised semaphore

◆ cthread_sema_wait()

CNDP_API int cthread_sema_wait ( struct cthread_sema *  s,
struct cthread_mutex *  m 
)

Wait on a semaphore

The function blocks the current thread waiting on the semaphore specified by s. The waiting thread unblocks only after another thread calls cthread_sema_signal specifying the same semaphore.

Parameters
sPointer to the semaphore on which to wait
mMutex to release or NULL if no mutex.
Returns
0 Success EINVAL s is not an initialised semaphore

◆ cthread_sema_timedwait()

CNDP_API int cthread_sema_timedwait ( struct cthread_sema *  s,
struct cthread_mutex *  m,
const struct timespec *  abstime 
)

Wait on a semaphore with timeout

The function blocks the current thread waiting on the semaphore specified by s. The waiting thread unblocks only after another thread calls cthread_sema_signal specifying the same semaphore, or abstime elapses.

Parameters
sPointer to the semaphore to be waited on
mMutex to release or NULL if no mutex.
abstimeTimespec used for timeout value.
Returns
0 Success CT_STATE_EXPIRED timeout expired without semaphore signal EINVAL s is not an initialised semaphore

◆ cthread_sema_signal()

CNDP_API int cthread_sema_signal ( struct cthread_sema *  s)

Signal a semaphore

The function unblocks one thread waiting for the semaphore.

Parameters
sPointer to the semaphore to be signalled
Returns
0 Success EINVAL s is not an initialised semaphore

◆ cthread_sema_flush()

CNDP_API int cthread_sema_flush ( struct cthread_sema *  s)

Flush a semaphore

The function unblocks all threads waiting for the semaphore.

Parameters
sPointer to the semaphore to be flushed
Returns
0 Success EINVAL s is not an initialised semaphore

◆ cthread_sema_flush_no_sched()

CNDP_API int cthread_sema_flush_no_sched ( struct cthread_sema *  s)

Flush a semaphore, but do not reschedule threads

The function unblocks all threads waiting for the semaphore.

Parameters
sPointer to the semaphore to be flushed
Returns
0 Success EINVAL s is not an initialised semaphore

◆ is_cthread_running()

CNDP_API int is_cthread_running ( void  )

Return true if the current cthread is running

◆ cthread_find()

CNDP_API struct cthread* cthread_find ( struct cthread_sched s,
int  threadid 
)

Find a cthread structure pointer for a given scheduler and thread id.

Parameters
sThe cthread scheduler pointer
threadidThe threadid value to look for on the scheduler.
Returns
pointer to cthread structure or NULL on not found
Examples
examples/phil/main.c.

◆ cthread_foreach()

CNDP_API int cthread_foreach ( struct cthread_sched s,
cthread_cb_t  func,
void *  arg 
)

Foreach cthread on a scheduler call the function with argument

Parameters
sThe scheduler structure pointer
funcThe function pointer to call for each cthread
argThe arg supplied by the user to pass to the callback function
Returns
0 on success or -1 on error
Examples
examples/phil/main.c.

◆ cthread_get_sched()

CNDP_API struct cthread_sched* cthread_get_sched ( struct cthread c)

Get the scheduler for the cthread structure.

Parameters
cThe cthread structure pointer
Returns
NULL on error or the cthread_sched structure pointer.

◆ cthread_sched_id()

CNDP_API int cthread_sched_id ( struct cthread_sched s)

return the scheduler ID value

Parameters
sThe scheduler structure pointer
Returns
-1 on error or scheduler ID value

◆ cthread_sched_find()

CNDP_API struct cthread_sched* cthread_sched_find ( int  schedid)

return the cthread_sched pointer for the given sched ID

Parameters
schedidThe schedid value to search for in the scheduler list.
Returns
NULL on error or pointer to cthread_sched structure.
Examples
examples/phil/main.c.

◆ cthread_sched_foreach()

CNDP_API int cthread_sched_foreach ( sched_cb_t  func,
void *  arg 
)

Loop over all schedulers and call the function pointer with argument.

Parameters
funcThe function to callback foreach scheduler passing the argument given
argThe argument to pass to the callback function
Returns
0 on success or -1 on error
Examples
examples/phil/main.c.

◆ cthread_thread_private()

CNDP_API void* cthread_thread_private ( struct cthread c)

return the thread private pointer or value

Parameters
cThe cthread structure pointer.
Returns
The therad private pointer value.
Examples
examples/phil/main.c.

◆ cthread_set_thread_private()

CNDP_API int cthread_set_thread_private ( struct cthread c,
void *  arg 
)

Set a thread private pointer or value.

Parameters
cThe cthread structure pointer.
argThe pointer value to set in the cthread structure. The value is not used or freed on thread exit.
Returns
0 on success or -1 on error.
Examples
examples/phil/phil.c.

◆ cthread_once_init()

CNDP_API int cthread_once_init ( struct cthread_once **  once)

Initialize a once only structure

Parameters
oncePointer to pointer of a cthread_once structure
Returns
0 on success or -1 on error

◆ cthread_once_destroy()

CNDP_API int cthread_once_destroy ( struct cthread_once once)

Destroy a cthread_once structure

Parameters
oncePointer to pointer of a cthread_once structure
Returns
0 on success or -1 on error

◆ cthread_once_reset()

CNDP_API int cthread_once_reset ( struct cthread_once once)

Reset a cthread_once structure

Parameters
oncePointer to pointer of a cthread_once structure
Returns
0 on success or -1 on error

◆ cthread_once()

CNDP_API int cthread_once ( struct cthread_once *  once,
int(*)(void *)  func,
void *  arg 
)

Execute the function only once with the cthread_once structure

Parameters
oncePointer to pointer of a cthread_once structure
funcThe function to call only once passsing the argument value.
argThe opaque data to pass to func.
Returns
0 on success or -1 on error

Variable Documentation

◆ __start_per_dt

char __start_per_dt
extern

The macros below provide an alternative mechanism to access cthread local storage.

The macros can be used to declare define and access per cthread local storage in a similar way to the CNE_PER_THREAD macros which control storage local to an thread.

Memory for per cthread variables declared in this way is allocated when the cthread is created and a pointer to this memory is stored in the cthread. The per cthread variables are accessed via the pointer + the offset of the particular variable.

The total size of per cthread storage, and the variable offsets are found by defining the variables in a unique global memory section, the start and end of which is known. This global memory section is used only in the computation of the addresses of the cthread variables, and is never actually used to store any data.

Due to the fact that variables declared this way may be scattered across many files, the start and end of the section and variable offsets are only known after linking, thus the computation of section size and variable addresses is performed at run time.

These macros are primarily provided to aid porting of code that makes use of the existing CNE_PER_THREAD macros. In principle it would be more efficient to gather all cthread local variables into a single structure and set/retrieve a pointer to that struct using the alternative cthread_data_set/get APIs.

These macros are mutually exclusive with the cthread_data_set/get APIs. If you define storage using these macros then the cthread_data_set/get APIs will not perform as expected, the cthread_data_set API does nothing, and the cthread_data_get API returns the start of global section.