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