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