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