diff options
Diffstat (limited to 'pjlib/include/pj/os.h')
-rw-r--r-- | pjlib/include/pj/os.h | 1849 |
1 files changed, 935 insertions, 914 deletions
diff --git a/pjlib/include/pj/os.h b/pjlib/include/pj/os.h index a1fef6b8..5e244504 100644 --- a/pjlib/include/pj/os.h +++ b/pjlib/include/pj/os.h @@ -1,329 +1,350 @@ -/* $Id$ - * - */ - -#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. - */ -PJ_DECL(void) 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. - */ -PJ_DECL(void) pj_atomic_inc(pj_atomic_t *atomic_var); - +/* $Id$
+ *
+ */
+/*
+ * PJLIB - PJ Foundation Library
+ * (C)2003-2005 Benny Prijono <bennylp@bulukucing.org>
+ *
+ * Author:
+ * Benny Prijono <bennylp@bulukucing.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#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.
+ */
+PJ_DECL(void) 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.
+ */
+PJ_DECL(void) pj_atomic_inc(pj_atomic_t *atomic_var);
+
/**
* Increment the value of an atomic type and get the result.
*
@@ -333,12 +354,12 @@ PJ_DECL(void) pj_atomic_inc(pj_atomic_t *atomic_var); */
PJ_DECL(pj_atomic_value_t) pj_atomic_inc_and_get(pj_atomic_t *atomic_var);
-/** - * Decrement the value of an atomic type. - * - * @param atomic_var the atomic variable. - */ -PJ_DECL(void) pj_atomic_dec(pj_atomic_t *atomic_var); +/**
+ * Decrement the value of an atomic type.
+ *
+ * @param atomic_var the atomic variable.
+ */
+PJ_DECL(void) pj_atomic_dec(pj_atomic_t *atomic_var);
/**
* Decrement the value of an atomic type and get the result.
@@ -348,15 +369,15 @@ PJ_DECL(void) pj_atomic_dec(pj_atomic_t *atomic_var); * @return The decremented value.
*/
PJ_DECL(pj_atomic_value_t) pj_atomic_dec_and_get(pj_atomic_t *atomic_var);
- -/** - * Add a value to an atomic type. - * - * @param atomic_var The atomic variable. - * @param value Value to be added. - */ -PJ_DECL(void) pj_atomic_add( pj_atomic_t *atomic_var, - pj_atomic_value_t value); +
+/**
+ * Add a value to an atomic type.
+ *
+ * @param atomic_var The atomic variable.
+ * @param value Value to be added.
+ */
+PJ_DECL(void) pj_atomic_add( pj_atomic_t *atomic_var,
+ pj_atomic_value_t value);
/**
* Add a value to an atomic type and get the result.
@@ -368,576 +389,576 @@ PJ_DECL(void) pj_atomic_add( pj_atomic_t *atomic_var, */
PJ_DECL(pj_atomic_value_t) pj_atomic_add_and_get( pj_atomic_t *atomic_var,
pj_atomic_value_t value);
- -/** - * @} - */ - -/////////////////////////////////////////////////////////////////////////////// -/** - * @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__ */ - +
+/**
+ * @}
+ */
+
+///////////////////////////////////////////////////////////////////////////////
+/**
+ * @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__ */
+
|