910 lines
24 KiB
C
910 lines
24 KiB
C
/* $Header: /pjproject-0.3/pjlib/include/pj/os.h 12 10/29/05 11:30a Bennylp $ */
|
|
|
|
#ifndef __PJ_OS_H__
|
|
#define __PJ_OS_H__
|
|
|
|
/**
|
|
* @file os.h
|
|
* @brief OS dependent functions
|
|
*/
|
|
#include <pj/types.h>
|
|
|
|
PJ_BEGIN_DECL
|
|
|
|
/**
|
|
* @defgroup PJ_OS Operating System Dependent Functionality.
|
|
* @ingroup PJ
|
|
*/
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
/**
|
|
* @defgroup PJ_THREAD Threads
|
|
* @ingroup PJ_OS
|
|
* @{
|
|
* This module provides multithreading API.
|
|
*
|
|
* \section pj_thread_examples_sec Examples
|
|
*
|
|
* For examples, please see:
|
|
* - \ref page_pjlib_thread_test
|
|
* - \ref page_pjlib_sleep_test
|
|
*
|
|
*/
|
|
|
|
/**
|
|
* Thread creation flags:
|
|
* - PJ_THREAD_SUSPENDED: specify that the thread should be created suspended.
|
|
*/
|
|
typedef enum pj_thread_create_flags
|
|
{
|
|
PJ_THREAD_SUSPENDED = 1
|
|
} pj_thread_create_flags;
|
|
|
|
|
|
/**
|
|
* Specify this as \a stack_size argument in #pj_thread_create() to specify
|
|
* that thread should use default stack size for the current platform.
|
|
*/
|
|
#define PJ_THREAD_DEFAULT_STACK_SIZE 0
|
|
|
|
/**
|
|
* Type of thread entry function.
|
|
*/
|
|
typedef int (PJ_THREAD_FUNC pj_thread_proc)(void*);
|
|
|
|
/**
|
|
* Size of thread struct.
|
|
*/
|
|
#if !defined(PJ_THREAD_DESC_SIZE)
|
|
# define PJ_THREAD_DESC_SIZE (16)
|
|
#endif
|
|
|
|
/**
|
|
* Thread structure, to thread's state when the thread is created by external
|
|
* or native API.
|
|
*/
|
|
typedef long pj_thread_desc[PJ_THREAD_DESC_SIZE];
|
|
|
|
/**
|
|
* Get process ID.
|
|
* @return process ID.
|
|
*/
|
|
PJ_DECL(pj_uint32_t) pj_getpid(void);
|
|
|
|
/**
|
|
* Create a new thread.
|
|
*
|
|
* @param pool The memory pool from which the thread record
|
|
* will be allocated from.
|
|
* @param thread_name The optional name to be assigned to the thread.
|
|
* @param proc Thread entry function.
|
|
* @param arg Argument to be passed to the thread entry function.
|
|
* @param stack_size The size of the stack for the new thread, or ZERO or
|
|
* PJ_THREAD_DEFAULT_STACK_SIZE to let the
|
|
* library choose the reasonable size for the stack.
|
|
* For some systems, the stack will be allocated from
|
|
* the pool, so the pool must have suitable capacity.
|
|
* @param flags Flags for thread creation, which is bitmask combination
|
|
* from enum pj_thread_create_flags.
|
|
* @param thread Pointer to hold the newly created thread.
|
|
*
|
|
* @return PJ_SUCCESS on success, or the error code.
|
|
*/
|
|
PJ_DECL(pj_status_t) pj_thread_create( pj_pool_t *pool,
|
|
const char *thread_name,
|
|
pj_thread_proc *proc,
|
|
void *arg,
|
|
pj_size_t stack_size,
|
|
unsigned flags,
|
|
pj_thread_t **thread );
|
|
|
|
/**
|
|
* Register a thread that was created by external or native API to PJLIB.
|
|
* This function must be called in the context of the thread being registered.
|
|
* When the thread is created by external function or API call,
|
|
* it must be 'registered' to PJLIB using pj_thread_register(), so that it can
|
|
* cooperate with PJLIB's framework. During registration, some data needs to
|
|
* be maintained, and this data must remain available during the thread's
|
|
* lifetime.
|
|
*
|
|
* @param thread_name The optional name to be assigned to the thread.
|
|
* @param desc Thread descriptor, which must be available throughout
|
|
* the lifetime of the thread.
|
|
* @param thread Pointer to hold the created thread handle.
|
|
*
|
|
* @return PJ_SUCCESS on success, or the error code.
|
|
*/
|
|
PJ_DECL(pj_status_t) pj_thread_register ( const char *thread_name,
|
|
pj_thread_desc desc,
|
|
pj_thread_t **thread);
|
|
|
|
/**
|
|
* Get thread name.
|
|
*
|
|
* @param thread The thread handle.
|
|
*
|
|
* @return Thread name as null terminated string.
|
|
*/
|
|
PJ_DECL(const char*) pj_thread_get_name(pj_thread_t *thread);
|
|
|
|
/**
|
|
* Resume a suspended thread.
|
|
*
|
|
* @param thread The thread handle.
|
|
*
|
|
* @return zero on success.
|
|
*/
|
|
PJ_DECL(pj_status_t) pj_thread_resume(pj_thread_t *thread);
|
|
|
|
/**
|
|
* Get the current thread.
|
|
*
|
|
* @return Thread handle of current thread.
|
|
*/
|
|
PJ_DECL(pj_thread_t*) pj_thread_this(void);
|
|
|
|
/**
|
|
* Join thread.
|
|
* This function will block the caller thread until the specified thread exits.
|
|
*
|
|
* @param thread The thread handle.
|
|
*
|
|
* @return zero on success.
|
|
*/
|
|
PJ_DECL(pj_status_t) pj_thread_join(pj_thread_t *thread);
|
|
|
|
|
|
/**
|
|
* Destroy thread and release resources allocated for the thread.
|
|
* However, the memory allocated for the pj_thread_t itself will only be released
|
|
* when the pool used to create the thread is destroyed.
|
|
*
|
|
* @param thread The thread handle.
|
|
*
|
|
* @return zero on success.
|
|
*/
|
|
PJ_DECL(pj_status_t) pj_thread_destroy(pj_thread_t *thread);
|
|
|
|
|
|
/**
|
|
* Put the current thread to sleep for the specified miliseconds.
|
|
*
|
|
* @param msec Miliseconds delay.
|
|
*
|
|
* @return zero if successfull.
|
|
*/
|
|
PJ_DECL(pj_status_t) pj_thread_sleep(unsigned msec);
|
|
|
|
/**
|
|
* @def PJ_CHECK_STACK()
|
|
* PJ_CHECK_STACK() macro is used to check the sanity of the stack.
|
|
* The OS implementation may check that no stack overflow occurs, and
|
|
* it also may collect statistic about stack usage.
|
|
*/
|
|
#if defined(PJ_OS_HAS_CHECK_STACK) && PJ_OS_HAS_CHECK_STACK!=0
|
|
|
|
# define PJ_CHECK_STACK() pj_thread_check_stack(__FILE__, __LINE__)
|
|
|
|
/** @internal
|
|
* The implementation of stack checking.
|
|
*/
|
|
PJ_DECL(void) pj_thread_check_stack(const char *file, int line);
|
|
|
|
/** @internal
|
|
* Get maximum stack usage statistic.
|
|
*/
|
|
PJ_DECL(pj_uint32_t) pj_thread_get_stack_max_usage(pj_thread_t *thread);
|
|
|
|
/** @internal
|
|
* Dump thread stack status.
|
|
*/
|
|
PJ_DECL(pj_status_t) pj_thread_get_stack_info(pj_thread_t *thread,
|
|
const char **file,
|
|
int *line);
|
|
#else
|
|
|
|
# define PJ_CHECK_STACK()
|
|
/** pj_thread_get_stack_max_usage() for the thread */
|
|
# define pj_thread_get_stack_max_usage(thread) 0
|
|
/** pj_thread_get_stack_info() for the thread */
|
|
# define pj_thread_get_stack_info(thread,f,l) (*(f)="",*(l)=0)
|
|
#endif /* PJ_OS_HAS_CHECK_STACK */
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
/**
|
|
* @defgroup PJ_TLS Thread Local Storage.
|
|
* @ingroup PJ_OS
|
|
* @{
|
|
*/
|
|
|
|
/**
|
|
* Allocate thread local storage index. The initial value of the variable at
|
|
* the index is zero.
|
|
*
|
|
* @param index Pointer to hold the return value.
|
|
* @return PJ_SUCCESS on success, or the error code.
|
|
*/
|
|
PJ_DECL(pj_status_t) pj_thread_local_alloc(long *index);
|
|
|
|
/**
|
|
* Deallocate thread local variable.
|
|
*
|
|
* @param index The variable index.
|
|
*/
|
|
PJ_DECL(void) pj_thread_local_free(long index);
|
|
|
|
/**
|
|
* Set the value of thread local variable.
|
|
*
|
|
* @param index The index of the variable.
|
|
* @param value The value.
|
|
*/
|
|
PJ_DECL(pj_status_t) pj_thread_local_set(long index, void *value);
|
|
|
|
/**
|
|
* Get the value of thread local variable.
|
|
*
|
|
* @param index The index of the variable.
|
|
* @return The value.
|
|
*/
|
|
PJ_DECL(void*) pj_thread_local_get(long index);
|
|
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
/**
|
|
* @defgroup PJ_ATOMIC Atomic Variables
|
|
* @ingroup PJ_OS
|
|
* @{
|
|
*
|
|
* This module provides API to manipulate atomic variables.
|
|
*
|
|
* \section pj_atomic_examples_sec Examples
|
|
*
|
|
* For some example codes, please see:
|
|
* - @ref page_pjlib_atomic_test
|
|
*/
|
|
|
|
|
|
/**
|
|
* Create atomic variable.
|
|
*
|
|
* @param pool The pool.
|
|
* @param initial The initial value of the atomic variable.
|
|
* @param atomic Pointer to hold the atomic variable upon return.
|
|
*
|
|
* @return PJ_SUCCESS on success, or the error code.
|
|
*/
|
|
PJ_DECL(pj_status_t) pj_atomic_create( pj_pool_t *pool,
|
|
pj_atomic_value_t initial,
|
|
pj_atomic_t **atomic );
|
|
|
|
/**
|
|
* Destroy atomic variable.
|
|
*
|
|
* @param atomic_var the atomic variable.
|
|
*
|
|
* @return PJ_SUCCESS if success.
|
|
*/
|
|
PJ_DECL(pj_status_t) pj_atomic_destroy( pj_atomic_t *atomic_var );
|
|
|
|
/**
|
|
* Set the value of an atomic type, and return the previous value.
|
|
*
|
|
* @param atomic_var the atomic variable.
|
|
* @param value value to be set to the variable.
|
|
*
|
|
* @return the previous value of the variable.
|
|
*/
|
|
PJ_DECL(pj_atomic_value_t) pj_atomic_set(pj_atomic_t *atomic_var,
|
|
pj_atomic_value_t value);
|
|
|
|
/**
|
|
* Get the value of an atomic type.
|
|
*
|
|
* @param atomic_var the atomic variable.
|
|
*
|
|
* @return the value of the atomic variable.
|
|
*/
|
|
PJ_DECL(pj_atomic_value_t) pj_atomic_get(pj_atomic_t *atomic_var);
|
|
|
|
/**
|
|
* Increment the value of an atomic type.
|
|
*
|
|
* @param atomic_var the atomic variable.
|
|
*
|
|
* @return the result.
|
|
*/
|
|
PJ_DECL(pj_atomic_value_t) pj_atomic_inc(pj_atomic_t *atomic_var);
|
|
|
|
/**
|
|
* Decrement the value of an atomic type.
|
|
*
|
|
* @param atomic_var the atomic variable.
|
|
*
|
|
* @return the result.
|
|
*/
|
|
PJ_DECL(pj_atomic_value_t) pj_atomic_dec(pj_atomic_t *atomic_var);
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
/**
|
|
* @defgroup PJ_MUTEX Mutexes.
|
|
* @ingroup PJ_OS
|
|
* @{
|
|
*
|
|
* Mutex manipulation. Alternatively, application can use higher abstraction
|
|
* for lock objects, which provides uniform API for all kinds of lock
|
|
* mechanisms, including mutex. See @ref PJ_LOCK for more information.
|
|
*/
|
|
|
|
/**
|
|
* Mutex types:
|
|
* - PJ_MUTEX_DEFAULT: default mutex type, which is system dependent.
|
|
* - PJ_MUTEX_SIMPLE: non-recursive mutex.
|
|
* - PJ_MUTEX_RECURSIVE: recursive mutex.
|
|
*/
|
|
typedef enum pj_mutex_type_e
|
|
{
|
|
PJ_MUTEX_DEFAULT,
|
|
PJ_MUTEX_SIMPLE,
|
|
PJ_MUTEX_RECURSE,
|
|
} pj_mutex_type_e;
|
|
|
|
|
|
/**
|
|
* Create mutex of the specified type.
|
|
*
|
|
* @param pool The pool.
|
|
* @param name Name to be associated with the mutex (for debugging).
|
|
* @param type The type of the mutex, of type #pj_mutex_type_e.
|
|
* @param mutex Pointer to hold the returned mutex instance.
|
|
*
|
|
* @return PJ_SUCCESS on success, or the error code.
|
|
*/
|
|
PJ_DECL(pj_status_t) pj_mutex_create(pj_pool_t *pool,
|
|
const char *name,
|
|
int type,
|
|
pj_mutex_t **mutex);
|
|
|
|
/**
|
|
* Create simple, non-recursive mutex.
|
|
* This function is a simple wrapper for #pj_mutex_create to create
|
|
* non-recursive mutex.
|
|
*
|
|
* @param pool The pool.
|
|
* @param name Mutex name.
|
|
* @param mutex Pointer to hold the returned mutex instance.
|
|
*
|
|
* @return PJ_SUCCESS on success, or the error code.
|
|
*/
|
|
PJ_DECL(pj_status_t) pj_mutex_create_simple( pj_pool_t *pool, const char *name,
|
|
pj_mutex_t **mutex );
|
|
|
|
/**
|
|
* Create recursive mutex.
|
|
* This function is a simple wrapper for #pj_mutex_create to create
|
|
* recursive mutex.
|
|
*
|
|
* @param pool The pool.
|
|
* @param name Mutex name.
|
|
* @param mutex Pointer to hold the returned mutex instance.
|
|
*
|
|
* @return PJ_SUCCESS on success, or the error code.
|
|
*/
|
|
PJ_DECL(pj_status_t) pj_mutex_create_recursive( pj_pool_t *pool,
|
|
const char *name,
|
|
pj_mutex_t **mutex );
|
|
|
|
/**
|
|
* Acquire mutex lock.
|
|
*
|
|
* @param mutex The mutex.
|
|
* @return PJ_SUCCESS on success, or the error code.
|
|
*/
|
|
PJ_DECL(pj_status_t) pj_mutex_lock(pj_mutex_t *mutex);
|
|
|
|
/**
|
|
* Release mutex lock.
|
|
*
|
|
* @param mutex The mutex.
|
|
* @return PJ_SUCCESS on success, or the error code.
|
|
*/
|
|
PJ_DECL(pj_status_t) pj_mutex_unlock(pj_mutex_t *mutex);
|
|
|
|
/**
|
|
* Try to acquire mutex lock.
|
|
*
|
|
* @param mutex The mutex.
|
|
* @return PJ_SUCCESS on success, or the error code if the
|
|
* lock couldn't be acquired.
|
|
*/
|
|
PJ_DECL(pj_status_t) pj_mutex_trylock(pj_mutex_t *mutex);
|
|
|
|
/**
|
|
* Destroy mutex.
|
|
*
|
|
* @param mutex Te mutex.
|
|
* @return PJ_SUCCESS on success, or the error code.
|
|
*/
|
|
PJ_DECL(pj_status_t) pj_mutex_destroy(pj_mutex_t *mutex);
|
|
|
|
/**
|
|
* Determine whether calling thread is owning the mutex (only available when
|
|
* PJ_DEBUG is set).
|
|
* @param mutex The mutex.
|
|
* @return Non-zero if yes.
|
|
*/
|
|
#if defined(PJ_DEBUG) && PJ_DEBUG != 0
|
|
PJ_DECL(pj_bool_t) pj_mutex_is_locked(pj_mutex_t *mutex);
|
|
#else
|
|
# define pj_mutex_is_locked(mutex) 1
|
|
#endif
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
/**
|
|
* @defgroup PJ_CRIT_SEC Critical sections.
|
|
* @ingroup PJ_OS
|
|
* @{
|
|
* Critical section protection can be used to protect regions where:
|
|
* - mutual exclusion protection is needed.
|
|
* - it's rather too expensive to create a mutex.
|
|
* - the time spent in the region is very very brief.
|
|
*
|
|
* Critical section is a global object, and it prevents any threads from
|
|
* entering any regions that are protected by critical section once a thread
|
|
* is already in the section.
|
|
*
|
|
* Critial section is \a not recursive!
|
|
*
|
|
* Application <b>MUST NOT</b> call any functions that may cause current
|
|
* thread to block (such as allocating memory, performing I/O, locking mutex,
|
|
* etc.) while holding the critical section.
|
|
*/
|
|
/**
|
|
* Enter critical section.
|
|
*/
|
|
PJ_DECL(void) pj_enter_critical_section(void);
|
|
|
|
/**
|
|
* Leave critical section.
|
|
*/
|
|
PJ_DECL(void) pj_leave_critical_section(void);
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
#if defined(PJ_HAS_SEMAPHORE) && PJ_HAS_SEMAPHORE != 0
|
|
/**
|
|
* @defgroup PJ_SEM Semaphores.
|
|
* @ingroup PJ_OS
|
|
* @{
|
|
*
|
|
* This module provides abstraction for semaphores, where available.
|
|
*/
|
|
|
|
/**
|
|
* Create semaphore.
|
|
*
|
|
* @param pool The pool.
|
|
* @param name Name to be assigned to the semaphore (for logging purpose)
|
|
* @param initial The initial count of the semaphore.
|
|
* @param max The maximum count of the semaphore.
|
|
* @param sem Pointer to hold the semaphore created.
|
|
*
|
|
* @return PJ_SUCCESS on success, or the error code.
|
|
*/
|
|
PJ_DECL(pj_status_t) pj_sem_create( pj_pool_t *pool,
|
|
const char *name,
|
|
unsigned initial,
|
|
unsigned max,
|
|
pj_sem_t **sem);
|
|
|
|
/**
|
|
* Wait for semaphore.
|
|
*
|
|
* @param sem The semaphore.
|
|
*
|
|
* @return PJ_SUCCESS on success, or the error code.
|
|
*/
|
|
PJ_DECL(pj_status_t) pj_sem_wait(pj_sem_t *sem);
|
|
|
|
/**
|
|
* Try wait for semaphore.
|
|
*
|
|
* @param sem The semaphore.
|
|
*
|
|
* @return PJ_SUCCESS on success, or the error code.
|
|
*/
|
|
PJ_DECL(pj_status_t) pj_sem_trywait(pj_sem_t *sem);
|
|
|
|
/**
|
|
* Release semaphore.
|
|
*
|
|
* @param sem The semaphore.
|
|
*
|
|
* @return PJ_SUCCESS on success, or the error code.
|
|
*/
|
|
PJ_DECL(pj_status_t) pj_sem_post(pj_sem_t *sem);
|
|
|
|
/**
|
|
* Destroy semaphore.
|
|
*
|
|
* @param sem The semaphore.
|
|
*
|
|
* @return PJ_SUCCESS on success, or the error code.
|
|
*/
|
|
PJ_DECL(pj_status_t) pj_sem_destroy(pj_sem_t *sem);
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
#endif /* PJ_HAS_SEMAPHORE */
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
#if defined(PJ_HAS_EVENT_OBJ) && PJ_HAS_EVENT_OBJ != 0
|
|
/**
|
|
* @defgroup PJ_EVENT Event Object.
|
|
* @ingroup PJ_OS
|
|
* @{
|
|
*
|
|
* This module provides abstraction to event object (e.g. Win32 Event) where
|
|
* available. Event objects can be used for synchronization among threads.
|
|
*/
|
|
|
|
/**
|
|
* Create event object.
|
|
*
|
|
* @param pool The pool.
|
|
* @param name The name of the event object (for logging purpose).
|
|
* @param manual_reset Specify whether the event is manual-reset
|
|
* @param initial Specify the initial state of the event object.
|
|
* @param event Pointer to hold the returned event object.
|
|
*
|
|
* @return event handle, or NULL if failed.
|
|
*/
|
|
PJ_DECL(pj_status_t) pj_event_create(pj_pool_t *pool, const char *name,
|
|
pj_bool_t manual_reset, pj_bool_t initial,
|
|
pj_event_t **event);
|
|
|
|
/**
|
|
* Wait for event to be signaled.
|
|
*
|
|
* @param event The event object.
|
|
*
|
|
* @return zero if successfull.
|
|
*/
|
|
PJ_DECL(pj_status_t) pj_event_wait(pj_event_t *event);
|
|
|
|
/**
|
|
* Try wait for event object to be signalled.
|
|
*
|
|
* @param event The event object.
|
|
*
|
|
* @return zero if successfull.
|
|
*/
|
|
PJ_DECL(pj_status_t) pj_event_trywait(pj_event_t *event);
|
|
|
|
/**
|
|
* Set the event object state to signaled. For auto-reset event, this
|
|
* will only release the first thread that are waiting on the event. For
|
|
* manual reset event, the state remains signaled until the event is reset.
|
|
* If there is no thread waiting on the event, the event object state
|
|
* remains signaled.
|
|
*
|
|
* @param event The event object.
|
|
*
|
|
* @return zero if successfull.
|
|
*/
|
|
PJ_DECL(pj_status_t) pj_event_set(pj_event_t *event);
|
|
|
|
/**
|
|
* Set the event object to signaled state to release appropriate number of
|
|
* waiting threads and then reset the event object to non-signaled. For
|
|
* manual-reset event, this function will release all waiting threads. For
|
|
* auto-reset event, this function will only release one waiting thread.
|
|
*
|
|
* @param event The event object.
|
|
*
|
|
* @return zero if successfull.
|
|
*/
|
|
PJ_DECL(pj_status_t) pj_event_pulse(pj_event_t *event);
|
|
|
|
/**
|
|
* Set the event object state to non-signaled.
|
|
*
|
|
* @param event The event object.
|
|
*
|
|
* @return zero if successfull.
|
|
*/
|
|
PJ_DECL(pj_status_t) pj_event_reset(pj_event_t *event);
|
|
|
|
/**
|
|
* Destroy the event object.
|
|
*
|
|
* @param event The event object.
|
|
*
|
|
* @return zero if successfull.
|
|
*/
|
|
PJ_DECL(pj_status_t) pj_event_destroy(pj_event_t *event);
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
#endif /* PJ_HAS_EVENT_OBJ */
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
/**
|
|
* @addtogroup PJ_TIME Time Data Type and Manipulation.
|
|
* @ingroup PJ_OS
|
|
* @{
|
|
* This module provides API for manipulating time.
|
|
*
|
|
* \section pj_time_examples_sec Examples
|
|
*
|
|
* For examples, please see:
|
|
* - \ref page_pjlib_sleep_test
|
|
*/
|
|
|
|
/**
|
|
* Get current time of day in local representation.
|
|
*
|
|
* @param tv Variable to store the result.
|
|
*
|
|
* @return zero if successfull.
|
|
*/
|
|
PJ_DECL(pj_status_t) pj_gettimeofday(pj_time_val *tv);
|
|
|
|
|
|
/**
|
|
* Parse time value into date/time representation.
|
|
*
|
|
* @param tv The time.
|
|
* @param pt Variable to store the date time result.
|
|
*
|
|
* @return zero if successfull.
|
|
*/
|
|
PJ_DECL(pj_status_t) pj_time_decode(const pj_time_val *tv, pj_parsed_time *pt);
|
|
|
|
/**
|
|
* Encode date/time to time value.
|
|
*
|
|
* @param pt The date/time.
|
|
* @param tv Variable to store time value result.
|
|
*
|
|
* @return zero if successfull.
|
|
*/
|
|
PJ_DECL(pj_status_t) pj_time_encode(const pj_parsed_time *pt, pj_time_val *tv);
|
|
|
|
/**
|
|
* Convert local time to GMT.
|
|
*
|
|
* @param tv Time to convert.
|
|
*
|
|
* @return zero if successfull.
|
|
*/
|
|
PJ_DECL(pj_status_t) pj_time_local_to_gmt(pj_time_val *tv);
|
|
|
|
/**
|
|
* Convert GMT to local time.
|
|
*
|
|
* @param tv Time to convert.
|
|
*
|
|
* @return zero if successfull.
|
|
*/
|
|
PJ_DECL(pj_status_t) pj_time_gmt_to_local(pj_time_val *tv);
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
#if defined(PJ_TERM_HAS_COLOR) && PJ_TERM_HAS_COLOR != 0
|
|
|
|
/**
|
|
* @defgroup PJ_TERM Terminal
|
|
* @ingroup PJ_OS
|
|
* @{
|
|
*/
|
|
|
|
/**
|
|
* Set current terminal color.
|
|
*
|
|
* @param color The RGB color.
|
|
*
|
|
* @return zero on success.
|
|
*/
|
|
PJ_DECL(pj_status_t) pj_term_set_color(pj_color_t color);
|
|
|
|
/**
|
|
* Get current terminal foreground color.
|
|
*
|
|
* @return RGB color.
|
|
*/
|
|
PJ_DECL(pj_color_t) pj_term_get_color(void);
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
#endif /* PJ_TERM_HAS_COLOR */
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
/**
|
|
* @defgroup PJ_TIMESTAMP High Resolution Timestamp
|
|
* @ingroup PJ_OS
|
|
* @{
|
|
*
|
|
* PJLIB provides <b>High Resolution Timestamp</b> API to access highest
|
|
* resolution timestamp value provided by the platform. The API is usefull
|
|
* to measure precise elapsed time, and can be used in applications such
|
|
* as profiling.
|
|
*
|
|
* The timestamp value is represented in cycles, and can be related to
|
|
* normal time (in seconds or sub-seconds) using various functions provided.
|
|
*
|
|
* \section pj_timestamp_examples_sec Examples
|
|
*
|
|
* For examples, please see:
|
|
* - \ref page_pjlib_sleep_test
|
|
* - \ref page_pjlib_timestamp_test
|
|
*/
|
|
|
|
/*
|
|
* High resolution timer.
|
|
*/
|
|
#if defined(PJ_HAS_HIGH_RES_TIMER) && PJ_HAS_HIGH_RES_TIMER != 0
|
|
|
|
/**
|
|
* This structure represents high resolution (64bit) time value. The time
|
|
* values represent time in cycles, which is retrieved by calling
|
|
* #pj_get_timestamp().
|
|
*/
|
|
typedef union pj_timestamp
|
|
{
|
|
struct
|
|
{
|
|
#if defined(PJ_IS_LITTLE_ENDIAN) && PJ_IS_LITTLE_ENDIAN!=0
|
|
pj_uint32_t lo; /**< Low 32-bit value of the 64-bit value. */
|
|
pj_uint32_t hi; /**< high 32-bit value of the 64-bit value. */
|
|
#else
|
|
pj_uint32_t hi; /**< high 32-bit value of the 64-bit value. */
|
|
pj_uint32_t lo; /**< Low 32-bit value of the 64-bit value. */
|
|
#endif
|
|
} u32; /**< The 64-bit value as two 32-bit values. */
|
|
|
|
#if PJ_HAS_INT64
|
|
pj_uint64_t u64; /**< The whole 64-bit value, where available. */
|
|
#endif
|
|
} pj_timestamp;
|
|
|
|
|
|
/**
|
|
* Acquire high resolution timer value. The time value are stored
|
|
* in cycles.
|
|
*
|
|
* @param ts High resolution timer value.
|
|
* @return PJ_SUCCESS or the appropriate error code.
|
|
*
|
|
* @see pj_get_timestamp_freq().
|
|
*/
|
|
PJ_DECL(pj_status_t) pj_get_timestamp(pj_timestamp *ts);
|
|
|
|
/**
|
|
* Get high resolution timer frequency, in cycles per second.
|
|
*
|
|
* @param freq Timer frequency, in cycles per second.
|
|
* @return PJ_SUCCESS or the appropriate error code.
|
|
*/
|
|
PJ_DECL(pj_status_t) pj_get_timestamp_freq(pj_timestamp *freq);
|
|
|
|
/**
|
|
* Calculate the elapsed time, and store it in pj_time_val.
|
|
* This function calculates the elapsed time using highest precision
|
|
* calculation that is available for current platform, considering
|
|
* whether floating point or 64-bit precision arithmetic is available.
|
|
* For maximum portability, application should prefer to use this function
|
|
* rather than calculating the elapsed time by itself.
|
|
*
|
|
* @param start The starting timestamp.
|
|
* @param stop The end timestamp.
|
|
*
|
|
* @return Elapsed time as #pj_time_val.
|
|
*
|
|
* @see pj_elapsed_usec(), pj_elapsed_cycle(), pj_elapsed_nanosec()
|
|
*/
|
|
PJ_DECL(pj_time_val) pj_elapsed_time( const pj_timestamp *start,
|
|
const pj_timestamp *stop );
|
|
|
|
/**
|
|
* Calculate the elapsed time in 32-bit microseconds.
|
|
* This function calculates the elapsed time using highest precision
|
|
* calculation that is available for current platform, considering
|
|
* whether floating point or 64-bit precision arithmetic is available.
|
|
* For maximum portability, application should prefer to use this function
|
|
* rather than calculating the elapsed time by itself.
|
|
*
|
|
* @param start The starting timestamp.
|
|
* @param stop The end timestamp.
|
|
*
|
|
* @return Elapsed time in microsecond.
|
|
*
|
|
* @see pj_elapsed_time(), pj_elapsed_cycle(), pj_elapsed_nanosec()
|
|
*/
|
|
PJ_DECL(pj_uint32_t) pj_elapsed_usec( const pj_timestamp *start,
|
|
const pj_timestamp *stop );
|
|
|
|
/**
|
|
* Calculate the elapsed time in 32-bit nanoseconds.
|
|
* This function calculates the elapsed time using highest precision
|
|
* calculation that is available for current platform, considering
|
|
* whether floating point or 64-bit precision arithmetic is available.
|
|
* For maximum portability, application should prefer to use this function
|
|
* rather than calculating the elapsed time by itself.
|
|
*
|
|
* @param start The starting timestamp.
|
|
* @param stop The end timestamp.
|
|
*
|
|
* @return Elapsed time in nanoseconds.
|
|
*
|
|
* @see pj_elapsed_time(), pj_elapsed_cycle(), pj_elapsed_usec()
|
|
*/
|
|
PJ_DECL(pj_uint32_t) pj_elapsed_nanosec( const pj_timestamp *start,
|
|
const pj_timestamp *stop );
|
|
|
|
/**
|
|
* Calculate the elapsed time in 32-bit cycles.
|
|
* This function calculates the elapsed time using highest precision
|
|
* calculation that is available for current platform, considering
|
|
* whether floating point or 64-bit precision arithmetic is available.
|
|
* For maximum portability, application should prefer to use this function
|
|
* rather than calculating the elapsed time by itself.
|
|
*
|
|
* @param start The starting timestamp.
|
|
* @param stop The end timestamp.
|
|
*
|
|
* @return Elapsed time in cycles.
|
|
*
|
|
* @see pj_elapsed_usec(), pj_elapsed_time(), pj_elapsed_nanosec()
|
|
*/
|
|
PJ_DECL(pj_uint32_t) pj_elapsed_cycle( const pj_timestamp *start,
|
|
const pj_timestamp *stop );
|
|
|
|
|
|
#endif /* PJ_HAS_HIGH_RES_TIMER */
|
|
|
|
/** @} */
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
/**
|
|
* Internal PJLIB function to initialize the threading subsystem.
|
|
* @return PJ_SUCCESS or the appropriate error code.
|
|
*/
|
|
pj_status_t pj_thread_init(void);
|
|
|
|
|
|
PJ_END_DECL
|
|
|
|
#endif /* __PJ_OS_H__ */
|
|
|