libnds
Loading...
Searching...
No Matches
Typedefs | Functions
cothread.h File Reference

Cooperative multithreading system. More...

#include <assert.h>
#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
#include <nds/ndstypes.h>
#include <nds/cothread_asm.h>

Typedefs

typedef volatile uint8_t comutex_t
 Mutex.
 
typedef volatile uint32_t cosema_t
 Semaphore (counting, not binary)
 
typedef int(* cothread_entrypoint_t) (void *)
 Thread entrypoint.
 
typedef int cothread_t
 Thread ID.
 

Functions

static void comutex_acquire (comutex_t *mutex)
 Waits in a loop until the mutex is available.
 
static bool comutex_init (comutex_t *mutex)
 Initializes a mutex.
 
static void comutex_release (comutex_t *mutex)
 Releases a mutex.
 
static bool comutex_try_acquire (comutex_t *mutex)
 Tries to acquire a mutex without blocking execution.
 
static bool cosema_init (cosema_t *sema, uint32_t init_val)
 Initializes a counting semaphore to the desired value.
 
static void cosema_signal (cosema_t *sema)
 Signals a semaphore.
 
static bool cosema_try_wait (cosema_t *sema)
 Checks if a semaphore has been signalled.
 
static void cosema_wait (cosema_t *sema)
 Waits in a loop until the semaphore is signalled.
 
cothread_t cothread_create (cothread_entrypoint_t entrypoint, void *arg, size_t stack_size, unsigned int flags)
 Creates a thread and allocate the stack for it.
 
cothread_t cothread_create_manual (cothread_entrypoint_t entrypoint, void *arg, void *stack_base, size_t stack_size, unsigned int flags)
 Create a thread.
 
int cothread_delete (cothread_t thread)
 Deletes a running thread and frees all memory used by it.
 
int cothread_detach (cothread_t thread)
 Detach the specified thread.
 
cothread_t cothread_get_current (void)
 Returns ID of the thread that is running currently.
 
int cothread_get_exit_code (cothread_t thread)
 If the thread has ended, this function returns the exit code.
 
bool cothread_has_joined (cothread_t thread)
 Used to determine if a thread is running or if it has ended (joined).
 
void cothread_send_signal (uint32_t signal_id)
 Awake threads waiting for the provided signal ID.
 
void cothread_yield (void)
 Tells the scheduler to switch to a different thread.
 
void cothread_yield_irq (uint32_t flag)
 Tells the scheduler to switch to a different thread until the specified IRQ has happened.
 
void cothread_yield_irq_aux (uint32_t flag)
 Tells the scheduler to switch to a different thread until the specified ARM7 AUX IRQ has happened.
 
void cothread_yield_signal (uint32_t signal_id)
 Tells the scheduler to switch to a different thread until the specified signal ID is received.
 

Detailed Description

Cooperative multithreading system.

Only enabled in the ARM9 at the moment.

Function Documentation

◆ comutex_acquire()

static void comutex_acquire ( comutex_t mutex)
inlinestatic

Waits in a loop until the mutex is available.

The main body of the loop yields after each try so that other threads can take control of the CPU and eventually release the mutex.

Parameters
mutexPointer to the mutex.

◆ comutex_init()

static bool comutex_init ( comutex_t mutex)
inlinestatic

Initializes a mutex.

Parameters
mutexPointer to the mutex.
Returns
It returns true if the mutex has been initialized, false if not.

◆ comutex_release()

static void comutex_release ( comutex_t mutex)
inlinestatic

Releases a mutex.

It also sends a signal to all threads that may be waiting for this mutex.

Parameters
mutexPointer to the mutex.

◆ comutex_try_acquire()

static bool comutex_try_acquire ( comutex_t mutex)
inlinestatic

Tries to acquire a mutex without blocking execution.

Parameters
mutexPointer to the mutex.
Returns
It returns true if the mutex has been acquired, false if not.

◆ cosema_init()

static bool cosema_init ( cosema_t sema,
uint32_t  init_val 
)
inlinestatic

Initializes a counting semaphore to the desired value.

Parameters
semaPointer to the semaphore.
init_valInitial value (zero or a positive integer).
Returns
It returns true if the semaphore has been initialized, false if not.

◆ cosema_signal()

static void cosema_signal ( cosema_t sema)
inlinestatic

Signals a semaphore.

It increases the semaphore counter so that other threads can access the resources protected by the semaphore. It also sends a signal to all threads that may be waiting for this semaphore.

Parameters
semaPointer to the semaphore.

◆ cosema_try_wait()

static bool cosema_try_wait ( cosema_t sema)
inlinestatic

Checks if a semaphore has been signalled.

It checks the value of the semaphore and returns right away instead of waiting for the semaphore to be signalled.

Parameters
semaPointer to the semaphore.
Returns
If the semaphore has been signalled it returns true. If not, false.

◆ cosema_wait()

static void cosema_wait ( cosema_t sema)
inlinestatic

Waits in a loop until the semaphore is signalled.

The main body of the loop yields after each try so that other threads can take control of the CPU and eventually signal the semaphore.

Parameters
semaPointer to the semaphore.

◆ cothread_create()

cothread_t cothread_create ( cothread_entrypoint_t  entrypoint,
void *  arg,
size_t  stack_size,
unsigned int  flags 
)

Creates a thread and allocate the stack for it.

This stack will be freed when the thread is deleted.

Important: If this thread is going to do filesystem accesses, you need to assign it a reasonably big stack size.

Parameters
entrypointFunction to be run. The argument is the value of 'arg' passed to cothread_create().
argArgument to be passed to entrypoint.
stack_sizeSize of the stack. If it is set to zero it will use a default value. If non-zero, it must be aligned to 64 bit.
flagsSet of ORed flags (like COTHREAD_DETACHED) or 0.
Returns
On success, it returns a non-negative value representing the thread ID. On failure, it returns -1 and sets errno.

◆ cothread_create_manual()

cothread_t cothread_create_manual ( cothread_entrypoint_t  entrypoint,
void *  arg,
void *  stack_base,
size_t  stack_size,
unsigned int  flags 
)

Create a thread.

The stack is owned by the caller of this function, and it has to be freed manually after the thread ends.

Parameters
entrypointFunction to be run. The argument is the value of 'arg' passed to cothread_create_manual().
argArgument to be passed to entrypoint.
stack_basePointer to the base of the memory to be used as stack. It must be aligned to 64 bit.
stack_sizeSize of the stack. Must be aligned to 64 bit.
flagsSet of ORed flags (like COTHREAD_DETACHED) or 0.
Returns
On success, it returns a non-negative value representing the thread ID. On failure, it returns -1 and sets errno.

◆ cothread_delete()

int cothread_delete ( cothread_t  thread)

Deletes a running thread and frees all memory used by it.

It isn't possible to delete the currently running thread.

Parameters
threadThread ID.
Returns
On success, it returns 0. On failure, it returns -1 and sets errno.

◆ cothread_detach()

int cothread_detach ( cothread_t  thread)

Detach the specified thread.

Parameters
threadThe thread to detach.
Returns
On success, it returns 0. On failure, it returns -1 and sets errno.

◆ cothread_get_current()

cothread_t cothread_get_current ( void  )

Returns ID of the thread that is running currently.

Returns
Thread ID of the current thread.

◆ cothread_get_exit_code()

int cothread_get_exit_code ( cothread_t  thread)

If the thread has ended, this function returns the exit code.

Don't call this if the thread is detached, it will never return an exit code because the thread information will be deleted as soon as the thread ends (and, at that point, it won't exist, so the function will return an error code).

Parameters
threadThread ID.
Returns
Returns the exit code if the thread has finished, -1 otherwise. It will set errno as well (for example, if the thread is still running, it will set errno to EBUSY).

◆ cothread_has_joined()

bool cothread_has_joined ( cothread_t  thread)

Used to determine if a thread is running or if it has ended (joined).

Don't call this if the thread is detached. It will always return false because as soon as the thread ends all information associated to it will be deleted (and, at that point, it won't exist, so the function will return false along an error code).

Parameters
threadThread ID.
Returns
Returns true if the thread has ended, false otherwise. It can also set errno.

◆ cothread_send_signal()

void cothread_send_signal ( uint32_t  signal_id)

Awake threads waiting for the provided signal ID.

All threads waiting for this signal ID will wake up.

User-defined signal IDs aren't allowed to use numbers greater than 0x7FFFFFFF. Bit 31 is reserved for system signal IDs.

Parameters
signal_idA user-defined number.

◆ cothread_yield()

void cothread_yield ( void  )

Tells the scheduler to switch to a different thread.

This can also be called from main().

◆ cothread_yield_irq()

void cothread_yield_irq ( uint32_t  flag)

Tells the scheduler to switch to a different thread until the specified IRQ has happened.

Parameters
flagIRQ flag to wait for (only one).

◆ cothread_yield_irq_aux()

void cothread_yield_irq_aux ( uint32_t  flag)

Tells the scheduler to switch to a different thread until the specified ARM7 AUX IRQ has happened.

Parameters
flagAUX IRQ flag to wait for (only one).
Note
ARM7 only.

◆ cothread_yield_signal()

void cothread_yield_signal ( uint32_t  signal_id)

Tells the scheduler to switch to a different thread until the specified signal ID is received.

The thread will wait until cothread_send_signal() is called with the same signal ID.

User-defined signal IDs aren't allowed to use numbers greater than 0x7FFFFFFF. Bit 31 is reserved for system signal IDs.

Parameters
signal_idA user-defined number.