Skip to content

File dp_thread.h

FileList > doppler > dp_thread.h

Go to the source code of this file

The threading primitives doppler uses, with one platform split. More...

  • #include "doppler/dp_once.h"
  • #include <pthread.h>
  • #include <sched.h>
  • #include <time.h>
  • #include <unistd.h>

Public Types

Type Name
typedef pthread_cond_t dp_cond_t
typedef pthread_mutex_t dp_mutex_t
typedef pthread_t dp_thread_t

Public Static Functions

Type Name
void dp_cond_broadcast (dp_cond_t * c)
void dp_cond_destroy (dp_cond_t * c)
void dp_cond_init (dp_cond_t * c)
void dp_cond_signal (dp_cond_t * c)
void dp_cond_wait (dp_cond_t * c, dp_mutex_t * m)
int dp_cpu_count (void)
Online processor count, or 1 if it cannot be determined.
void dp_mutex_destroy (dp_mutex_t * m)
void dp_mutex_init (dp_mutex_t * m)
void dp_mutex_lock (dp_mutex_t * m)
void dp_mutex_unlock (dp_mutex_t * m)
int dp_thread_create (dp_thread_t * t, void *(*)(void *) fn, void * arg)
Starts fn on a new thread. Returns 0 on success.
int dp_thread_join (dp_thread_t t)
Waits for t to finish and releases it. Returns 0 on success, as pthread_join does, so a caller that asserted the join can still.
void dp_thread_sleep_us (unsigned us)
Sleeps for at least us _microseconds. For "let the other thread
get there", never for timing._
void dp_thread_yield (void)
Gives up the rest of this thread's time slice.

Macros

Type Name
define DP_THREAD_FN (name, arg) static void \*name (void \*arg)
Declares a thread entry point portably. arg is a declarator name, so it cannot be parenthesised. NOLINTNEXTLINE(bugprone-macro-parentheses)
define DP_THREAD_RETURN return NULL
Returns from a DP_THREAD_FN body.

Detailed Description

A mutex, a condition variable, a joinable thread and a core count. That is the entire set doppler needs dp_tlm_capture (a writer thread behind a mutex and two condvars) and dp_parallel (a bounded parallel-for) both use exactly these and nothing more.

Why a shim rather than #ifdef at each call site: those two files carry thirty-three and twenty-odd pthread calls respectively, and scattering a platform conditional through a working producer/consumer is how a deadlock gets introduced by a port that "only changed includes". One home, both platforms, and the call sites stay readable.

The Windows side is Vista-era and deliberately not pthreads-win32:

pthread Win32
pthread_mutex_t SRWLOCK (smaller and faster than a
CRITICAL_SECTION, and doppler never
needs recursion)
pthread_cond_t CONDITION_VARIABLE
pthread_cond_wait SleepConditionVariableSRW
pthread_create/join _beginthreadex / WaitForSingleObject
sysconf(_SC_NPROCESSORS_ONLN) GetActiveProcessorCount
pthread_once InitOnceExecuteOnce, both behind
dp_once() (dp_once.h, included here)

A one-time build has its own header and its own dp_once.c because the tables it guards live in components that start no thread (AWGN, LO, CCSDS): they include dp_once.h alone, and <windows.h> stays inside dp_once.c (doppler#2328).

_beginthreadex rather than CreateThread: a thread that touches the CRT (these do malloc, and the capture writer does file I/O) needs the CRT's per-thread state initialised, and CreateThread does not do it.

Neither SRWLOCK nor CONDITION_VARIABLE has a destructor, so the destroy calls are no-ops on Windows rather than absent the call sites keep their symmetry and a reader is not left wondering which platform leaked.

Public Types Documentation

typedef dp_cond_t

typedef pthread_cond_t dp_cond_t;

typedef dp_mutex_t

typedef pthread_mutex_t dp_mutex_t;

typedef dp_thread_t

typedef pthread_t dp_thread_t;

Public Static Functions Documentation

function dp_cond_broadcast

static inline void dp_cond_broadcast (
    dp_cond_t * c
) 

function dp_cond_destroy

static inline void dp_cond_destroy (
    dp_cond_t * c
) 

function dp_cond_init

static inline void dp_cond_init (
    dp_cond_t * c
) 

function dp_cond_signal

static inline void dp_cond_signal (
    dp_cond_t * c
) 

function dp_cond_wait

static inline void dp_cond_wait (
    dp_cond_t * c,
    dp_mutex_t * m
) 

function dp_cpu_count

Online processor count, or 1 if it cannot be determined.

static inline int dp_cpu_count (
    void
) 


function dp_mutex_destroy

static inline void dp_mutex_destroy (
    dp_mutex_t * m
) 

function dp_mutex_init

static inline void dp_mutex_init (
    dp_mutex_t * m
) 

function dp_mutex_lock

static inline void dp_mutex_lock (
    dp_mutex_t * m
) 

function dp_mutex_unlock

static inline void dp_mutex_unlock (
    dp_mutex_t * m
) 

function dp_thread_create

Starts fn on a new thread. Returns 0 on success.

static inline int dp_thread_create (
    dp_thread_t * t,
    void *(*)(void *) fn,
    void * arg
) 


function dp_thread_join

Waits for t to finish and releases it. Returns 0 on success, as pthread_join does, so a caller that asserted the join can still.

static inline int dp_thread_join (
    dp_thread_t t
) 


function dp_thread_sleep_us

Sleeps for at least us microseconds. For "let the other thread get there", never for timing.

static inline void dp_thread_sleep_us (
    unsigned us
) 


function dp_thread_yield

Gives up the rest of this thread's time slice.

static inline void dp_thread_yield (
    void
) 


Macro Definition Documentation

define DP_THREAD_FN

Declares a thread entry point portably. arg is a declarator name, so it cannot be parenthesised. NOLINTNEXTLINE(bugprone-macro-parentheses)

#define DP_THREAD_FN (
    name,
    arg
) `static void *name (void *arg)`


define DP_THREAD_RETURN

Returns from a DP_THREAD_FN body.

#define DP_THREAD_RETURN `return NULL`



The documentation for this class was generated from the following file native/inc/doppler/dp_thread.h