1
/* $Id: os.h 3664 2011-07-19 03:42:28Z nanang $ */
3
* Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
4
* Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25
* @brief OS dependent functions
32
* @defgroup PJ_OS Operating System Dependent Functionality.
36
/* **************************************************************************/
38
* @defgroup PJ_SYS_INFO System Information
44
* These enumeration contains constants to indicate support of miscellaneous
45
* system features. These will go in "flags" field of #pj_sys_info structure.
47
typedef enum pj_sys_info_flag
50
* Support for Apple iOS background feature.
58
* This structure contains information about the system. Use #pj_get_sys_info()
59
* to obtain the system information.
61
typedef struct pj_sys_info
64
* Null terminated string containing processor information (e.g. "i386",
65
* "x86_64"). It may contain empty string if the value cannot be obtained.
70
* Null terminated string identifying the system operation (e.g. "Linux",
71
* "win32", "wince"). It may contain empty string if the value cannot be
77
* A number containing the operating system version number. By convention,
78
* this field is divided into four bytes, where the highest order byte
79
* contains the most major version of the OS, the next less significant
80
* byte contains the less major version, and so on. How the OS version
81
* number is mapped into these four bytes would be specific for each OS.
82
* For example, Linux-2.6.32-28 would yield "os_ver" value of 0x0206201c,
83
* while for Windows 7 it will be 0x06010000 (because dwMajorVersion is
84
* 6 and dwMinorVersion is 1 for Windows 7).
86
* This field may contain zero if the OS version cannot be obtained.
91
* Null terminated string identifying the SDK name that is used to build
92
* the library (e.g. "glibc", "uclibc", "msvc", "wince"). It may contain
93
* empty string if the value cannot eb obtained.
98
* A number containing the SDK version, using the numbering convention as
99
* the "os_ver" field. The value will be zero if the version cannot be
105
* A longer null terminated string identifying the underlying system with
106
* as much information as possible.
111
* Other flags containing system specific information. The value is
112
* bitmask of #pj_sys_info_flag constants.
120
* Obtain the system information.
122
* @return System information structure.
124
PJ_DECL(const pj_sys_info*) pj_get_sys_info(void);
130
/* **************************************************************************/
132
* @defgroup PJ_THREAD Threads
135
* This module provides multithreading API.
137
* \section pj_thread_examples_sec Examples
139
* For examples, please see:
140
* - \ref page_pjlib_thread_test
141
* - \ref page_pjlib_sleep_test
146
* Thread creation flags:
147
* - PJ_THREAD_SUSPENDED: specify that the thread should be created suspended.
149
typedef enum pj_thread_create_flags
151
PJ_THREAD_SUSPENDED = 1
152
} pj_thread_create_flags;
156
* Type of thread entry function.
158
typedef int (PJ_THREAD_FUNC pj_thread_proc)(void*);
161
* Size of thread struct.
163
#if !defined(PJ_THREAD_DESC_SIZE)
164
# define PJ_THREAD_DESC_SIZE (64)
168
* Thread structure, to thread's state when the thread is created by external
171
typedef long pj_thread_desc[PJ_THREAD_DESC_SIZE];
175
* @return process ID.
177
PJ_DECL(pj_uint32_t) pj_getpid(void);
180
* Create a new thread.
182
* @param pool The memory pool from which the thread record
183
* will be allocated from.
184
* @param thread_name The optional name to be assigned to the thread.
185
* @param proc Thread entry function.
186
* @param arg Argument to be passed to the thread entry function.
187
* @param stack_size The size of the stack for the new thread, or ZERO or
188
* PJ_THREAD_DEFAULT_STACK_SIZE to let the
189
* library choose the reasonable size for the stack.
190
* For some systems, the stack will be allocated from
191
* the pool, so the pool must have suitable capacity.
192
* @param flags Flags for thread creation, which is bitmask combination
193
* from enum pj_thread_create_flags.
194
* @param thread Pointer to hold the newly created thread.
196
* @return PJ_SUCCESS on success, or the error code.
198
PJ_DECL(pj_status_t) pj_thread_create( pj_pool_t *pool,
199
const char *thread_name,
200
pj_thread_proc *proc,
202
pj_size_t stack_size,
204
pj_thread_t **thread );
207
* Register a thread that was created by external or native API to PJLIB.
208
* This function must be called in the context of the thread being registered.
209
* When the thread is created by external function or API call,
210
* it must be 'registered' to PJLIB using pj_thread_register(), so that it can
211
* cooperate with PJLIB's framework. During registration, some data needs to
212
* be maintained, and this data must remain available during the thread's
215
* @param thread_name The optional name to be assigned to the thread.
216
* @param desc Thread descriptor, which must be available throughout
217
* the lifetime of the thread.
218
* @param thread Pointer to hold the created thread handle.
220
* @return PJ_SUCCESS on success, or the error code.
222
PJ_DECL(pj_status_t) pj_thread_register ( const char *thread_name,
224
pj_thread_t **thread);
227
* Check if this thread has been registered to PJLIB.
229
* @return Non-zero if it is registered.
231
PJ_DECL(pj_bool_t) pj_thread_is_registered(void);
235
* Get thread priority value for the thread.
237
* @param thread Thread handle.
239
* @return Thread priority value, or -1 on error.
241
PJ_DECL(int) pj_thread_get_prio(pj_thread_t *thread);
245
* Set the thread priority. The priority value must be in the priority
246
* value range, which can be retrieved with #pj_thread_get_prio_min() and
247
* #pj_thread_get_prio_max() functions.
249
* @param thread Thread handle.
250
* @param prio New priority to be set to the thread.
252
* @return PJ_SUCCESS on success or the error code.
254
PJ_DECL(pj_status_t) pj_thread_set_prio(pj_thread_t *thread, int prio);
257
* Get the lowest priority value available for this thread.
259
* @param thread Thread handle.
260
* @return Minimum thread priority value, or -1 on error.
262
PJ_DECL(int) pj_thread_get_prio_min(pj_thread_t *thread);
266
* Get the highest priority value available for this thread.
268
* @param thread Thread handle.
269
* @return Minimum thread priority value, or -1 on error.
271
PJ_DECL(int) pj_thread_get_prio_max(pj_thread_t *thread);
275
* Return native handle from pj_thread_t for manipulation using native
278
* @param thread PJLIB thread descriptor.
280
* @return Native thread handle. For example, when the
281
* backend thread uses pthread, this function will
282
* return pointer to pthread_t, and on Windows,
283
* this function will return HANDLE.
285
PJ_DECL(void*) pj_thread_get_os_handle(pj_thread_t *thread);
290
* @param thread The thread handle.
292
* @return Thread name as null terminated string.
294
PJ_DECL(const char*) pj_thread_get_name(pj_thread_t *thread);
297
* Resume a suspended thread.
299
* @param thread The thread handle.
301
* @return zero on success.
303
PJ_DECL(pj_status_t) pj_thread_resume(pj_thread_t *thread);
306
* Get the current thread.
308
* @return Thread handle of current thread.
310
PJ_DECL(pj_thread_t*) pj_thread_this(void);
313
* Join thread, and block the caller thread until the specified thread exits.
314
* If the specified thread has already been dead, or it does not exist,
315
* the function will return immediately with successfull status.
317
* @param thread The thread handle.
319
* @return PJ_SUCCESS on success.
321
PJ_DECL(pj_status_t) pj_thread_join(pj_thread_t *thread);
325
* Destroy thread and release resources allocated for the thread.
326
* However, the memory allocated for the pj_thread_t itself will only be released
327
* when the pool used to create the thread is destroyed.
329
* @param thread The thread handle.
331
* @return zero on success.
333
PJ_DECL(pj_status_t) pj_thread_destroy(pj_thread_t *thread);
337
* Put the current thread to sleep for the specified miliseconds.
339
* @param msec Miliseconds delay.
341
* @return zero if successfull.
343
PJ_DECL(pj_status_t) pj_thread_sleep(unsigned msec);
346
* @def PJ_CHECK_STACK()
347
* PJ_CHECK_STACK() macro is used to check the sanity of the stack.
348
* The OS implementation may check that no stack overflow occurs, and
349
* it also may collect statistic about stack usage.
351
#if defined(PJ_OS_HAS_CHECK_STACK) && PJ_OS_HAS_CHECK_STACK!=0
353
# define PJ_CHECK_STACK() pj_thread_check_stack(__FILE__, __LINE__)
356
* The implementation of stack checking.
358
PJ_DECL(void) pj_thread_check_stack(const char *file, int line);
361
* Get maximum stack usage statistic.
363
PJ_DECL(pj_uint32_t) pj_thread_get_stack_max_usage(pj_thread_t *thread);
366
* Dump thread stack status.
368
PJ_DECL(pj_status_t) pj_thread_get_stack_info(pj_thread_t *thread,
373
# define PJ_CHECK_STACK()
374
/** pj_thread_get_stack_max_usage() for the thread */
375
# define pj_thread_get_stack_max_usage(thread) 0
376
/** pj_thread_get_stack_info() for the thread */
377
# define pj_thread_get_stack_info(thread,f,l) (*(f)="",*(l)=0)
378
#endif /* PJ_OS_HAS_CHECK_STACK */
384
/* **************************************************************************/
386
* @defgroup PJ_SYMBIAN_OS Symbian OS Specific
389
* Functionalities specific to Symbian OS.
391
* Symbian OS strongly discourages the use of polling since this wastes
392
* CPU power, and instead provides Active Object and Active Scheduler
393
* pattern to allow application (in this case, PJLIB) to register asynchronous
394
* tasks. PJLIB port for Symbian complies to this recommended behavior.
395
* As the result, few things have been changed in PJLIB for Symbian:
396
* - the timer heap (see @ref PJ_TIMER) is implemented with active
397
* object framework, and each timer entry registered to the timer
398
* heap will register an Active Object to the Active Scheduler.
399
* Because of this, polling the timer heap with pj_timer_heap_poll()
400
* is no longer necessary, and this function will just evaluate
402
* - the ioqueue (see @ref PJ_IOQUEUE) is also implemented with
403
* active object framework, with each asynchronous operation will
404
* register an Active Object to the Active Scheduler. Because of
405
* this, polling the ioqueue with pj_ioqueue_poll() is no longer
406
* necessary, and this function will just evaluate to nothing.
408
* Since timer heap and ioqueue polling are no longer necessary, Symbian
409
* application can now poll for all events by calling
410
* \a User::WaitForAnyRequest() and \a CActiveScheduler::RunIfReady().
411
* PJLIB provides a thin wrapper which calls these two functions,
412
* called pj_symbianos_poll().
416
* Wait the completion of any Symbian active objects. When the timeout
417
* value is not specified (the \a ms_timeout argument is -1), this
418
* function is a thin wrapper which calls \a User::WaitForAnyRequest()
419
* and \a CActiveScheduler::RunIfReady(). If the timeout value is
420
* specified, this function will schedule a timer entry to the timer
421
* heap (which is an Active Object), to limit the wait time for event
422
* occurences. Scheduling a timer entry is an expensive operation,
423
* therefore application should only specify a timeout value when it's
424
* really necessary (for example, when it's not sure there are other
425
* Active Objects currently running in the application).
427
* @param priority The minimum priority of the Active Objects to
428
* poll, which values are from CActive::TPriority
429
* constants. If -1 is given, CActive::EPriorityStandard.
430
* priority will be used.
431
* @param ms_timeout Optional timeout to wait. Application should
432
* specify -1 to let the function wait indefinitely
435
* @return PJ_TRUE if there have been any events executed
436
* during the polling. This function will only return
437
* PJ_FALSE if \a ms_timeout argument is specified
438
* (i.e. the value is not -1) and there was no event
439
* executed when the timeout timer elapsed.
441
PJ_DECL(pj_bool_t) pj_symbianos_poll(int priority, int ms_timeout);
445
* This structure declares Symbian OS specific parameters that can be
446
* specified when calling #pj_symbianos_set_params().
448
typedef struct pj_symbianos_params
451
* Optional RSocketServ instance to be used by PJLIB. If this
452
* value is NULL, PJLIB will create a new RSocketServ instance
453
* when pj_init() is called.
458
* Optional RConnection instance to be used by PJLIB when creating
459
* sockets. If this value is NULL, no RConnection will be
460
* specified when creating sockets.
465
* Optional RHostResolver instance to be used by PJLIB. If this value
466
* is NULL, a new RHostResolver instance will be created when
467
* pj_init() is called.
472
* Optional RHostResolver for IPv6 instance to be used by PJLIB.
473
* If this value is NULL, a new RHostResolver instance will be created
474
* when pj_init() is called.
476
void *rhostresolver6;
478
} pj_symbianos_params;
481
* Specify Symbian OS parameters to be used by PJLIB. This function MUST
482
* be called before #pj_init() is called.
484
* @param prm Symbian specific parameters.
486
* @return PJ_SUCCESS if the parameters can be applied
489
PJ_DECL(pj_status_t) pj_symbianos_set_params(pj_symbianos_params *prm);
492
* Notify PJLIB that the access point connection has been down or unusable
493
* and PJLIB should not try to access the Symbian socket API (especially ones
494
* that send packets). Sending packet when RConnection is reconnected to
495
* different access point may cause the WaitForRequest() for the function to
496
* block indefinitely.
498
* @param up If set to PJ_FALSE it will cause PJLIB to not try
499
* to access socket API, and error will be returned
500
* immediately instead.
502
PJ_DECL(void) pj_symbianos_set_connection_status(pj_bool_t up);
508
/* **************************************************************************/
510
* @defgroup PJ_TLS Thread Local Storage.
516
* Allocate thread local storage index. The initial value of the variable at
519
* @param index Pointer to hold the return value.
520
* @return PJ_SUCCESS on success, or the error code.
522
PJ_DECL(pj_status_t) pj_thread_local_alloc(long *index);
525
* Deallocate thread local variable.
527
* @param index The variable index.
529
PJ_DECL(void) pj_thread_local_free(long index);
532
* Set the value of thread local variable.
534
* @param index The index of the variable.
535
* @param value The value.
537
PJ_DECL(pj_status_t) pj_thread_local_set(long index, void *value);
540
* Get the value of thread local variable.
542
* @param index The index of the variable.
545
PJ_DECL(void*) pj_thread_local_get(long index);
553
/* **************************************************************************/
555
* @defgroup PJ_ATOMIC Atomic Variables
559
* This module provides API to manipulate atomic variables.
561
* \section pj_atomic_examples_sec Examples
563
* For some example codes, please see:
564
* - @ref page_pjlib_atomic_test
569
* Create atomic variable.
571
* @param pool The pool.
572
* @param initial The initial value of the atomic variable.
573
* @param atomic Pointer to hold the atomic variable upon return.
575
* @return PJ_SUCCESS on success, or the error code.
577
PJ_DECL(pj_status_t) pj_atomic_create( pj_pool_t *pool,
578
pj_atomic_value_t initial,
579
pj_atomic_t **atomic );
582
* Destroy atomic variable.
584
* @param atomic_var the atomic variable.
586
* @return PJ_SUCCESS if success.
588
PJ_DECL(pj_status_t) pj_atomic_destroy( pj_atomic_t *atomic_var );
591
* Set the value of an atomic type, and return the previous value.
593
* @param atomic_var the atomic variable.
594
* @param value value to be set to the variable.
596
PJ_DECL(void) pj_atomic_set( pj_atomic_t *atomic_var,
597
pj_atomic_value_t value);
600
* Get the value of an atomic type.
602
* @param atomic_var the atomic variable.
604
* @return the value of the atomic variable.
606
PJ_DECL(pj_atomic_value_t) pj_atomic_get(pj_atomic_t *atomic_var);
609
* Increment the value of an atomic type.
611
* @param atomic_var the atomic variable.
613
PJ_DECL(void) pj_atomic_inc(pj_atomic_t *atomic_var);
616
* Increment the value of an atomic type and get the result.
618
* @param atomic_var the atomic variable.
620
* @return The incremented value.
622
PJ_DECL(pj_atomic_value_t) pj_atomic_inc_and_get(pj_atomic_t *atomic_var);
625
* Decrement the value of an atomic type.
627
* @param atomic_var the atomic variable.
629
PJ_DECL(void) pj_atomic_dec(pj_atomic_t *atomic_var);
632
* Decrement the value of an atomic type and get the result.
634
* @param atomic_var the atomic variable.
636
* @return The decremented value.
638
PJ_DECL(pj_atomic_value_t) pj_atomic_dec_and_get(pj_atomic_t *atomic_var);
641
* Add a value to an atomic type.
643
* @param atomic_var The atomic variable.
644
* @param value Value to be added.
646
PJ_DECL(void) pj_atomic_add( pj_atomic_t *atomic_var,
647
pj_atomic_value_t value);
650
* Add a value to an atomic type and get the result.
652
* @param atomic_var The atomic variable.
653
* @param value Value to be added.
655
* @return The result after the addition.
657
PJ_DECL(pj_atomic_value_t) pj_atomic_add_and_get( pj_atomic_t *atomic_var,
658
pj_atomic_value_t value);
664
/* **************************************************************************/
666
* @defgroup PJ_MUTEX Mutexes.
670
* Mutex manipulation. Alternatively, application can use higher abstraction
671
* for lock objects, which provides uniform API for all kinds of lock
672
* mechanisms, including mutex. See @ref PJ_LOCK for more information.
677
* - PJ_MUTEX_DEFAULT: default mutex type, which is system dependent.
678
* - PJ_MUTEX_SIMPLE: non-recursive mutex.
679
* - PJ_MUTEX_RECURSE: recursive mutex.
681
typedef enum pj_mutex_type_e
690
* Create mutex of the specified type.
692
* @param pool The pool.
693
* @param name Name to be associated with the mutex (for debugging).
694
* @param type The type of the mutex, of type #pj_mutex_type_e.
695
* @param mutex Pointer to hold the returned mutex instance.
697
* @return PJ_SUCCESS on success, or the error code.
699
PJ_DECL(pj_status_t) pj_mutex_create(pj_pool_t *pool,
705
* Create simple, non-recursive mutex.
706
* This function is a simple wrapper for #pj_mutex_create to create
707
* non-recursive mutex.
709
* @param pool The pool.
710
* @param name Mutex name.
711
* @param mutex Pointer to hold the returned mutex instance.
713
* @return PJ_SUCCESS on success, or the error code.
715
PJ_DECL(pj_status_t) pj_mutex_create_simple( pj_pool_t *pool, const char *name,
716
pj_mutex_t **mutex );
719
* Create recursive mutex.
720
* This function is a simple wrapper for #pj_mutex_create to create
723
* @param pool The pool.
724
* @param name Mutex name.
725
* @param mutex Pointer to hold the returned mutex instance.
727
* @return PJ_SUCCESS on success, or the error code.
729
PJ_DECL(pj_status_t) pj_mutex_create_recursive( pj_pool_t *pool,
731
pj_mutex_t **mutex );
734
* Acquire mutex lock.
736
* @param mutex The mutex.
737
* @return PJ_SUCCESS on success, or the error code.
739
PJ_DECL(pj_status_t) pj_mutex_lock(pj_mutex_t *mutex);
742
* Release mutex lock.
744
* @param mutex The mutex.
745
* @return PJ_SUCCESS on success, or the error code.
747
PJ_DECL(pj_status_t) pj_mutex_unlock(pj_mutex_t *mutex);
750
* Try to acquire mutex lock.
752
* @param mutex The mutex.
753
* @return PJ_SUCCESS on success, or the error code if the
754
* lock couldn't be acquired.
756
PJ_DECL(pj_status_t) pj_mutex_trylock(pj_mutex_t *mutex);
761
* @param mutex Te mutex.
762
* @return PJ_SUCCESS on success, or the error code.
764
PJ_DECL(pj_status_t) pj_mutex_destroy(pj_mutex_t *mutex);
767
* Determine whether calling thread is owning the mutex (only available when
769
* @param mutex The mutex.
770
* @return Non-zero if yes.
772
PJ_DECL(pj_bool_t) pj_mutex_is_locked(pj_mutex_t *mutex);
778
/* **************************************************************************/
780
* @defgroup PJ_RW_MUTEX Reader/Writer Mutex
783
* Reader/writer mutex is a classic synchronization object where multiple
784
* readers can acquire the mutex, but only a single writer can acquire the
789
* Opaque declaration for reader/writer mutex.
790
* Reader/writer mutex is a classic synchronization object where multiple
791
* readers can acquire the mutex, but only a single writer can acquire the
794
typedef struct pj_rwmutex_t pj_rwmutex_t;
797
* Create reader/writer mutex.
799
* @param pool Pool to allocate memory for the mutex.
800
* @param name Name to be assigned to the mutex.
801
* @param mutex Pointer to receive the newly created mutex.
803
* @return PJ_SUCCESS on success, or the error code.
805
PJ_DECL(pj_status_t) pj_rwmutex_create(pj_pool_t *pool, const char *name,
806
pj_rwmutex_t **mutex);
809
* Lock the mutex for reading.
811
* @param mutex The mutex.
812
* @return PJ_SUCCESS on success, or the error code.
814
PJ_DECL(pj_status_t) pj_rwmutex_lock_read(pj_rwmutex_t *mutex);
817
* Lock the mutex for writing.
819
* @param mutex The mutex.
820
* @return PJ_SUCCESS on success, or the error code.
822
PJ_DECL(pj_status_t) pj_rwmutex_lock_write(pj_rwmutex_t *mutex);
827
* @param mutex The mutex.
828
* @return PJ_SUCCESS on success, or the error code.
830
PJ_DECL(pj_status_t) pj_rwmutex_unlock_read(pj_rwmutex_t *mutex);
833
* Release write lock.
835
* @param mutex The mutex.
836
* @return PJ_SUCCESS on success, or the error code.
838
PJ_DECL(pj_status_t) pj_rwmutex_unlock_write(pj_rwmutex_t *mutex);
841
* Destroy reader/writer mutex.
843
* @param mutex The mutex.
844
* @return PJ_SUCCESS on success, or the error code.
846
PJ_DECL(pj_status_t) pj_rwmutex_destroy(pj_rwmutex_t *mutex);
854
/* **************************************************************************/
856
* @defgroup PJ_CRIT_SEC Critical sections.
859
* Critical section protection can be used to protect regions where:
860
* - mutual exclusion protection is needed.
861
* - it's rather too expensive to create a mutex.
862
* - the time spent in the region is very very brief.
864
* Critical section is a global object, and it prevents any threads from
865
* entering any regions that are protected by critical section once a thread
866
* is already in the section.
868
* Critial section is \a not recursive!
870
* Application <b>MUST NOT</b> call any functions that may cause current
871
* thread to block (such as allocating memory, performing I/O, locking mutex,
872
* etc.) while holding the critical section.
875
* Enter critical section.
877
PJ_DECL(void) pj_enter_critical_section(void);
880
* Leave critical section.
882
PJ_DECL(void) pj_leave_critical_section(void);
888
/* **************************************************************************/
889
#if defined(PJ_HAS_SEMAPHORE) && PJ_HAS_SEMAPHORE != 0
891
* @defgroup PJ_SEM Semaphores.
895
* This module provides abstraction for semaphores, where available.
901
* @param pool The pool.
902
* @param name Name to be assigned to the semaphore (for logging purpose)
903
* @param initial The initial count of the semaphore.
904
* @param max The maximum count of the semaphore.
905
* @param sem Pointer to hold the semaphore created.
907
* @return PJ_SUCCESS on success, or the error code.
909
PJ_DECL(pj_status_t) pj_sem_create( pj_pool_t *pool,
916
* Wait for semaphore.
918
* @param sem The semaphore.
920
* @return PJ_SUCCESS on success, or the error code.
922
PJ_DECL(pj_status_t) pj_sem_wait(pj_sem_t *sem);
925
* Try wait for semaphore.
927
* @param sem The semaphore.
929
* @return PJ_SUCCESS on success, or the error code.
931
PJ_DECL(pj_status_t) pj_sem_trywait(pj_sem_t *sem);
936
* @param sem The semaphore.
938
* @return PJ_SUCCESS on success, or the error code.
940
PJ_DECL(pj_status_t) pj_sem_post(pj_sem_t *sem);
945
* @param sem The semaphore.
947
* @return PJ_SUCCESS on success, or the error code.
949
PJ_DECL(pj_status_t) pj_sem_destroy(pj_sem_t *sem);
954
#endif /* PJ_HAS_SEMAPHORE */
957
/* **************************************************************************/
958
#if defined(PJ_HAS_EVENT_OBJ) && PJ_HAS_EVENT_OBJ != 0
960
* @defgroup PJ_EVENT Event Object.
964
* This module provides abstraction to event object (e.g. Win32 Event) where
965
* available. Event objects can be used for synchronization among threads.
969
* Create event object.
971
* @param pool The pool.
972
* @param name The name of the event object (for logging purpose).
973
* @param manual_reset Specify whether the event is manual-reset
974
* @param initial Specify the initial state of the event object.
975
* @param event Pointer to hold the returned event object.
977
* @return event handle, or NULL if failed.
979
PJ_DECL(pj_status_t) pj_event_create(pj_pool_t *pool, const char *name,
980
pj_bool_t manual_reset, pj_bool_t initial,
984
* Wait for event to be signaled.
986
* @param event The event object.
988
* @return zero if successfull.
990
PJ_DECL(pj_status_t) pj_event_wait(pj_event_t *event);
993
* Try wait for event object to be signalled.
995
* @param event The event object.
997
* @return zero if successfull.
999
PJ_DECL(pj_status_t) pj_event_trywait(pj_event_t *event);
1002
* Set the event object state to signaled. For auto-reset event, this
1003
* will only release the first thread that are waiting on the event. For
1004
* manual reset event, the state remains signaled until the event is reset.
1005
* If there is no thread waiting on the event, the event object state
1008
* @param event The event object.
1010
* @return zero if successfull.
1012
PJ_DECL(pj_status_t) pj_event_set(pj_event_t *event);
1015
* Set the event object to signaled state to release appropriate number of
1016
* waiting threads and then reset the event object to non-signaled. For
1017
* manual-reset event, this function will release all waiting threads. For
1018
* auto-reset event, this function will only release one waiting thread.
1020
* @param event The event object.
1022
* @return zero if successfull.
1024
PJ_DECL(pj_status_t) pj_event_pulse(pj_event_t *event);
1027
* Set the event object state to non-signaled.
1029
* @param event The event object.
1031
* @return zero if successfull.
1033
PJ_DECL(pj_status_t) pj_event_reset(pj_event_t *event);
1036
* Destroy the event object.
1038
* @param event The event object.
1040
* @return zero if successfull.
1042
PJ_DECL(pj_status_t) pj_event_destroy(pj_event_t *event);
1047
#endif /* PJ_HAS_EVENT_OBJ */
1049
/* **************************************************************************/
1051
* @addtogroup PJ_TIME Time Data Type and Manipulation.
1054
* This module provides API for manipulating time.
1056
* \section pj_time_examples_sec Examples
1058
* For examples, please see:
1059
* - \ref page_pjlib_sleep_test
1063
* Get current time of day in local representation.
1065
* @param tv Variable to store the result.
1067
* @return zero if successfull.
1069
PJ_DECL(pj_status_t) pj_gettimeofday(pj_time_val *tv);
1073
* Parse time value into date/time representation.
1075
* @param tv The time.
1076
* @param pt Variable to store the date time result.
1078
* @return zero if successfull.
1080
PJ_DECL(pj_status_t) pj_time_decode(const pj_time_val *tv, pj_parsed_time *pt);
1083
* Encode date/time to time value.
1085
* @param pt The date/time.
1086
* @param tv Variable to store time value result.
1088
* @return zero if successfull.
1090
PJ_DECL(pj_status_t) pj_time_encode(const pj_parsed_time *pt, pj_time_val *tv);
1093
* Convert local time to GMT.
1095
* @param tv Time to convert.
1097
* @return zero if successfull.
1099
PJ_DECL(pj_status_t) pj_time_local_to_gmt(pj_time_val *tv);
1102
* Convert GMT to local time.
1104
* @param tv Time to convert.
1106
* @return zero if successfull.
1108
PJ_DECL(pj_status_t) pj_time_gmt_to_local(pj_time_val *tv);
1114
/* **************************************************************************/
1115
#if defined(PJ_TERM_HAS_COLOR) && PJ_TERM_HAS_COLOR != 0
1118
* @defgroup PJ_TERM Terminal
1124
* Set current terminal color.
1126
* @param color The RGB color.
1128
* @return zero on success.
1130
PJ_DECL(pj_status_t) pj_term_set_color(pj_color_t color);
1133
* Get current terminal foreground color.
1135
* @return RGB color.
1137
PJ_DECL(pj_color_t) pj_term_get_color(void);
1143
#endif /* PJ_TERM_HAS_COLOR */
1145
/* **************************************************************************/
1147
* @defgroup PJ_TIMESTAMP High Resolution Timestamp
1151
* PJLIB provides <b>High Resolution Timestamp</b> API to access highest
1152
* resolution timestamp value provided by the platform. The API is usefull
1153
* to measure precise elapsed time, and can be used in applications such
1156
* The timestamp value is represented in cycles, and can be related to
1157
* normal time (in seconds or sub-seconds) using various functions provided.
1159
* \section pj_timestamp_examples_sec Examples
1161
* For examples, please see:
1162
* - \ref page_pjlib_sleep_test
1163
* - \ref page_pjlib_timestamp_test
1167
* High resolution timer.
1169
#if defined(PJ_HAS_HIGH_RES_TIMER) && PJ_HAS_HIGH_RES_TIMER != 0
1172
* Get monotonic time since some unspecified starting point.
1174
* @param tv Variable to store the result.
1176
* @return PJ_SUCCESS if successful.
1178
PJ_DECL(pj_status_t) pj_gettickcount(pj_time_val *tv);
1181
* Acquire high resolution timer value. The time value are stored
1184
* @param ts High resolution timer value.
1185
* @return PJ_SUCCESS or the appropriate error code.
1187
* @see pj_get_timestamp_freq().
1189
PJ_DECL(pj_status_t) pj_get_timestamp(pj_timestamp *ts);
1192
* Get high resolution timer frequency, in cycles per second.
1194
* @param freq Timer frequency, in cycles per second.
1195
* @return PJ_SUCCESS or the appropriate error code.
1197
PJ_DECL(pj_status_t) pj_get_timestamp_freq(pj_timestamp *freq);
1200
* Set timestamp from 32bit values.
1201
* @param t The timestamp to be set.
1202
* @param hi The high 32bit part.
1203
* @param lo The low 32bit part.
1205
PJ_INLINE(void) pj_set_timestamp32(pj_timestamp *t, pj_uint32_t hi,
1214
* Compare timestamp t1 and t2.
1217
* @return -1 if (t1 < t2), 1 if (t1 > t2), or 0 if (t1 == t2)
1219
PJ_INLINE(int) pj_cmp_timestamp(const pj_timestamp *t1, const pj_timestamp *t2)
1222
if (t1->u64 < t2->u64)
1224
else if (t1->u64 > t2->u64)
1229
if (t1->u32.hi < t2->u32.hi ||
1230
(t1->u32.hi == t2->u32.hi && t1->u32.lo < t2->u32.lo))
1232
else if (t1->u32.hi > t2->u32.hi ||
1233
(t1->u32.hi == t2->u32.hi && t1->u32.lo > t2->u32.lo))
1242
* Add timestamp t2 to t1.
1246
PJ_INLINE(void) pj_add_timestamp(pj_timestamp *t1, const pj_timestamp *t2)
1251
pj_uint32_t old = t1->u32.lo;
1252
t1->u32.hi += t2->u32.hi;
1253
t1->u32.lo += t2->u32.lo;
1254
if (t1->u32.lo < old)
1260
* Add timestamp t2 to t1.
1264
PJ_INLINE(void) pj_add_timestamp32(pj_timestamp *t1, pj_uint32_t t2)
1269
pj_uint32_t old = t1->u32.lo;
1271
if (t1->u32.lo < old)
1277
* Substract timestamp t2 from t1.
1281
PJ_INLINE(void) pj_sub_timestamp(pj_timestamp *t1, const pj_timestamp *t2)
1286
t1->u32.hi -= t2->u32.hi;
1287
if (t1->u32.lo >= t2->u32.lo)
1288
t1->u32.lo -= t2->u32.lo;
1290
t1->u32.lo -= t2->u32.lo;
1297
* Substract timestamp t2 from t1.
1301
PJ_INLINE(void) pj_sub_timestamp32(pj_timestamp *t1, pj_uint32_t t2)
1306
if (t1->u32.lo >= t2)
1316
* Get the timestamp difference between t2 and t1 (that is t2 minus t1),
1317
* and return a 32bit signed integer difference.
1319
PJ_INLINE(pj_int32_t) pj_timestamp_diff32(const pj_timestamp *t1,
1320
const pj_timestamp *t2)
1322
/* Be careful with the signess (I think!) */
1324
pj_int64_t diff = t2->u64 - t1->u64;
1325
return (pj_int32_t) diff;
1327
pj_int32 diff = t2->u32.lo - t1->u32.lo;
1334
* Calculate the elapsed time, and store it in pj_time_val.
1335
* This function calculates the elapsed time using highest precision
1336
* calculation that is available for current platform, considering
1337
* whether floating point or 64-bit precision arithmetic is available.
1338
* For maximum portability, application should prefer to use this function
1339
* rather than calculating the elapsed time by itself.
1341
* @param start The starting timestamp.
1342
* @param stop The end timestamp.
1344
* @return Elapsed time as #pj_time_val.
1346
* @see pj_elapsed_usec(), pj_elapsed_cycle(), pj_elapsed_nanosec()
1348
PJ_DECL(pj_time_val) pj_elapsed_time( const pj_timestamp *start,
1349
const pj_timestamp *stop );
1352
* Calculate the elapsed time as 32-bit miliseconds.
1353
* This function calculates the elapsed time using highest precision
1354
* calculation that is available for current platform, considering
1355
* whether floating point or 64-bit precision arithmetic is available.
1356
* For maximum portability, application should prefer to use this function
1357
* rather than calculating the elapsed time by itself.
1359
* @param start The starting timestamp.
1360
* @param stop The end timestamp.
1362
* @return Elapsed time in milisecond.
1364
* @see pj_elapsed_time(), pj_elapsed_cycle(), pj_elapsed_nanosec()
1366
PJ_DECL(pj_uint32_t) pj_elapsed_msec( const pj_timestamp *start,
1367
const pj_timestamp *stop );
1370
* Variant of #pj_elapsed_msec() which returns 64bit value.
1372
PJ_DECL(pj_uint64_t) pj_elapsed_msec64(const pj_timestamp *start,
1373
const pj_timestamp *stop );
1376
* Calculate the elapsed time in 32-bit microseconds.
1377
* This function calculates the elapsed time using highest precision
1378
* calculation that is available for current platform, considering
1379
* whether floating point or 64-bit precision arithmetic is available.
1380
* For maximum portability, application should prefer to use this function
1381
* rather than calculating the elapsed time by itself.
1383
* @param start The starting timestamp.
1384
* @param stop The end timestamp.
1386
* @return Elapsed time in microsecond.
1388
* @see pj_elapsed_time(), pj_elapsed_cycle(), pj_elapsed_nanosec()
1390
PJ_DECL(pj_uint32_t) pj_elapsed_usec( const pj_timestamp *start,
1391
const pj_timestamp *stop );
1394
* Calculate the elapsed time in 32-bit nanoseconds.
1395
* This function calculates the elapsed time using highest precision
1396
* calculation that is available for current platform, considering
1397
* whether floating point or 64-bit precision arithmetic is available.
1398
* For maximum portability, application should prefer to use this function
1399
* rather than calculating the elapsed time by itself.
1401
* @param start The starting timestamp.
1402
* @param stop The end timestamp.
1404
* @return Elapsed time in nanoseconds.
1406
* @see pj_elapsed_time(), pj_elapsed_cycle(), pj_elapsed_usec()
1408
PJ_DECL(pj_uint32_t) pj_elapsed_nanosec( const pj_timestamp *start,
1409
const pj_timestamp *stop );
1412
* Calculate the elapsed time in 32-bit cycles.
1413
* This function calculates the elapsed time using highest precision
1414
* calculation that is available for current platform, considering
1415
* whether floating point or 64-bit precision arithmetic is available.
1416
* For maximum portability, application should prefer to use this function
1417
* rather than calculating the elapsed time by itself.
1419
* @param start The starting timestamp.
1420
* @param stop The end timestamp.
1422
* @return Elapsed time in cycles.
1424
* @see pj_elapsed_usec(), pj_elapsed_time(), pj_elapsed_nanosec()
1426
PJ_DECL(pj_uint32_t) pj_elapsed_cycle( const pj_timestamp *start,
1427
const pj_timestamp *stop );
1430
#endif /* PJ_HAS_HIGH_RES_TIMER */
1435
/* **************************************************************************/
1437
* @defgroup PJ_APP_OS Application execution
1442
/* Type for main function. */
1443
typedef int (*pj_main_func_ptr)(int argc, char *argv[]);
1446
* Run the application. This function has to be called in the main thread
1447
* and after doing the necessary initialization according to the flags
1448
* provided, it will call main_func() function.
1450
* @param main_func Application's main function.
1451
* @param argc Number of arguments from the main() function, which
1452
* will be passed to main_func() function.
1453
* @param argv The arguments from the main() function, which will
1454
* be passed to main_func() function.
1455
* @param flags Flags for application execution, currently must be 0.
1457
* @return main_func()'s return value.
1459
int pj_run_app(pj_main_func_ptr main_func, int argc, char *argv[],
1465
/* **************************************************************************/
1467
* Internal PJLIB function to initialize the threading subsystem.
1468
* @return PJ_SUCCESS or the appropriate error code.
1470
pj_status_t pj_thread_init(void);
1475
#endif /* __PJ_OS_H__ */