API

group atomics

Public function definitions and types for Yc’s atomics.

Functions

bool y_atomic_testandset(volatile y_atomicflag *flag)

Atomically sets the flag and returns the previous value.

Parameters:

flag – The flag to set.

Returns:

The previous value of the flag.

Pre:

flag must not be NULL.

void y_atomic_clear(volatile y_atomicflag *flag)

Atomically sets the flag to false.

Parameters:

flag – The flag to clear.

Pre:

flag must not be NULL.

bool y_atomic_cmpxchg_uint(volatile y_atomicuint *dest, y_uint expected, y_uint desired)

Does a strong atomic compare exchange for unsigned ints.

Parameters:
  • dest – The destination pointer.

  • expected – The expected initial value.

  • desired – The desired end value for the destination.

Returns:

True if the exchange succeeded, false otherwise.

Pre:

dest must not be NULL.

y_uint y_atomic_inc_uint(volatile y_atomicuint *op)

Performs an atomic increment for unsigned ints.

Parameters:

op – The operand.

Returns:

The resulting incremented value.

y_uint y_atomic_dec_uint(volatile y_atomicuint *op)

Performs an atomic decrement for unsigned ints.

Parameters:

op – The operand.

Returns:

The resulting incremented value.

y_uint y_atomic_load_uint(volatile y_atomicuint *v)

Performs an atomic load for unsigned ints.

Parameters:

v – The value to load.

Returns:

The value.

void y_atomic_store_uint(volatile y_atomicuint *v, y_uint val)

Performs an atomic store for unsigned ints.

Parameters:
  • v – The value to store to.

  • val – The value to store.

Pre:

v must not be NULL.

bool y_atomic_cmpxchg_32(volatile y_atomic32 *dest, uint32_t expected, uint32_t desired)

Does a 32-bit strong atomic compare exchange.

Parameters:
  • dest – The destination pointer.

  • expected – The expected initial value.

  • desired – The desired end value for the destination.

Returns:

True if the exchange succeeded, false otherwise.

Pre:

dest must not be NULL.

uint32_t y_atomic_inc_32(volatile y_atomic32 *op)

Performs a 32-bit atomic increment.

Parameters:

op – The operand.

Returns:

The resulting incremented value.

uint32_t y_atomic_dec_32(volatile y_atomic32 *op)

Performs a 32-bit atomic decrement.

Parameters:

op – The operand.

Returns:

The resulting incremented value.

uint32_t y_atomic_load_32(volatile y_atomic32 *v)

Performs a 32-bit atomic load.

Parameters:

v – The value to load.

Returns:

The value.

void y_atomic_store_32(volatile y_atomic32 *v, y_uint val)

Performs a 32-bit atomic store.

Parameters:
  • v – The value to store to.

  • val – The value to store.

Pre:

v must not be NULL.

group strucon

Public function definitions and types for Yc’s structured concurrency.

Defines

y_THREAD_INVALID_ID

An invalid thread ID.

Typedefs

typedef y_ListID y_ThreadID

The typedef for Yc’s thread ID.

typedef struct y_strucon_mutex *y_StruconMutex

Public type of the private mutex type.

typedef struct y_strucon_rwlock *y_StruconRWLock

Public type of the private reader-writer lock type.

typedef struct y_strucon_sem *y_StruconSem

Public type for private semaphore type.

typedef struct y_strucon_condvar *y_StruconCondvar

Public type for private condition variable type.

typedef y_atomicuint y_ThreadLock

A type for thread locks.

typedef y_Status (*y_StruconThreadFunc)(void *ptr1, void *ptr2)

A function type for starting threads.

It takes two pointers so that one can serve the purpose of capturing a “closure” if so desired.

Param ptr1:

The first pointer to pass to the thread.

Param ptr2:

The second pointer to pass to the thread.

Return:

An error code, if any. This will be returned to the parent.

Functions

y_Status y_strucon_init(void)

Initializes global structured concurrency data.

This must be called once and only once, before any other structured concurrency functions.

Returns:

An error code, if any.

y_StackPool y_strucon_stackpool(void)

Returns the stack pool for the thread.

Returns:

The stack pool for the thread.

y_ThreadID y_strucon_id(void)

Returns the thread ID for the thread.

Returns:

The thread ID for the current thread.

y_Status y_strucon_status(void)

Returns the status for the current thread.

Returns:

The status of the current thread.

void y_strucon_setStatus(y_Status s)

Sets the status for the current thread.

Parameters:

s – The status to set for the current thread.

y_Status y_strucon_stack_push(const char *key, void *data, size_t len)

Pushes an item onto the context stack for the current thread that is identified by the key.

Parameters:
  • key – The name of the context stack to push onto.

  • data – A pointer to the data to push. It must have the correct size.

  • len – The size of the data in bytes.

Returns:

An error code, if any.

Pre:

key must not be NULL.

Pre:

data must not be NULL.

Pre:

key must have as many bytes as will be copied into the stack.

void y_strucon_stack_pop(const char *key)

Pops an item off of the context stack for the current thread that is identified by the key.

Parameters:

key – The name of the context stack to pop from.

Pre:

key must not be NULL.

y_Status y_strucon_stack_pushErrorHandler(y_ErrorHandler handler)

Pushes an error handler onto the error handler context stack for the current thread.

Parameters:

handler – The error handler to push.

Returns:

An error code, if any.

Pre:

handler must not be NULL.

void y_strucon_stack_popErrorHandler(void)

Pops an error handler off of the error handler context stack for the current thread.

This panics if there is no error handler in the stack.

y_Status y_strucon_handleError(y_Error e)

Handles an error.

This runs the error handlers in the error handler context stack for the current thread and all of its ancestors, in order, until one error handler returns true.

Parameters:

e – The error to handle.

Returns:

The error code returned by the handler that handled the error, or the status corresponding to e if no handler handles the error.

void *y_strucon_stack_at(const char *key)

Returns the top of the context stack with the key.

If the context stack does not exist, ancestor threads are searched, in order, for it. If it doesn’t exist in ancestor threads either, this panics.

Parameters:

key – The key of the context stack.

Returns:

A pointer to the item at the top of the context stack.

Pre:

key must not be NULL.

Pre:

A context stack must exist with key.

void y_strucon_free(void)

Frees global structured concurrency data.

This must be called once and only once, after any other structured concurrency functions and after all threads are joined. It must be called from the same thread that called y_strucon_init() and only after all structured concurrency is done.

void y_strucon_mutex_lock(y_StruconMutex m)

Locks the mutex.

Parameters:

m – The mutex.

Pre:

m must not be NULL.

y_Error y_strucon_mutex_trylock(y_StruconMutex m)

Tries to lock the mutex.

Parameters:

m – The mutex.

Returns:

An error code, if any.

Pre:

m must not be NULL.

void y_strucon_mutex_unlock(y_StruconMutex m)

Unlocks the mutex.

Parameters:

m – The mutex.

Pre:

m must not be NULL.

void y_strucon_rwlock_rdlock(y_StruconRWLock l)

Grabs a read lock.

Parameters:

l – The reader/writer lock.

Pre:

l must not be NULL.

y_Error y_strucon_rwlock_tryrdlock(y_StruconRWLock l)

Tries to grab a read lock.

Parameters:

l – The reader/writer lock.

Returns:

An error code, if any.

Pre:

l must not be NULL.

void y_strucon_rwlock_rdunlock(y_StruconRWLock l)

Unlocks a read lock.

Parameters:

l – The reader/writer lock.

Pre:

l must not be NULL.

void y_strucon_rwlock_wrlock(y_StruconRWLock l)

Grabs a write lock.

Parameters:

l – The reader/writer lock.

Pre:

l must not be NULL.

y_Error y_strucon_rwlock_trywrlock(y_StruconRWLock l)

Tries to grab a write lock.

Parameters:

l – The reader/writer lock.

Returns:

An error code, if any.

Pre:

l must not be NULL.

void y_strucon_rwlock_wrunlock(y_StruconRWLock l)

Unlocks a write lock.

Parameters:

l – The reader/writer lock.

Pre:

l must not be NULL.

void y_strucon_sem_wait(y_StruconSem sm)

Wait on the semaphore.

Parameters:

sm – The semaphore.

Pre:

sm must not be NULL.

y_Error y_strucon_sem_trywait(y_StruconSem sm)

Attempt to wait on the semaphore, but return immediately regardless of if the semaphore was successfully locked.

Parameters:

sm – The semaphore.

Returns:

An error code, if any. This returns y_ERROR_LOCKED if the semaphore failed to be taken.

Pre:

sm must not be NULL.

y_Error y_strucon_sem_timedwait(y_StruconSem sm, y_ulong millis)

Waits on a semaphore for at least the specified amount of milliseconds and returns regardless of if the semaphore was successfully locked.

Parameters:
  • sm – The semaphore.

  • millis – The number of milliseconds to wait (at least).

Returns:

An error code, if any. This returns y_ERROR_LOCKED if the semaphore failed to be taken.

Pre:

sm must not be NULL.

void y_strucon_sem_post(y_StruconSem sm, y_uint amt)

Signal the semaphore.

Parameters:
  • sm – The semaphore.

  • amt – The amount of times to signal the semaphore.

Pre:

sm must not be NULL.

Pre:

amt must be greater than 0.

void y_strucon_condvar_signal(y_StruconCondvar v)

Signals the condition variable and unblocks one thread waiting on it, if any.

Parameters:

v – The condition variable.

Pre:

v must not be NULL.

void y_strucon_condvar_broadcast(y_StruconCondvar v)

Signals the condition variable and unblocks all threads waiting on it, if any.

Parameters:

v – The condition variable.

Pre:

v must not be NULL.

void y_strucon_condvar_wait(y_StruconCondvar v, y_StruconMutex m)

Waits on the condition variable, atomically releasing the mutex when doing so.

The mutex must be locked by the thread when this function is called.

Parameters:
  • v – The condition variable.

  • m – The mutex.

Pre:

v must not be NULL.

Pre:

v must be initialized.

Pre:

m must not be NULL.

Pre:

m must be initialized.

Pre:

m must be locked.

y_Error y_strucon_condvar_timedwait(y_StruconCondvar v, y_StruconMutex m, y_ulong millis)

Waits for the specified time on the condition variable, atomically releasing the mutex when doing so.

The mutex must be locked by the thread when this function is called. This returns y_ERROR_LOCKED if the timeout expires.

Parameters:
  • v – The condition variable.

  • m – The mutex.

  • millis – The amount of time to wait, in milliseconds.

Returns:

An error code, if any.

Pre:

v must not be NULL.

Pre:

v must be initialized.

Pre:

m must not be NULL.

Pre:

m must be initialized.

Pre:

m must be locked.

void y_strucon_thread_lock(void)

Locks the current thread by incrementing the lock count.

y_uint y_strucon_thread_unlock(void)

Decrements the thread lock count and returns the new lock count.

If the resulting count is 0, then the thread is unlocked.

Returns:

The resulting value of the lock.

bool y_strucon_thread_root(void)

Returns true if the current thread is the root thread, false otherwise.

Returns:

True if the current thread is the root thread, false otherwise.

group threadpool

Common definitions for threadpools.

group threadset

Public function definitions and types for threadsets.

Defines

y_THREADSET_OPEN(t)

Opens a threadset with a new scope.

This is meant to be followed immediately by a new scope. This does not give any indication of an error, except that the scope is not entered, so if you want to find out if there’s an error, use a boolean set to true inside the scope and check it after the scope.

Parameters:
  • t – The name of the threadset inside the scope. This macro creates a new threadset variable.

Pre:

t must only be a variable name, nothing else.

Typedefs

typedef struct y_threadset *y_ThreadSet

The public type of the non-public threadset type.

Functions

y_ThreadSet y_threadset_screate(void)

Creates and initializes a threadset.

Returns:

A threadset, or NULL on error.

size_t y_threadset_nchildren(y_ThreadSet s)

Returns the number of children in the threadset.

Parameters:

s – The threadset.

Returns:

The number of children in the threadset.

Pre:

s must not be NULL.

Pre:

s must be initialized.

y_Status y_threadset_run(y_ThreadSet s, y_StruconThreadFunc func, void *ptr1, void *ptr2, bool from_child, bool to_child)

Runs a thread in the threadset and initializes pipe between the parent and the child according to the two flags.

Parameters:
  • s – The set to run the thread in.

  • func – The thread function to run.

  • ptr1 – The first pointer to pass to the thread function.

  • ptr2 – The second pointer to pass to the thread function.

  • from_child – Initialize a pipe to receive messages from the child.

  • to_child – Initialize a pipe to send messages to the child.

Returns:

An error code, if any.

Pre:

s must not be NULL.

Pre:

func must not be NULL.

y_Status y_threadset_addChildToMultiplexer(y_ThreadSet s, y_Multiplex m, size_t idx, y_MultiplexData data)

Adds the pipe to receive messages from the child at the specified index to the multiplexer with the specified data.

Parameters:
  • s – The threadset.

  • m – The multiplexer.

  • idx – The index of the child to add. If there is no child at the index, or the child does not have an initialized pipe, this panics.

  • data – The multiplexer data to associate with the child’s fd.

Returns:

An error code, if any.

Pre:

s must not be NULL.

Pre:

m must not be NULL.

Pre:

data.func must not be NULL.

Pre:

There must be a child at idx.

Pre:

The child at idx must have initialized pipes.

y_Status y_threadset_receiveMsgFromChild(y_ThreadSet s, size_t idx, void *buf, size_t len)

Receives a message from a child.

The message should be small.

Parameters:
  • s – The threadset.

  • idx – The index of the child to receive from. If there is no child at the index, or the child does not have an initialized pipe, this panics.

  • buf – The buffer to fill with the message, which must be len bytes.

  • len – The length of the expected message, in bytes.

Returns:

An error code, if any.

Pre:

s must not be NULL.

Pre:

buf must not be NULL.

Pre:

There must be a child at idx.

Pre:

The child at idx must have initialized pipes.

y_Status y_threadset_sendMsgToChild(y_ThreadSet s, size_t idx, void *msg, size_t len)

Sends a message to a child.

The message should be small.

Parameters:
  • s – The threadset.

  • idx – The index of the child to send to. If there is no child at the index, or the child does not have an initialized pipe, this panics.

  • msg – The message to send, which must be len bytes.

  • len – The length of the message, in bytes.

Returns:

An error code, if any.

Pre:

s must not be NULL.

Pre:

msg must not be NULL.

Pre:

There must be a child at idx.

Pre:

The child at idx must have initialized pipes.

y_Status y_threadset_sendMsgToChildren(y_ThreadSet s, void *msg, size_t len)

Sends a message to all children.

The message should be small.

Parameters:
  • s – The threadset.

  • msg – The message to send, which must be len bytes.

  • len – The length of the message, in bytes.

Returns:

An error code, if any.

Pre:

s must not be NULL.

Pre:

msg must not be NULL.

Pre:

The child at idx must have initialized pipes.

y_Status y_threadset_addParentToMultiplexer(y_Multiplex m, y_MultiplexData data)

Adds the fd to receive messages from the parent thread to the multiplexer.

This panics if the file descriptors to the parent are uninitialized.

Parameters:
  • m – The multiplexer to add to.

  • data – The data to associate with the file descriptor.

Returns:

An error code, if any.

Pre:

m must not be NULL.

Pre:

data.func must not be NULL.

Pre:

The thread must have initialized file descriptors to the parent.

y_Status y_threadset_receiveMsgFromParent(void *buf, size_t len)

Receives a message from the thread’s parent.

The message should be small. The thread must have initialized file descriptors to communicate with the parent. This panics if the file descriptors to the parent are uninitialized.

Parameters:
  • buf – A buffer to fill with the sent message.

  • len – The expected length of the message.

Returns:

An error code, if any.

Pre:

buf must not be NULL.

Pre:

The thread must have initialized file descriptors to the parent.

y_Status y_threadset_sendMsgToParent(void *msg, size_t len)

Sends a message to the thread’s parent.

The message should be small. The thread must have initialized file descriptors to communicate with the parent. This panics if the file descriptors to the parent are uninitialized.

Parameters:
  • msg – The message to send.

  • len – The length of the message to send.

Returns:

An error code, if any.

Pre:

msg must not be NULL.

Pre:

The thread must have initialized file descriptors to the parent.

y_Status y_threadset_cancelAll(y_ThreadSet s)

Cancels all child threads.

Parameters:

s – The threadset.

Returns:

An error code, if any.

Pre:

s must not be NULL.