blob: 845a26bc0989088ecef586f55a9754c746f29202 [file] [log] [blame]
Benny Prijono0a749f12005-10-31 21:02:30 +00001/* $Header: /pjproject-0.3/pjlib/include/pj/os.h 12 10/29/05 11:30a Bennylp $ */
2
3#ifndef __PJ_OS_H__
4#define __PJ_OS_H__
5
6/**
7 * @file os.h
8 * @brief OS dependent functions
9 */
10#include <pj/types.h>
11
12PJ_BEGIN_DECL
13
14/**
15 * @defgroup PJ_OS Operating System Dependent Functionality.
16 * @ingroup PJ
17 */
18
19
20///////////////////////////////////////////////////////////////////////////////
21/**
22 * @defgroup PJ_THREAD Threads
23 * @ingroup PJ_OS
24 * @{
25 * This module provides multithreading API.
26 *
27 * \section pj_thread_examples_sec Examples
28 *
29 * For examples, please see:
30 * - \ref page_pjlib_thread_test
31 * - \ref page_pjlib_sleep_test
32 *
33 */
34
35/**
36 * Thread creation flags:
37 * - PJ_THREAD_SUSPENDED: specify that the thread should be created suspended.
38 */
39typedef enum pj_thread_create_flags
40{
41 PJ_THREAD_SUSPENDED = 1
42} pj_thread_create_flags;
43
44
45/**
46 * Specify this as \a stack_size argument in #pj_thread_create() to specify
47 * that thread should use default stack size for the current platform.
48 */
49#define PJ_THREAD_DEFAULT_STACK_SIZE 0
50
51/**
52 * Type of thread entry function.
53 */
54typedef int (PJ_THREAD_FUNC pj_thread_proc)(void*);
55
56/**
57 * Size of thread struct.
58 */
59#if !defined(PJ_THREAD_DESC_SIZE)
60# define PJ_THREAD_DESC_SIZE (PJ_MAX_OBJ_NAME + 10*sizeof(long))
61#endif
62
63/**
64 * Thread structure, to thread's state when the thread is created by external
65 * or native API.
66 */
67typedef pj_uint8_t pj_thread_desc[PJ_THREAD_DESC_SIZE];
68
69/**
70 * Get process ID.
71 * @return process ID.
72 */
73PJ_DECL(pj_uint32_t) pj_getpid(void);
74
75/**
76 * Create a new thread.
77 *
78 * @param pool The memory pool from which the thread record
79 * will be allocated from.
80 * @param thread_name The optional name to be assigned to the thread.
81 * @param proc Thread entry function.
82 * @param arg Argument to be passed to the thread entry function.
83 * @param stack_size The size of the stack for the new thread, or ZERO or
84 * PJ_THREAD_DEFAULT_STACK_SIZE to let the
85 * library choose the reasonable size for the stack.
86 * For some systems, the stack will be allocated from
87 * the pool, so the pool must have suitable capacity.
88 * @param flags Flags for thread creation, which is bitmask combination
89 * from enum pj_thread_create_flags.
90 * @param thread Pointer to hold the newly created thread.
91 *
92 * @return PJ_SUCCESS on success, or the error code.
93 */
94PJ_DECL(pj_status_t) pj_thread_create( pj_pool_t *pool,
95 const char *thread_name,
96 pj_thread_proc *proc,
97 void *arg,
98 pj_size_t stack_size,
99 unsigned flags,
100 pj_thread_t **thread );
101
102/**
103 * Register a thread that was created by external or native API to PJLIB.
104 * This function must be called in the context of the thread being registered.
105 * When the thread is created by external function or API call,
106 * it must be 'registered' to PJLIB using pj_thread_register(), so that it can
107 * cooperate with PJLIB's framework. During registration, some data needs to
108 * be maintained, and this data must remain available during the thread's
109 * lifetime.
110 *
111 * @param thread_name The optional name to be assigned to the thread.
112 * @param desc Thread descriptor, which must be available throughout
113 * the lifetime of the thread.
114 * @param thread Pointer to hold the created thread handle.
115 *
116 * @return PJ_SUCCESS on success, or the error code.
117 */
118PJ_DECL(pj_status_t) pj_thread_register ( const char *thread_name,
119 pj_thread_desc desc,
120 pj_thread_t **thread);
121
122/**
123 * Get thread name.
124 *
125 * @param thread The thread handle.
126 *
127 * @return Thread name as null terminated string.
128 */
129PJ_DECL(const char*) pj_thread_get_name(pj_thread_t *thread);
130
131/**
132 * Resume a suspended thread.
133 *
134 * @param thread The thread handle.
135 *
136 * @return zero on success.
137 */
138PJ_DECL(pj_status_t) pj_thread_resume(pj_thread_t *thread);
139
140/**
141 * Get the current thread.
142 *
143 * @return Thread handle of current thread.
144 */
145PJ_DECL(pj_thread_t*) pj_thread_this(void);
146
147/**
148 * Join thread.
149 * This function will block the caller thread until the specified thread exits.
150 *
151 * @param thread The thread handle.
152 *
153 * @return zero on success.
154 */
155PJ_DECL(pj_status_t) pj_thread_join(pj_thread_t *thread);
156
157
158/**
159 * Destroy thread and release resources allocated for the thread.
160 * However, the memory allocated for the pj_thread_t itself will only be released
161 * when the pool used to create the thread is destroyed.
162 *
163 * @param thread The thread handle.
164 *
165 * @return zero on success.
166 */
167PJ_DECL(pj_status_t) pj_thread_destroy(pj_thread_t *thread);
168
169
170/**
171 * Put the current thread to sleep for the specified miliseconds.
172 *
173 * @param msec Miliseconds delay.
174 *
175 * @return zero if successfull.
176 */
177PJ_DECL(pj_status_t) pj_thread_sleep(unsigned msec);
178
179/**
180 * @def PJ_CHECK_STACK()
181 * PJ_CHECK_STACK() macro is used to check the sanity of the stack.
182 * The OS implementation may check that no stack overflow occurs, and
183 * it also may collect statistic about stack usage.
184 */
185#if defined(PJ_OS_HAS_CHECK_STACK) && PJ_OS_HAS_CHECK_STACK!=0
186
187# define PJ_CHECK_STACK() pj_thread_check_stack(__FILE__, __LINE__)
188
189/** @internal
190 * The implementation of stack checking.
191 */
192PJ_DECL(void) pj_thread_check_stack(const char *file, int line);
193
194/** @internal
195 * Get maximum stack usage statistic.
196 */
197PJ_DECL(pj_uint32_t) pj_thread_get_stack_max_usage(pj_thread_t *thread);
198
199/** @internal
200 * Dump thread stack status.
201 */
202PJ_DECL(pj_status_t) pj_thread_get_stack_info(pj_thread_t *thread,
203 const char **file,
204 int *line);
205#else
206
207# define PJ_CHECK_STACK()
208/** pj_thread_get_stack_max_usage() for the thread */
209# define pj_thread_get_stack_max_usage(thread) 0
210/** pj_thread_get_stack_info() for the thread */
211# define pj_thread_get_stack_info(thread,f,l) (*(f)="",*(l)=0)
212#endif /* PJ_OS_HAS_CHECK_STACK */
213
214/**
215 * @}
216 */
217
218///////////////////////////////////////////////////////////////////////////////
219/**
220 * @defgroup PJ_TLS Thread Local Storage.
221 * @ingroup PJ_OS
222 * @{
223 */
224
225/**
226 * Allocate thread local storage index. The initial value of the variable at
227 * the index is zero.
228 *
229 * @param index Pointer to hold the return value.
230 * @return PJ_SUCCESS on success, or the error code.
231 */
232PJ_DECL(pj_status_t) pj_thread_local_alloc(long *index);
233
234/**
235 * Deallocate thread local variable.
236 *
237 * @param index The variable index.
238 */
239PJ_DECL(void) pj_thread_local_free(long index);
240
241/**
242 * Set the value of thread local variable.
243 *
244 * @param index The index of the variable.
245 * @param value The value.
246 */
247PJ_DECL(void) pj_thread_local_set(long index, void *value);
248
249/**
250 * Get the value of thread local variable.
251 *
252 * @param index The index of the variable.
253 * @return The value.
254 */
255PJ_DECL(void*) pj_thread_local_get(long index);
256
257
258/**
259 * @}
260 */
261
262
263///////////////////////////////////////////////////////////////////////////////
264/**
265 * @defgroup PJ_ATOMIC Atomic Variables
266 * @ingroup PJ_OS
267 * @{
268 *
269 * This module provides API to manipulate atomic variables.
270 *
271 * \section pj_atomic_examples_sec Examples
272 *
273 * For some example codes, please see:
274 * - @ref page_pjlib_atomic_test
275 */
276
277
278/**
279 * Create atomic variable.
280 *
281 * @param pool The pool.
282 * @param initial The initial value of the atomic variable.
283 * @param atomic Pointer to hold the atomic variable upon return.
284 *
285 * @return PJ_SUCCESS on success, or the error code.
286 */
287PJ_DECL(pj_status_t) pj_atomic_create( pj_pool_t *pool,
288 pj_atomic_value_t initial,
289 pj_atomic_t **atomic );
290
291/**
292 * Destroy atomic variable.
293 *
294 * @param atomic_var the atomic variable.
295 *
296 * @return PJ_SUCCESS if success.
297 */
298PJ_DECL(pj_status_t) pj_atomic_destroy( pj_atomic_t *atomic_var );
299
300/**
301 * Set the value of an atomic type, and return the previous value.
302 *
303 * @param atomic_var the atomic variable.
304 * @param value value to be set to the variable.
305 *
306 * @return the previous value of the variable.
307 */
308PJ_DECL(pj_atomic_value_t) pj_atomic_set(pj_atomic_t *atomic_var,
309 pj_atomic_value_t value);
310
311/**
312 * Get the value of an atomic type.
313 *
314 * @param atomic_var the atomic variable.
315 *
316 * @return the value of the atomic variable.
317 */
318PJ_DECL(pj_atomic_value_t) pj_atomic_get(pj_atomic_t *atomic_var);
319
320/**
321 * Increment the value of an atomic type.
322 *
323 * @param atomic_var the atomic variable.
324 *
325 * @return the result.
326 */
327PJ_DECL(pj_atomic_value_t) pj_atomic_inc(pj_atomic_t *atomic_var);
328
329/**
330 * Decrement the value of an atomic type.
331 *
332 * @param atomic_var the atomic variable.
333 *
334 * @return the result.
335 */
336PJ_DECL(pj_atomic_value_t) pj_atomic_dec(pj_atomic_t *atomic_var);
337
338/**
339 * @}
340 */
341
342///////////////////////////////////////////////////////////////////////////////
343/**
344 * @defgroup PJ_MUTEX Mutexes.
345 * @ingroup PJ_OS
346 * @{
347 *
348 * Mutex manipulation. Alternatively, application can use higher abstraction
349 * for lock objects, which provides uniform API for all kinds of lock
350 * mechanisms, including mutex. See @ref PJ_LOCK for more information.
351 */
352
353/**
354 * Mutex types:
355 * - PJ_MUTEX_DEFAULT: default mutex type, which is system dependent.
356 * - PJ_MUTEX_SIMPLE: non-recursive mutex.
357 * - PJ_MUTEX_RECURSIVE: recursive mutex.
358 */
359typedef enum pj_mutex_type_e
360{
361 PJ_MUTEX_DEFAULT,
362 PJ_MUTEX_SIMPLE,
363 PJ_MUTEX_RECURSE,
364} pj_mutex_type_e;
365
366
367/**
368 * Create mutex of the specified type.
369 *
370 * @param pool The pool.
371 * @param name Name to be associated with the mutex (for debugging).
372 * @param type The type of the mutex, of type #pj_mutex_type_e.
373 * @param mutex Pointer to hold the returned mutex instance.
374 *
375 * @return PJ_SUCCESS on success, or the error code.
376 */
377PJ_DECL(pj_status_t) pj_mutex_create(pj_pool_t *pool,
378 const char *name,
379 int type,
380 pj_mutex_t **mutex);
381
382/**
383 * Create simple, non-recursive mutex.
384 * This function is a simple wrapper for #pj_mutex_create to create
385 * non-recursive mutex.
386 *
387 * @param pool The pool.
388 * @param name Mutex name.
389 * @param mutex Pointer to hold the returned mutex instance.
390 *
391 * @return PJ_SUCCESS on success, or the error code.
392 */
393PJ_DECL(pj_status_t) pj_mutex_create_simple( pj_pool_t *pool, const char *name,
394 pj_mutex_t **mutex );
395
396/**
397 * Create recursive mutex.
398 * This function is a simple wrapper for #pj_mutex_create to create
399 * recursive mutex.
400 *
401 * @param pool The pool.
402 * @param name Mutex name.
403 * @param mutex Pointer to hold the returned mutex instance.
404 *
405 * @return PJ_SUCCESS on success, or the error code.
406 */
407PJ_DECL(pj_status_t) pj_mutex_create_recursive( pj_pool_t *pool,
408 const char *name,
409 pj_mutex_t **mutex );
410
411/**
412 * Acquire mutex lock.
413 *
414 * @param mutex The mutex.
415 * @return PJ_SUCCESS on success, or the error code.
416 */
417PJ_DECL(pj_status_t) pj_mutex_lock(pj_mutex_t *mutex);
418
419/**
420 * Release mutex lock.
421 *
422 * @param mutex The mutex.
423 * @return PJ_SUCCESS on success, or the error code.
424 */
425PJ_DECL(pj_status_t) pj_mutex_unlock(pj_mutex_t *mutex);
426
427/**
428 * Try to acquire mutex lock.
429 *
430 * @param mutex The mutex.
431 * @return PJ_SUCCESS on success, or the error code if the
432 * lock couldn't be acquired.
433 */
434PJ_DECL(pj_status_t) pj_mutex_trylock(pj_mutex_t *mutex);
435
436/**
437 * Destroy mutex.
438 *
439 * @param mutex Te mutex.
440 * @return PJ_SUCCESS on success, or the error code.
441 */
442PJ_DECL(pj_status_t) pj_mutex_destroy(pj_mutex_t *mutex);
443
444/**
445 * Determine whether calling thread is owning the mutex (only available when
446 * PJ_DEBUG is set).
447 * @param mutex The mutex.
448 * @return Non-zero if yes.
449 */
450#if defined(PJ_DEBUG) && PJ_DEBUG != 0
451 PJ_DECL(pj_bool_t) pj_mutex_is_locked(pj_mutex_t *mutex);
452#else
453# define pj_mutex_is_locked(mutex) 1
454#endif
455
456/**
457 * @}
458 */
459
460///////////////////////////////////////////////////////////////////////////////
461/**
462 * @defgroup PJ_CRIT_SEC Critical sections.
463 * @ingroup PJ_OS
464 * @{
465 * Critical section protection can be used to protect regions where:
466 * - mutual exclusion protection is needed.
467 * - it's rather too expensive to create a mutex.
468 * - the time spent in the region is very very brief.
469 *
470 * Critical section is a global object, and it prevents any threads from
471 * entering any regions that are protected by critical section once a thread
472 * is already in the section.
473 *
474 * Critial section is \a not recursive!
475 *
476 * Application <b>MUST NOT</b> call any functions that may cause current
477 * thread to block (such as allocating memory, performing I/O, locking mutex,
478 * etc.) while holding the critical section.
479 */
480/**
481 * Enter critical section.
482 */
483PJ_DECL(void) pj_enter_critical_section(void);
484
485/**
486 * Leave critical section.
487 */
488PJ_DECL(void) pj_leave_critical_section(void);
489
490/**
491 * @}
492 */
493
494///////////////////////////////////////////////////////////////////////////////
495#if defined(PJ_HAS_SEMAPHORE) && PJ_HAS_SEMAPHORE != 0
496/**
497 * @defgroup PJ_SEM Semaphores.
498 * @ingroup PJ_OS
499 * @{
500 *
501 * This module provides abstraction for semaphores, where available.
502 */
503
504/**
505 * Create semaphore.
506 *
507 * @param pool The pool.
508 * @param name Name to be assigned to the semaphore (for logging purpose)
509 * @param initial The initial count of the semaphore.
510 * @param max The maximum count of the semaphore.
511 * @param sem Pointer to hold the semaphore created.
512 *
513 * @return PJ_SUCCESS on success, or the error code.
514 */
515PJ_DECL(pj_status_t) pj_sem_create( pj_pool_t *pool,
516 const char *name,
517 unsigned initial,
518 unsigned max,
519 pj_sem_t **sem);
520
521/**
522 * Wait for semaphore.
523 *
524 * @param sem The semaphore.
525 *
526 * @return PJ_SUCCESS on success, or the error code.
527 */
528PJ_DECL(pj_status_t) pj_sem_wait(pj_sem_t *sem);
529
530/**
531 * Try wait for semaphore.
532 *
533 * @param sem The semaphore.
534 *
535 * @return PJ_SUCCESS on success, or the error code.
536 */
537PJ_DECL(pj_status_t) pj_sem_trywait(pj_sem_t *sem);
538
539/**
540 * Release semaphore.
541 *
542 * @param sem The semaphore.
543 *
544 * @return PJ_SUCCESS on success, or the error code.
545 */
546PJ_DECL(pj_status_t) pj_sem_post(pj_sem_t *sem);
547
548/**
549 * Destroy semaphore.
550 *
551 * @param sem The semaphore.
552 *
553 * @return PJ_SUCCESS on success, or the error code.
554 */
555PJ_DECL(pj_status_t) pj_sem_destroy(pj_sem_t *sem);
556
557/**
558 * @}
559 */
560#endif /* PJ_HAS_SEMAPHORE */
561
562
563///////////////////////////////////////////////////////////////////////////////
564#if defined(PJ_HAS_EVENT_OBJ) && PJ_HAS_EVENT_OBJ != 0
565/**
566 * @defgroup PJ_EVENT Event Object.
567 * @ingroup PJ_OS
568 * @{
569 *
570 * This module provides abstraction to event object (e.g. Win32 Event) where
571 * available. Event objects can be used for synchronization among threads.
572 */
573
574/**
575 * Create event object.
576 *
577 * @param pool The pool.
578 * @param name The name of the event object (for logging purpose).
579 * @param manual_reset Specify whether the event is manual-reset
580 * @param initial Specify the initial state of the event object.
581 * @param event Pointer to hold the returned event object.
582 *
583 * @return event handle, or NULL if failed.
584 */
585PJ_DECL(pj_status_t) pj_event_create(pj_pool_t *pool, const char *name,
586 pj_bool_t manual_reset, pj_bool_t initial,
587 pj_event_t **event);
588
589/**
590 * Wait for event to be signaled.
591 *
592 * @param event The event object.
593 *
594 * @return zero if successfull.
595 */
596PJ_DECL(pj_status_t) pj_event_wait(pj_event_t *event);
597
598/**
599 * Try wait for event object to be signalled.
600 *
601 * @param event The event object.
602 *
603 * @return zero if successfull.
604 */
605PJ_DECL(pj_status_t) pj_event_trywait(pj_event_t *event);
606
607/**
608 * Set the event object state to signaled. For auto-reset event, this
609 * will only release the first thread that are waiting on the event. For
610 * manual reset event, the state remains signaled until the event is reset.
611 * If there is no thread waiting on the event, the event object state
612 * remains signaled.
613 *
614 * @param event The event object.
615 *
616 * @return zero if successfull.
617 */
618PJ_DECL(pj_status_t) pj_event_set(pj_event_t *event);
619
620/**
621 * Set the event object to signaled state to release appropriate number of
622 * waiting threads and then reset the event object to non-signaled. For
623 * manual-reset event, this function will release all waiting threads. For
624 * auto-reset event, this function will only release one waiting thread.
625 *
626 * @param event The event object.
627 *
628 * @return zero if successfull.
629 */
630PJ_DECL(pj_status_t) pj_event_pulse(pj_event_t *event);
631
632/**
633 * Set the event object state to non-signaled.
634 *
635 * @param event The event object.
636 *
637 * @return zero if successfull.
638 */
639PJ_DECL(pj_status_t) pj_event_reset(pj_event_t *event);
640
641/**
642 * Destroy the event object.
643 *
644 * @param event The event object.
645 *
646 * @return zero if successfull.
647 */
648PJ_DECL(pj_status_t) pj_event_destroy(pj_event_t *event);
649
650/**
651 * @}
652 */
653#endif /* PJ_HAS_EVENT_OBJ */
654
655///////////////////////////////////////////////////////////////////////////////
656/**
657 * @addtogroup PJ_TIME Time Data Type and Manipulation.
658 * @ingroup PJ_OS
659 * @{
660 * This module provides API for manipulating time.
661 *
662 * \section pj_time_examples_sec Examples
663 *
664 * For examples, please see:
665 * - \ref page_pjlib_sleep_test
666 */
667
668/**
669 * Get current time of day in local representation.
670 *
671 * @param tv Variable to store the result.
672 *
673 * @return zero if successfull.
674 */
675PJ_DECL(pj_status_t) pj_gettimeofday(pj_time_val *tv);
676
677
678/**
679 * Parse time value into date/time representation.
680 *
681 * @param tv The time.
682 * @param pt Variable to store the date time result.
683 *
684 * @return zero if successfull.
685 */
686PJ_DECL(pj_status_t) pj_time_decode(const pj_time_val *tv, pj_parsed_time *pt);
687
688/**
689 * Encode date/time to time value.
690 *
691 * @param pt The date/time.
692 * @param tv Variable to store time value result.
693 *
694 * @return zero if successfull.
695 */
696PJ_DECL(pj_status_t) pj_time_encode(const pj_parsed_time *pt, pj_time_val *tv);
697
698/**
699 * Convert local time to GMT.
700 *
701 * @param tv Time to convert.
702 *
703 * @return zero if successfull.
704 */
705PJ_DECL(pj_status_t) pj_time_local_to_gmt(pj_time_val *tv);
706
707/**
708 * Convert GMT to local time.
709 *
710 * @param tv Time to convert.
711 *
712 * @return zero if successfull.
713 */
714PJ_DECL(pj_status_t) pj_time_gmt_to_local(pj_time_val *tv);
715
716/**
717 * @}
718 */
719
720///////////////////////////////////////////////////////////////////////////////
721#if defined(PJ_TERM_HAS_COLOR) && PJ_TERM_HAS_COLOR != 0
722
723/**
724 * @defgroup PJ_TERM Terminal
725 * @ingroup PJ_OS
726 * @{
727 */
728
729/**
730 * Set current terminal color.
731 *
732 * @param color The RGB color.
733 *
734 * @return zero on success.
735 */
736PJ_DECL(pj_status_t) pj_term_set_color(pj_color_t color);
737
738/**
739 * Get current terminal foreground color.
740 *
741 * @return RGB color.
742 */
743PJ_DECL(pj_color_t) pj_term_get_color(void);
744
745/**
746 * @}
747 */
748
749#endif /* PJ_TERM_HAS_COLOR */
750
751///////////////////////////////////////////////////////////////////////////////
752/**
753 * @defgroup PJ_TIMESTAMP High Resolution Timestamp
754 * @ingroup PJ_OS
755 * @{
756 *
757 * PJLIB provides <b>High Resolution Timestamp</b> API to access highest
758 * resolution timestamp value provided by the platform. The API is usefull
759 * to measure precise elapsed time, and can be used in applications such
760 * as profiling.
761 *
762 * The timestamp value is represented in cycles, and can be related to
763 * normal time (in seconds or sub-seconds) using various functions provided.
764 *
765 * \section pj_timestamp_examples_sec Examples
766 *
767 * For examples, please see:
768 * - \ref page_pjlib_sleep_test
769 * - \ref page_pjlib_timestamp_test
770 */
771
772/*
773 * High resolution timer.
774 */
775#if defined(PJ_HAS_HIGH_RES_TIMER) && PJ_HAS_HIGH_RES_TIMER != 0
776
777/**
778 * This structure represents high resolution (64bit) time value. The time
779 * values represent time in cycles, which is retrieved by calling
780 * #pj_get_timestamp().
781 */
782typedef union pj_timestamp
783{
784 struct
785 {
786 pj_uint32_t lo; /**< Low 32-bit value of the 64-bit value. */
787 pj_uint32_t hi; /**< high 32-bit value of the 64-bit value. */
788 } u32; /**< The 64-bit value as two 32-bit values. */
789
790#if PJ_HAS_INT64
791 pj_uint64_t u64; /**< The whole 64-bit value, where available. */
792#endif
793} pj_timestamp;
794
795
796/**
797 * Acquire high resolution timer value. The time value are stored
798 * in cycles.
799 *
800 * @param ts High resolution timer value.
801 * @return PJ_SUCCESS or the appropriate error code.
802 *
803 * @see pj_get_timestamp_freq().
804 */
805PJ_DECL(pj_status_t) pj_get_timestamp(pj_timestamp *ts);
806
807/**
808 * Get high resolution timer frequency, in cycles per second.
809 *
810 * @param freq Timer frequency, in cycles per second.
811 * @return PJ_SUCCESS or the appropriate error code.
812 */
813PJ_DECL(pj_status_t) pj_get_timestamp_freq(pj_timestamp *freq);
814
815/**
816 * Calculate the elapsed time, and store it in pj_time_val.
817 * This function calculates the elapsed time using highest precision
818 * calculation that is available for current platform, considering
819 * whether floating point or 64-bit precision arithmetic is available.
820 * For maximum portability, application should prefer to use this function
821 * rather than calculating the elapsed time by itself.
822 *
823 * @param start The starting timestamp.
824 * @param stop The end timestamp.
825 *
826 * @return Elapsed time as #pj_time_val.
827 *
828 * @see pj_elapsed_usec(), pj_elapsed_cycle(), pj_elapsed_nanosec()
829 */
830PJ_DECL(pj_time_val) pj_elapsed_time( const pj_timestamp *start,
831 const pj_timestamp *stop );
832
833/**
834 * Calculate the elapsed time in 32-bit microseconds.
835 * This function calculates the elapsed time using highest precision
836 * calculation that is available for current platform, considering
837 * whether floating point or 64-bit precision arithmetic is available.
838 * For maximum portability, application should prefer to use this function
839 * rather than calculating the elapsed time by itself.
840 *
841 * @param start The starting timestamp.
842 * @param stop The end timestamp.
843 *
844 * @return Elapsed time in microsecond.
845 *
846 * @see pj_elapsed_time(), pj_elapsed_cycle(), pj_elapsed_nanosec()
847 */
848PJ_DECL(pj_uint32_t) pj_elapsed_usec( const pj_timestamp *start,
849 const pj_timestamp *stop );
850
851/**
852 * Calculate the elapsed time in 32-bit nanoseconds.
853 * This function calculates the elapsed time using highest precision
854 * calculation that is available for current platform, considering
855 * whether floating point or 64-bit precision arithmetic is available.
856 * For maximum portability, application should prefer to use this function
857 * rather than calculating the elapsed time by itself.
858 *
859 * @param start The starting timestamp.
860 * @param stop The end timestamp.
861 *
862 * @return Elapsed time in nanoseconds.
863 *
864 * @see pj_elapsed_time(), pj_elapsed_cycle(), pj_elapsed_usec()
865 */
866PJ_DECL(pj_uint32_t) pj_elapsed_nanosec( const pj_timestamp *start,
867 const pj_timestamp *stop );
868
869/**
870 * Calculate the elapsed time in 32-bit cycles.
871 * This function calculates the elapsed time using highest precision
872 * calculation that is available for current platform, considering
873 * whether floating point or 64-bit precision arithmetic is available.
874 * For maximum portability, application should prefer to use this function
875 * rather than calculating the elapsed time by itself.
876 *
877 * @param start The starting timestamp.
878 * @param stop The end timestamp.
879 *
880 * @return Elapsed time in cycles.
881 *
882 * @see pj_elapsed_usec(), pj_elapsed_time(), pj_elapsed_nanosec()
883 */
884PJ_DECL(pj_uint32_t) pj_elapsed_cycle( const pj_timestamp *start,
885 const pj_timestamp *stop );
886
887
888#endif /* PJ_HAS_HIGH_RES_TIMER */
889
890/** @} */
891
892
893///////////////////////////////////////////////////////////////////////////////
894/**
895 * Internal PJLIB function to initialize the threading subsystem.
896 * @return PJ_SUCCESS or the appropriate error code.
897 */
898pj_status_t pj_thread_init(void);
899
900
901PJ_END_DECL
902
903#endif /* __PJ_OS_H__ */
904