CDI SDK
SDK for transporting chunks of data reliably and with low latency using a polled mode network driver.
Loading...
Searching...
No Matches
os_linux.c File Reference

This file contains the Linux definitions for OS functions for creating/deleting threads, semaphores, mutexes, and also for sleeps and string copies. More...

#include "cdi_os_api.h"
#include <arpa/inet.h>
#include <assert.h>
#include <dirent.h>
#include <errno.h>
#include <malloc.h>
#include <netdb.h>
#include <netinet/ip.h>
#include <poll.h>
#include <pthread.h>
#include <semaphore.h>
#include <signal.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/socket.h>
#include <sys/uio.h>
#include <unistd.h>
#include "cdi_logger_api.h"

Data Structures

struct  CdiThreadInfo
 Structure to keep track of thread state info. More...
 
struct  SemInfo
 Structure used to hold semaphore state data. More...
 
struct  SignalInfo
 Structure used to hold signal state data. More...
 
struct  SocketInfo
 Structure used to hold semaphore state data. More...
 

Macros

#define __USE_XOPEN2K
 Linux definition.
 
#define _GNU_SOURCE
 _GNU_SOURCE Linux required for pthread_setname_np().
 
#define THREAD_STACK_SIZE   (1024*1024)
 Linux definition of stack size.
 
#define MAX_THREADS_WAITING   (50)
 Maximum number of threads that can register for notifications from another signal.
 
#define ERROR_MESSAGE(...)   LogMessage(kLogError, __FUNCTION__, __LINE__, __VA_ARGS__)
 Macro used within this file to handle generation of error messages either to the logger or stderr.
 
#define WARNING_MESSAGE(...)   LogMessage(kLogWarning, __FUNCTION__, __LINE__, __VA_ARGS__)
 Macro used within this file to handle generation of error messages either to the logger or stderr.
 
#define MAX_FORMATTED_MESSAGE_LENGTH   (1024)
 Maximum length of a single formatted message string.
 

Typedefs

typedef struct CdiThreadInfo CdiThreadInfo
 Thread Info is kept in a doubly-linked list.
 
typedef struct SemInfo SemInfo
 Forward declaration to create pointer to semaphore info when used.
 
typedef struct SignalInfo SignalInfo
 Forward declaration to create pointer to signal info when used.
 
typedef struct SocketInfo SocketInfo
 Forward declaration to create pointer to socket info when used.
 

Functions

static void LogMessage (CdiLogLevel level, const char *func_name_str, int line, const char *format_str,...)
 
static void GetTimeout (struct timespec *spec, uint32_t num_ms, clockid_t clock_id)
 
static void PopulateSigAction (struct sigaction *sig_act_ptr, CdiSignalHandlerFunction func_ptr)
 
static void * ThreadFuncHelper (void *thread_ptr)
 
static bool SocketWrite (CdiSocket socket_handle, const struct msghdr *msg_ptr, int *byte_count_ptr)
 
void CdiOsUseLogger (void)
 
bool CdiOsSignalHandlerSet (int signal_num, CdiSignalHandlerFunction func_ptr)
 
bool CdiOsThreadCreatePinned (CdiThreadFuncName thread_func, CdiThreadID *thread_id_out_ptr, const char *thread_name_str, void *thread_func_arg_ptr, CdiSignalType start_signal, int cpu_affinity)
 
bool CdiOsThreadAllocData (CdiThreadData *handle_out_ptr)
 
bool CdiOsThreadFreeData (CdiThreadData handle)
 
bool CdiOsThreadSetData (CdiThreadData handle, void *content_ptr)
 
bool CdiOsThreadGetData (CdiThreadData handle, void **content_out_ptr)
 
const char * CdiOsThreadGetName (CdiThreadID thread_id)
 
bool CdiOsThreadJoin (CdiThreadID thread_id, uint32_t timeout_in_ms, bool *timed_out_ptr)
 
bool CdiOsSemaphoreCreate (CdiSemID *ret_sem_handle_ptr, int sem_count)
 
bool CdiOsSemaphoreDelete (CdiSemID sem_handle)
 
bool CdiOsSemaphoreRelease (CdiSemID sem_handle)
 
bool CdiOsSemaphoreReserve (CdiSemID sem_handle, int timeout_in_ms)
 
int CdiOsSemaphoreValueGet (CdiSemID sem_handle)
 
bool CdiOsCritSectionCreate (CdiCsID *cs_handle_ptr)
 
void CdiOsCritSectionReserve (CdiCsID cs_handle)
 
void CdiOsCritSectionRelease (CdiCsID cs_handle)
 
bool CdiOsCritSectionDelete (CdiCsID cs_handle)
 
bool CdiOsSignalCreate (CdiSignalType *signal_handle_ptr)
 
bool CdiOsSignalDelete (CdiSignalType signal_handle)
 
bool CdiOsSignalClear (CdiSignalType signal_handle)
 
bool CdiOsSignalSet (CdiSignalType signal_handle)
 
bool CdiOsSignalGet (CdiSignalType signal_handle)
 
bool CdiOsSignalReadState (CdiSignalType signal_handle)
 
bool CdiOsSignalWait (CdiSignalType signal_handle, uint32_t timeout_in_ms, bool *timed_out_ptr)
 
bool CdiOsSignalsWait (CdiSignalType *signal_array, uint8_t num_signals, bool wait_all, uint32_t timeout_in_ms, uint32_t *ret_signal_index_ptr)
 
void * CdiOsMemAlloc (int64_t mem_size)
 
void * CdiOsMemAllocZero (int64_t mem_size)
 
void CdiOsMemFree (void *mem_ptr)
 
void * CdiOsMemAllocHugePage (int64_t mem_size)
 
void CdiOsMemFreeHugePage (void *mem_ptr, int64_t mem_size)
 
bool CdiOsOpenForWrite (const char *file_name_str, CdiFileID *file_handle_ptr)
 
bool CdiOsOpenForRead (const char *file_name_str, CdiFileID *file_handle_ptr)
 
bool CdiOsClose (CdiFileID file_handle)
 
bool CdiOsRead (CdiFileID file_handle, void *buffer_ptr, uint32_t byte_count, uint32_t *bytes_read_ptr)
 
bool CdiOsWrite (CdiFileID file_handle, const void *data_ptr, uint32_t byte_count)
 
bool CdiOsFlush (CdiFileID file_handle)
 
bool CdiOsFTell (CdiFileID file_handle, uint64_t *current_position_ptr)
 
bool CdiOsFSeek (CdiFileID file_handle, int64_t offset, int position)
 
bool CdiOsSplitPath (const char *filepath_str, char *filename_str, int filename_buf_size, char *directory_str, int directory_buf_size)
 
bool CdiOsIsPathWriteable (const char *directory_str)
 
int CdiOsStrCpy (char *dest_str, uint32_t max_str_len, const char *src_str)
 
void CdiOsSleep (uint32_t milliseconds)
 
void CdiOsSleepMicroseconds (uint32_t microseconds)
 
uint64_t CdiOsGetMicroseconds ()
 Timers get a microsecond timestamp from CLOCK_MONOTONIC on linux or from the performance counter on Windows.
 
void CdiOsGetUtcTime (struct timespec *ret_time_ptr)
 This is an OS call to get the current synced AWS network time in UTC format.
 
void CdiOsGetLocalTime (struct tm *local_time_ret_ptr)
 
int CdiOsGetLocalTimeString (char *time_str, int max_string_len)
 
bool CdiOsSocketOpen (const char *host_address_str, int port_number, const char *bind_address_str, CdiSocket *new_socket_ptr)
 
bool CdiOsSocketGetPort (CdiSocket socket_handle, int *port_number_ptr)
 
bool CdiOsSocketGetSockAddrIn (CdiSocket socket_handle, struct sockaddr_in *sockaddr_in_ptr)
 
bool CdiOsSocketClose (CdiSocket s)
 
bool CdiOsSocketRead (CdiSocket socket_handle, void *buffer_ptr, int *byte_count_ptr)
 
bool CdiOsSocketReadFrom (CdiSocket socket_handle, void *buffer_ptr, int *byte_count_ptr, struct sockaddr_in *source_address_ptr)
 
bool CdiOsSocketWrite (CdiSocket socket_handle, struct iovec *iov, int iovcnt, int *byte_count_ptr)
 
bool CdiOsSocketWriteTo (CdiSocket socket_handle, struct iovec *iov, int iovcnt, const struct sockaddr_in *destination_address_ptr, int *byte_count_ptr)
 
bool CdiOsEnvironmentVariableSet (const char *name_str, const char *value_str)
 
void CdiOsShutdown ()
 

Variables

static const clockid_t kPreferredClock = CLOCK_MONOTONIC
 Preferred clock used when doing timing calculations, because unaffected by system clock adjustments.
 
static CdiSignalHandlerInfo signal_handler_function_array [CDI_MAX_SIGNAL_HANDLERS]
 Array of data used to hold signal handlers.
 
static int signal_handler_count = 0
 Number of signal handlers in signal_handler_function_array.
 
static bool use_logger = false
 If true, the CDI logger will be used to generate error messages, otherwise output will be sent to stderr.
 

Detailed Description

This file contains the Linux definitions for OS functions for creating/deleting threads, semaphores, mutexes, and also for sleeps and string copies.

Function Documentation

◆ CdiOsClose()

bool CdiOsClose ( CdiFileID file_handle)

Closes a file.

Parameters
file_handleIdentifier of file to close.
Returns
true if successful, otherwise false.

◆ CdiOsCritSectionCreate()

bool CdiOsCritSectionCreate ( CdiCsID * cs_handle_ptr)

Creates and initializes a critical section.

Parameters
cs_handle_ptrPointer to critical section ID to return.
Returns
true if successful, otherwise false.

◆ CdiOsCritSectionDelete()

bool CdiOsCritSectionDelete ( CdiCsID cs_handle)

Deletes a critical section.

Parameters
cs_handlePointer to critical section ID to delete.
Returns
true if successful, otherwise false.

◆ CdiOsCritSectionRelease()

void CdiOsCritSectionRelease ( CdiCsID cs_handle)

Releases the specified critical section.

Parameters
cs_handleCritical section ID to release.

◆ CdiOsCritSectionReserve()

void CdiOsCritSectionReserve ( CdiCsID cs_handle)

Reserves the specified critical section.

Parameters
cs_handleCritical section ID to reserve.

◆ CdiOsEnvironmentVariableSet()

bool CdiOsEnvironmentVariableSet ( const char * name_str,
const char * value_str )

Set an environment variable for the currently running process. NOTE: Does not set the process's shell environment.

Parameters
name_strPointer to string name of variable to set. Assumed to be a non-NULL value.
value_strPointer to string value to set. NOTE: Cannot be NULL.
Returns
true if successful, otherwise false.

◆ CdiOsFlush()

bool CdiOsFlush ( CdiFileID file_handle)

Flushes write buffers for the specified file.

Parameters
file_handleIdentifier of the file to flush.
Returns
true if successful, otherwise false.

◆ CdiOsFSeek()

bool CdiOsFSeek ( CdiFileID file_handle,
int64_t offset,
int position )

Retrieves the current file position for the specified file.

Parameters
file_handleIdentifier of the file.
offsetNumber of bytes to offset from position.
positionThe position from where offset is added.
Returns
true if successful, otherwise false.

◆ CdiOsFTell()

bool CdiOsFTell ( CdiFileID file_handle,
uint64_t * current_position_ptr )

Retrieves the current file position for the specified file.

Parameters
file_handleIdentifier of the file.
current_position_ptrPointer to current position of the file.
Returns
true if successful, otherwise false.

◆ CdiOsGetLocalTime()

void CdiOsGetLocalTime ( struct tm * local_time_ret_ptr)

Get current local time as "tm" structure.

Parameters
local_time_ret_ptrPointer to returned local time.

◆ CdiOsGetLocalTimeString()

int CdiOsGetLocalTimeString ( char * time_str,
int max_string_len )

Get current local time as a formatted as ISO 8601.

Parameters
time_strFormatted string to represent ISO 8601 time format.
max_string_lenMaximum allowable characters in the time string.
Returns
char_count Returns the number of characters of the formatted string.

◆ CdiOsGetMicroseconds()

uint64_t CdiOsGetMicroseconds ( void )

Timers get a microsecond timestamp from CLOCK_MONOTONIC on linux or from the performance counter on Windows.

Returns
Microsecond timestamp.

◆ CdiOsGetUtcTime()

void CdiOsGetUtcTime ( struct timespec * ret_time_ptr)

This is an OS call to get the current synced AWS network time in UTC format.

This function will be kept up to date with the best practices for getting high accuracy time from Amazon Time Sync Service as improved accuracy time is available. All EC2 instances that call this function should be using the Amazon Time Sync Service. Amazon Time Sync Service setup directions for Linux can be found at: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/set-time.html#configure-amazon-time-service

For Windows follow the directions at: https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/windows-set-time.html

Parameters
ret_time_ptra pointer returned to a UTC timestamp in the format of a timespec structure as defined by time.h.

◆ CdiOsIsPathWriteable()

bool CdiOsIsPathWriteable ( const char * directory_str)

Takes in a directory string and verifies that the directory exists and is writeable.

Parameters
directory_strString containing the directory path, including any end '/' without the filename.
Returns
true if successful, otherwise false.

◆ CdiOsMemAlloc()

void * CdiOsMemAlloc ( int64_t mem_size)

Allocates a block of memory and returns a pointer to the start of the block.

Parameters
mem_sizeNumber of bytes to allocate.
Returns
Pointer to the allocated memory block. If unable to allocate the memory block, NULL is returned.

◆ CdiOsMemAllocHugePage()

void * CdiOsMemAllocHugePage ( int64_t mem_size)

Allocates a block of huge page memory and returns a pointer to the start of the block.

Parameters
mem_sizeNumber of bytes to allocate. Size must be a multiple of CDI_HUGE_PAGES_BYTE_SIZE. If not, NULL is returned.
Returns
Pointer to the allocated memory block. If unable to allocate the memory block, NULL is returned.

◆ CdiOsMemAllocZero()

void * CdiOsMemAllocZero ( int64_t mem_size)

Allocates a block of memory, writes zero across its entirety, and returns a pointer to the start of the block.

Parameters
mem_sizeNumber of bytes to allocate.
Returns
Pointer to the allocated memory block. If unable to allocate the memory block, NULL is returned.

◆ CdiOsMemFree()

void CdiOsMemFree ( void * mem_ptr)

Releases a previously allocated block of memory.

Parameters
mem_ptrPointer to start address of memory block.

◆ CdiOsMemFreeHugePage()

void CdiOsMemFreeHugePage ( void * mem_ptr,
int64_t mem_size )

Releases a previously allocated block of huge page memory.

Parameters
mem_ptrPointer to start address of memory block.
mem_sizeNumber of bytes that were allocated.

◆ CdiOsOpenForRead()

bool CdiOsOpenForRead ( const char * file_name_str,
CdiFileID * file_handle_ptr )

Opens a file (file_name_str) for read and returns a file handle.

Parameters
file_name_strPointer to filename to open.
file_handle_ptrAddress where to write returned file handle.
Returns
true if successful, otherwise false.

◆ CdiOsOpenForWrite()

bool CdiOsOpenForWrite ( const char * file_name_str,
CdiFileID * file_handle_ptr )

Opens a file (file_name_str) for writing and returns a file handle.

Parameters
file_name_strPointer to filename to open.
file_handle_ptrAddress where to write returned file handle.
Returns
true if successful, otherwise false.

◆ CdiOsRead()

bool CdiOsRead ( CdiFileID file_handle,
void * buffer_ptr,
uint32_t byte_count,
uint32_t * bytes_read_ptr )

Reads data from a file.

Parameters
file_handleIdentifier of file to read from.
buffer_ptrPointer to buffer to read in to.
byte_countNumber of bytes to read into the buffer pointed to by buffer_ptr.
bytes_read_ptrReturns the number of bytes read (NULL if you don't care).
Returns
true if successful, otherwise false. Check EOF using OS's EOF API function.

◆ CdiOsSemaphoreCreate()

bool CdiOsSemaphoreCreate ( CdiSemID * ret_sem_handle_ptr,
int sem_count )

Creates a semaphore.

Parameters
ret_sem_handle_ptrPointer to semaphore ID to return.
sem_countInitial semaphore count.
Returns
true if successful, otherwise false.

◆ CdiOsSemaphoreDelete()

bool CdiOsSemaphoreDelete ( CdiSemID sem_handle)

Deletes a semaphore.

Parameters
sem_handlePointer to semaphore ID to delete.
Returns
returns true if successful, otherwise false is returned.

◆ CdiOsSemaphoreRelease()

bool CdiOsSemaphoreRelease ( CdiSemID sem_handle)

Releases a semaphore.

Parameters
sem_handleSemaphore ID to release.
Returns
true if successful, otherwise false.

◆ CdiOsSemaphoreReserve()

bool CdiOsSemaphoreReserve ( CdiSemID sem_handle,
int timeout_in_ms )

Reserves a semaphore and blocks if the current semaphore count is 0. If the semaphore is already reserved by the calling thread, then this call simply returns success.

Parameters
sem_handleSemaphore ID to reserve.
timeout_in_msAmount of miliseconds to wait for the semaphore, CDI_INFINITE to wait indefinitely.
Returns
true if successful, otherwise false.

◆ CdiOsSemaphoreValueGet()

int CdiOsSemaphoreValueGet ( CdiSemID sem_handle)

Returns the value of the given semaphore (ie. how many semaphore resources are available).

Parameters
sem_handleSemaphore ID to check.
Returns
Value of semaphore.

◆ CdiOsShutdown()

void CdiOsShutdown ( void )

Shuts down OS specific resources used by the SDK.

◆ CdiOsSignalClear()

bool CdiOsSignalClear ( CdiSignalType signal_handle)

This function clears a signal.

Parameters
signal_handleA signal handle to clear the value of.
Returns
true if successful, otherwise false.

◆ CdiOsSignalCreate()

bool CdiOsSignalCreate ( CdiSignalType * signal_handle_ptr)

This function creates a signal. The initial value is not signaled.

Parameters
signal_handle_ptrAddress where to write the returned signal handle.
Returns
true if successful, otherwise false.

◆ CdiOsSignalDelete()

bool CdiOsSignalDelete ( CdiSignalType signal_handle)

This function deletes a signal.

Parameters
signal_handleA signal handle to delete.
Returns
true if successful, otherwise false.

◆ CdiOsSignalGet()

bool CdiOsSignalGet ( CdiSignalType signal_handle)

This function returns the value of the signal passed in.

Parameters
signal_handleA signal handle to get the value of.
Returns
true if successful, otherwise false.

◆ CdiOsSignalHandlerSet()

bool CdiOsSignalHandlerSet ( int signal_num,
CdiSignalHandlerFunction func_ptr )

Set the address to the default signal handler function shared by all threads.

Parameters
signal_numNumber of the signal to set the new handler.
func_ptrAddress of signal handler function to set for the signal.
Returns
true on success, false if there isn't enough storage to hold the signal or if there was an error.

◆ CdiOsSignalReadState()

bool CdiOsSignalReadState ( CdiSignalType signal_handle)

This function returns the value of the signal passed in without using any OS resources. It only accesses state data.

Parameters
signal_handleA signal handle to read the state value of.
Returns
true if successful, otherwise false.

◆ CdiOsSignalSet()

bool CdiOsSignalSet ( CdiSignalType signal_handle)

This function sets a signal and its related state variable.

Parameters
signal_handleA signal handle to set the value of.
Returns
true if successful, otherwise false.

◆ CdiOsSignalsWait()

bool CdiOsSignalsWait ( CdiSignalType * signal_array,
uint8_t num_signals,
bool wait_all,
uint32_t timeout_in_ms,
uint32_t * ret_signal_index_ptr )

This function waits for an array of signals.

Parameters
signal_arrayPointer to an array of signal handles to wait on.
num_signalsNumber of signals in the array.
wait_allUse true to wait for all signals, false to block on any signal.
timeout_in_msTimeout in mSec can be CDI_INFINITE to wait indefinitely.
ret_signal_index_ptrPointer to the returned signal index that caused the thread to be signaled. if wait_all is true, then this is set to 1 when all signals are signaled. If a timeout occurred, CDI_OS_SIG_TIMEOUT is returned. This is an optional parameter, you can pass NULL if you don't care.
Returns
true if successful, otherwise false.

◆ CdiOsSignalWait()

bool CdiOsSignalWait ( CdiSignalType signal_handle,
uint32_t timeout_in_ms,
bool * timed_out_ptr )

This function waits for a signal.

Parameters
signal_handleA signal handle to wait on.
timeout_in_msTimeout in mSec can be CDI_INFINITE to wait indefinitely.
timed_out_ptrPointer to boolean - set to true if timed out.
Returns
true if successful, otherwise false.

◆ CdiOsSleep()

void CdiOsSleep ( uint32_t milliseconds)

Block the current thread for the specified number of milliseconds.

Parameters
millisecondsBlock thread for this much time.

◆ CdiOsSleepMicroseconds()

void CdiOsSleepMicroseconds ( uint32_t microseconds)

Block the current thread for microseconds.

Parameters
microsecondsBlock thread for this much time.

◆ CdiOsSocketClose()

bool CdiOsSocketClose ( CdiSocket socket_handle)

Close a previously opened communications socket, freeing resources that were allocated for it including the local port if the socket was opened for receiving.

Parameters
socket_handleThe handle of the socket which is to be closed.
Returns
true if the socket was closed cleanly, false if a problem was encountered trying to close it.

◆ CdiOsSocketGetPort()

bool CdiOsSocketGetPort ( CdiSocket socket_handle,
int * port_number_ptr )

Gets the number of the port to which the specified socket is bound. This is useful for receive sockets opened with their port number specified as 0, which makes the operating system assign a random port number. It also works on transmit sockets which are also randomly assigned a port number.

Parameters
socket_handleThe socket whose port number is of interest.
port_number_ptrAddress of where the port number will be written.
Returns
true if the port number could be determined or false if a problem was encountered.

◆ CdiOsSocketGetSockAddrIn()

bool CdiOsSocketGetSockAddrIn ( CdiSocket socket_handle,
struct sockaddr_in * sockaddr_in_ptr )

Gets the sockaddr_in structure to which the specified socket is bound.

Parameters
socket_handleThe socket whose port number is of interest.
sockaddr_in_ptrAddress of where the sockaddr_in data will be written.
Returns
true if the sockaddr_in data could be determined or false if a problem was encountered.

◆ CdiOsSocketOpen()

bool CdiOsSocketOpen ( const char * host_address_str,
int port_number,
const char * bind_address_str,
CdiSocket * new_socket_ptr )

Opens a unidirectional or bidirectional Internet Protocol User Datagram Protocol (IP/UDP) socket for communications. For a unidirectional socket to send on, specify the host address of the remote host. To create a unidirectional socket for receiving, specify NULL as host_address_str.

For a bidirectional socket, where datagrams can be sent and received through the socket, specify NULL as host_address_str for both client and server sides. For the client side, specify zero for port_number so a randomly selected port number is used. Call

See also
CdiOsSocketGetPort to determine the port number that was assigned. When sending datagrams, Use
CdiOsSocketWriteTo to specify the remote destination address and port. For the server side, specify the local port number for port_number to listen for incoming datagrams. Use
CdiOsSocketReadFrom so that the datagram's source host's IP address and port number are provided.
Parameters
host_address_strThe address of the remote host (dotted IPv4 address) to which to send datagrams or NULL if the socket is to be used for receiving datagrams or is bidirectional.
port_numberFor a unidirectional send-only socket, the numeric port number on the remote host. For a unidirectional receive only socket or server side of a bidirectional socket, the local port number to listen for incoming datagrams. For the client side of a bidirectional socket, use zero for this value so that a randomly selected port number is used. Call
See also
CdiOsSocketGetPort to determine the port number that was assigned.
Parameters
bind_address_strOptional bind address (dotted IPv4 address). If NULL, default interface is used.
new_socket_ptrA pointer to the location which will get the new socket handle written to it.
Returns
true if the socket was successfully opened and is ready for communications, otherwise false.

◆ CdiOsSocketRead()

bool CdiOsSocketRead ( CdiSocket socket_handle,
void * buffer_ptr,
int * byte_count_ptr )

Synchronously reads the next available datagram from the specified socket. If no datagram is available after a short timeout, true is returned but the value written to byte_count_ptr will be zero. This timeout is so that the caller can periodically check whether to shut down its polling loop.

Parameters
socket_handleThe handle for the socket for which incoming datagrams are to be received.
buffer_ptrThe address in memory where the bytes of the datagram will be written.
byte_count_ptrOn entry, the value at the location pointed to must be the size of the buffer at buffer_ptr available for the datagram to be written. At exit, the address will be overwritten with the number of bytes that are actually contained in the datagram and thus written to the buffer. A value of 0 indicates that the read timed out waiting for a datagram and that the read should be retried unless the polling process should be shut down.
Returns
true if the function succeeded, false if it failed. Timing out is considered to be success but zero will have been written to byte_count_ptr to disambiguate a timeout condition from data being written into the buffer.

◆ CdiOsSocketReadFrom()

bool CdiOsSocketReadFrom ( CdiSocket socket_handle,
void * buffer_ptr,
int * byte_count_ptr,
struct sockaddr_in * source_address_ptr )

Synchronously reads the next available datagram from the specified socket and provides the source IP address/port number. If no datagram is available after a short timeout, true is returned but the value written to byte_count_ptr will be zero. This timeout is so that the caller can periodically check whether to shut down its polling loop.

Parameters
socket_handleThe handle for the socket for which incoming datagrams are to be received.
buffer_ptrThe address in memory where the bytes of the datagram will be written.
byte_count_ptrOn entry, the value at the location pointed to must be the size of the buffer at buffer_ptr available for the datagram to be written. At exit, the address will be overwritten with the number of bytes that are actually contained in the datagram and thus written to the buffer. A value of 0 indicates that the read timed out waiting for a datagram and that the read should be retried unless the polling process should be shut down.
source_address_ptrPointer to memory where the source address and port number from the UDP packet will be written so that the caller can determine where to send replies.
Returns
true if the function succeeded, false if it failed. Timing out is considered to be success but zero will have been written to byte_count_ptr to disambiguate a timeout condition from data being written into the buffer.

◆ CdiOsSocketWrite()

bool CdiOsSocketWrite ( CdiSocket socket_handle,
struct iovec * iov,
int iovcnt,
int * byte_count_ptr )

Synchronously write a datagram to a communications socket. The data is represented as an array of address pointers and sizes. This data is copied inside of the function so once it returns the buffer(s) are available for reuse.

Parameters
socket_handleThe handle for the socket through which the datagram will be written.
iovThe address of an array of iovec structures which specify the data to be sent.
iovcntThe number of iovec structures contained in the iov array. This value is limited to CDI_OS_SOCKET_MAX_IOVCNT.
byte_count_ptrThe address of a location into which the number of bytes written to the socket will be placed if the datagram was successfully sent.
Returns
true if the datagram was successfully sent, false if not. Note that there is no guarantee that the datagram was actually received by the destination host.

◆ CdiOsSocketWriteTo()

bool CdiOsSocketWriteTo ( CdiSocket socket_handle,
struct iovec * iov,
int iovcnt,
const struct sockaddr_in * destination_address_ptr,
int * byte_count_ptr )

Synchronously write a datagram to a communications socket. The data is represented as an array of address pointers and sizes. This data is copied inside of the function so once it returns the buffer(s) are available for reuse.

Parameters
socket_handleThe handle for the socket through which the datagram will be written.
iovThe address of an array of iovec structures which specify the data to be sent.
iovcntThe number of iovec structures contained in the iov array. This value is limited to RMT_OS_SOCKET_MAX_IOVCNT.
destination_address_ptrPointer to the destination (IP address and port number) to which to send the UDP packet.
byte_count_ptrThe address of a location into which the number of bytes written to the socket will be placed if the datagram was successfully sent.
Returns
true if the datagram was successfully sent, false if not. Note that there is no guarantee that the datagram was actually received by the destination host.

◆ CdiOsSplitPath()

bool CdiOsSplitPath ( const char * filepath_str,
char * filename_str,
int filename_buf_size,
char * directory_str,
int directory_buf_size )

Takes in a filepath and breaks it into its component directory and filename.

Parameters
filepath_strString containing a path name and filename.
filename_strString containing the filename without the path. Pass NULL for this parameter if the filename is not needed.
filename_buf_sizeSize of the buffer sent for storing the filename string.
directory_strString containing the directory path, including any end '/' without the filename. Pass NULL for this parameter if the directory path is not needed.
directory_buf_sizeSize of the buffer sent for storing the directory path string.
Returns
true if successful, otherwise false.

◆ CdiOsStrCpy()

int CdiOsStrCpy ( char * dest_str,
uint32_t max_str_len,
const char * src_str )

A portable version of strcpy with range checking to replace Microsoft's strcpy_s.

Parameters
dest_strBuffer to receive copied string.
max_str_lenMaximum number of characters to copy. This includes the terminating '\0'.
src_strSource string to copy.
Returns
Number of characters copied.

◆ CdiOsThreadAllocData()

bool CdiOsThreadAllocData ( CdiThreadData * handle_out_ptr)

Allocates a slot of thread-local storage. The slot is allocated once for the whole program, after which each thread can store and read private data from the slot.

Parameters
handle_out_ptrReturned handle for a thread data slot.
Returns
true if successful, otherwise false.

◆ CdiOsThreadCreatePinned()

bool CdiOsThreadCreatePinned ( CdiThreadFuncName thread_func,
CdiThreadID * thread_id_out_ptr,
const char * thread_name_str,
void * thread_func_arg_ptr,
CdiSignalType start_signal,
int cpu_affinity )

Creates a thread which can optionally be pinned to a specific CPU.

Parameters
thread_funcPointer to a function for the thread.
thread_id_out_ptrPointer to CdiThreadID to return.
thread_name_strOptional Thread Name for debugging and logging purposes (NULL if don't care).
thread_func_arg_ptrOptional pointer to user data passed to the thread delegate.
start_signalOptional signal used to start the thread. If NULL, thread starts running immediately.
cpu_affinityZero-based CPU number to pin this thread to, -1 to not pin.
Returns
true if successful, otherwise false.

◆ CdiOsThreadFreeData()

bool CdiOsThreadFreeData ( CdiThreadData handle)

Frees a slot of thread-local storage. Should be called before program exit but after all threads are done using the slot.

Parameters
handleHandle of thread data to free.
Returns
true if successful, otherwise false.

◆ CdiOsThreadGetData()

bool CdiOsThreadGetData ( CdiThreadData handle,
void ** content_out_ptr )

Get the value of this thread's copy of a thread-local storage slot.

Parameters
handleHandle to thread data slot.
content_out_ptrPointer to a variable which receives the data.
Returns
true if successful, otherwise false.

◆ CdiOsThreadGetName()

const char * CdiOsThreadGetName ( CdiThreadID thread_id)

Get the name of the thread that was created using CdiOsThreadCreatePinned().

Parameters
thread_idData structure for thread to get name.
Returns
Pointer to name of the thread.

◆ CdiOsThreadJoin()

bool CdiOsThreadJoin ( CdiThreadID thread_id,
uint32_t timeout_in_ms,
bool * timed_out_ptr )

Waits/blocks until the given thread has finished.

Parameters
thread_idData structure for thread to wait for.
timeout_in_msHow long to wait for join before timing out.
timed_out_ptrPointer to a boolean that indicates a timeout has occurred when true.
Returns
true if successful, otherwise false.

◆ CdiOsThreadSetData()

bool CdiOsThreadSetData ( CdiThreadData handle,
void * content_ptr )

Stores a value in this thread's copy of a thread-local storage slot. Calls to osThreadGetData from the same thread will get this value back. The slot must have been allocated by CdiOsThreadAllocData.

Parameters
handleHandle to thread data slot.
content_ptrPointer to be stored in the slot.
Returns
true if successful, otherwise false.

◆ CdiOsUseLogger()

void CdiOsUseLogger ( void )

Enable use of the logger when generating error messages. This function is normally used internally as part of initialization of the CDI SDK. If it is not used, then output will be directed to stderr.

◆ CdiOsWrite()

bool CdiOsWrite ( CdiFileID file_handle,
const void * data_ptr,
uint32_t byte_count )

Writes a file.

Parameters
file_handleIdentifier of file to write to.
data_ptrPointer to data to write.
byte_countNumber of bytes to write.
Returns
true if successful, otherwise false.

◆ GetTimeout()

static void GetTimeout ( struct timespec * spec,
uint32_t num_ms,
clockid_t clock_id )
static

Get the time for a given delay (timeout) and return it.

Parameters
specA timespec pointer for the resulting time calculation.
num_msThe number of milliseconds into the future to calculate.
clock_idClock to use (CLOCK_REALTIME, CLOCK_MONOTONIC, CLOCK_PROCESS_CPUTIME_ID, CLOCK_THREAD_CPUTIME_ID).

◆ LogMessage()

static void LogMessage ( CdiLogLevel level,
const char * func_name_str,
int line,
const char * format_str,
... )
static

Generate an error message and send to logger or stderr.

Parameters
levelThe log level.
func_name_strPointer to function name string.
lineSource line number.
format_strPointer to format string.
...Variable length list of message arguments.

◆ PopulateSigAction()

static void PopulateSigAction ( struct sigaction * sig_act_ptr,
CdiSignalHandlerFunction func_ptr )
static

This populates the sigaction structure with the appropriate flags and user-defined callback.

Parameters
sig_act_ptrThe pointer to the sigaction structure.
func_ptrThe pointer to the callback that executes on an intercepted signal.

◆ SocketWrite()

static bool SocketWrite ( CdiSocket socket_handle,
const struct msghdr * msg_ptr,
int * byte_count_ptr )
static

Helper function to write an IPv4 UDP packet through a socket.

Parameters
socket_handleThe handle of the socket through which to send the UDP packet.
msg_ptrStructure with the details of the packet and optionally the destination address/port.
byte_count_ptrAddress where to write the number of bytes written to the socket; this pointer is only accessed if the function returns true.
Returns
bool true if the write was successful, false if not.

◆ ThreadFuncHelper()

static void * ThreadFuncHelper ( void * thread_ptr)
static

When we create a thread, we use ThreadFuncHelper so that the is_done signal can be set. The only reason for this is so we can timeout when we try to join the thread. (Our osSignalWait can timeout but pthread_join can't.)

Parameters
thread_ptrThe pointer to the thread info.