blob: 38eb8ea60c26b0c0d5beac7c42c084bb8f1a72db [file] [log] [blame]
Benny Prijono9033e312005-11-21 02:08:39 +00001/* $Id$ */
2/*
Benny Prijono844653c2008-12-23 17:27:53 +00003 * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
4 * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
Benny Prijono9033e312005-11-21 02:08:39 +00005 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20#ifndef __PJ_OS_H__
21#define __PJ_OS_H__
22
23/**
24 * @file os.h
25 * @brief OS dependent functions
26 */
27#include <pj/types.h>
28
29PJ_BEGIN_DECL
30
31/**
32 * @defgroup PJ_OS Operating System Dependent Functionality.
Benny Prijono9033e312005-11-21 02:08:39 +000033 */
34
35
Benny Prijono92ac4472006-07-22 13:42:56 +000036/* **************************************************************************/
Benny Prijono9033e312005-11-21 02:08:39 +000037/**
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)
Benny Prijonod345a652006-07-31 15:10:36 +000070# define PJ_THREAD_DESC_SIZE (64)
Benny Prijono9033e312005-11-21 02:08:39 +000071#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/**
Benny Prijonod6b90f52006-08-11 19:25:17 +0000133 * Check if this thread has been registered to PJLIB.
134 *
135 * @return Non-zero if it is registered.
136 */
Benny Prijonoe71c3602006-10-03 17:00:00 +0000137PJ_DECL(pj_bool_t) pj_thread_is_registered(void);
Benny Prijonod6b90f52006-08-11 19:25:17 +0000138
139
140/**
Benny Prijono8f7adf72008-03-04 14:45:19 +0000141 * Get thread priority value for the thread.
142 *
143 * @param thread Thread handle.
144 *
145 * @return Thread priority value, or -1 on error.
146 */
147PJ_DECL(int) pj_thread_get_prio(pj_thread_t *thread);
148
149
150/**
151 * Set the thread priority. The priority value must be in the priority
152 * value range, which can be retrieved with #pj_thread_get_prio_min() and
153 * #pj_thread_get_prio_max() functions.
154 *
155 * @param thread Thread handle.
156 * @param prio New priority to be set to the thread.
157 *
158 * @return PJ_SUCCESS on success or the error code.
159 */
160PJ_DECL(pj_status_t) pj_thread_set_prio(pj_thread_t *thread, int prio);
161
162/**
163 * Get the lowest priority value available for this thread.
164 *
165 * @param thread Thread handle.
166 * @return Minimum thread priority value, or -1 on error.
167 */
168PJ_DECL(int) pj_thread_get_prio_min(pj_thread_t *thread);
169
170
171/**
172 * Get the highest priority value available for this thread.
173 *
174 * @param thread Thread handle.
175 * @return Minimum thread priority value, or -1 on error.
176 */
177PJ_DECL(int) pj_thread_get_prio_max(pj_thread_t *thread);
178
179
180/**
Benny Prijono83c38972007-11-21 14:12:01 +0000181 * Return native handle from pj_thread_t for manipulation using native
182 * OS APIs.
183 *
184 * @param thread PJLIB thread descriptor.
185 *
186 * @return Native thread handle. For example, when the
187 * backend thread uses pthread, this function will
188 * return pointer to pthread_t, and on Windows,
189 * this function will return HANDLE.
190 */
191PJ_DECL(void*) pj_thread_get_os_handle(pj_thread_t *thread);
192
193/**
Benny Prijono9033e312005-11-21 02:08:39 +0000194 * Get thread name.
195 *
196 * @param thread The thread handle.
197 *
198 * @return Thread name as null terminated string.
199 */
200PJ_DECL(const char*) pj_thread_get_name(pj_thread_t *thread);
201
202/**
203 * Resume a suspended thread.
204 *
205 * @param thread The thread handle.
206 *
207 * @return zero on success.
208 */
209PJ_DECL(pj_status_t) pj_thread_resume(pj_thread_t *thread);
210
211/**
212 * Get the current thread.
213 *
214 * @return Thread handle of current thread.
215 */
216PJ_DECL(pj_thread_t*) pj_thread_this(void);
217
218/**
Benny Prijono42c5b9e2006-05-10 19:24:40 +0000219 * Join thread, and block the caller thread until the specified thread exits.
220 * If the specified thread has already been dead, or it does not exist,
221 * the function will return immediately with successfull status.
Benny Prijono9033e312005-11-21 02:08:39 +0000222 *
223 * @param thread The thread handle.
224 *
Benny Prijono42c5b9e2006-05-10 19:24:40 +0000225 * @return PJ_SUCCESS on success.
Benny Prijono9033e312005-11-21 02:08:39 +0000226 */
227PJ_DECL(pj_status_t) pj_thread_join(pj_thread_t *thread);
228
229
230/**
231 * Destroy thread and release resources allocated for the thread.
232 * However, the memory allocated for the pj_thread_t itself will only be released
233 * when the pool used to create the thread is destroyed.
234 *
235 * @param thread The thread handle.
236 *
237 * @return zero on success.
238 */
239PJ_DECL(pj_status_t) pj_thread_destroy(pj_thread_t *thread);
240
241
242/**
243 * Put the current thread to sleep for the specified miliseconds.
244 *
245 * @param msec Miliseconds delay.
246 *
247 * @return zero if successfull.
248 */
249PJ_DECL(pj_status_t) pj_thread_sleep(unsigned msec);
250
251/**
252 * @def PJ_CHECK_STACK()
253 * PJ_CHECK_STACK() macro is used to check the sanity of the stack.
254 * The OS implementation may check that no stack overflow occurs, and
255 * it also may collect statistic about stack usage.
256 */
257#if defined(PJ_OS_HAS_CHECK_STACK) && PJ_OS_HAS_CHECK_STACK!=0
258
259# define PJ_CHECK_STACK() pj_thread_check_stack(__FILE__, __LINE__)
260
261/** @internal
262 * The implementation of stack checking.
263 */
264PJ_DECL(void) pj_thread_check_stack(const char *file, int line);
265
266/** @internal
267 * Get maximum stack usage statistic.
268 */
269PJ_DECL(pj_uint32_t) pj_thread_get_stack_max_usage(pj_thread_t *thread);
270
271/** @internal
272 * Dump thread stack status.
273 */
274PJ_DECL(pj_status_t) pj_thread_get_stack_info(pj_thread_t *thread,
275 const char **file,
276 int *line);
277#else
278
279# define PJ_CHECK_STACK()
280/** pj_thread_get_stack_max_usage() for the thread */
281# define pj_thread_get_stack_max_usage(thread) 0
282/** pj_thread_get_stack_info() for the thread */
283# define pj_thread_get_stack_info(thread,f,l) (*(f)="",*(l)=0)
284#endif /* PJ_OS_HAS_CHECK_STACK */
285
286/**
287 * @}
288 */
289
Benny Prijono92ac4472006-07-22 13:42:56 +0000290/* **************************************************************************/
Benny Prijono9033e312005-11-21 02:08:39 +0000291/**
Benny Prijono8ab968f2007-07-20 08:08:30 +0000292 * @defgroup PJ_SYMBIAN_OS Symbian OS Specific
293 * @ingroup PJ_OS
294 * @{
295 * Functionalities specific to Symbian OS.
296 *
297 * Symbian OS strongly discourages the use of polling since this wastes
298 * CPU power, and instead provides Active Object and Active Scheduler
299 * pattern to allow application (in this case, PJLIB) to register asynchronous
300 * tasks. PJLIB port for Symbian complies to this recommended behavior.
301 * As the result, few things have been changed in PJLIB for Symbian:
302 * - the timer heap (see @ref PJ_TIMER) is implemented with active
303 * object framework, and each timer entry registered to the timer
304 * heap will register an Active Object to the Active Scheduler.
305 * Because of this, polling the timer heap with pj_timer_heap_poll()
306 * is no longer necessary, and this function will just evaluate
307 * to nothing.
308 * - the ioqueue (see @ref PJ_IOQUEUE) is also implemented with
309 * active object framework, with each asynchronous operation will
310 * register an Active Object to the Active Scheduler. Because of
311 * this, polling the ioqueue with pj_ioqueue_poll() is no longer
312 * necessary, and this function will just evaluate to nothing.
313 *
314 * Since timer heap and ioqueue polling are no longer necessary, Symbian
315 * application can now poll for all events by calling
316 * \a User::WaitForAnyRequest() and \a CActiveScheduler::RunIfReady().
317 * PJLIB provides a thin wrapper which calls these two functions,
318 * called pj_symbianos_poll().
319 */
320
321/**
322 * Wait the completion of any Symbian active objects. When the timeout
323 * value is not specified (the \a ms_timeout argument is -1), this
324 * function is a thin wrapper which calls \a User::WaitForAnyRequest()
325 * and \a CActiveScheduler::RunIfReady(). If the timeout value is
326 * specified, this function will schedule a timer entry to the timer
327 * heap (which is an Active Object), to limit the wait time for event
328 * occurences. Scheduling a timer entry is an expensive operation,
329 * therefore application should only specify a timeout value when it's
330 * really necessary (for example, when it's not sure there are other
331 * Active Objects currently running in the application).
332 *
333 * @param priority The minimum priority of the Active Objects to
334 * poll, which values are from CActive::TPriority
335 * constants. If -1 is given, CActive::EPriorityStandard.
336 * priority will be used.
337 * @param ms_timeout Optional timeout to wait. Application should
338 * specify -1 to let the function wait indefinitely
339 * for any events.
340 *
341 * @return PJ_TRUE if there have been any events executed
342 * during the polling. This function will only return
343 * PJ_FALSE if \a ms_timeout argument is specified
344 * (i.e. the value is not -1) and there was no event
345 * executed when the timeout timer elapsed.
346 */
347PJ_DECL(pj_bool_t) pj_symbianos_poll(int priority, int ms_timeout);
348
Benny Prijono7d3e12c2007-10-26 05:25:35 +0000349
350/**
351 * This structure declares Symbian OS specific parameters that can be
352 * specified when calling #pj_symbianos_set_params().
353 */
354typedef struct pj_symbianos_params
355{
356 /**
357 * Optional RSocketServ instance to be used by PJLIB. If this
358 * value is NULL, PJLIB will create a new RSocketServ instance
359 * when pj_init() is called.
360 */
361 void *rsocketserv;
362
363 /**
364 * Optional RConnection instance to be used by PJLIB when creating
365 * sockets. If this value is NULL, no RConnection will be
366 * specified when creating sockets.
367 */
368 void *rconnection;
369
370 /**
371 * Optional RHostResolver instance to be used by PJLIB. If this value
372 * is NULL, a new RHostResolver instance will be created when
373 * pj_init() is called.
374 */
375 void *rhostresolver;
376
Benny Prijono62b86eb2007-12-01 08:52:57 +0000377 /**
378 * Optional RHostResolver for IPv6 instance to be used by PJLIB.
379 * If this value is NULL, a new RHostResolver instance will be created
380 * when pj_init() is called.
381 */
382 void *rhostresolver6;
383
Benny Prijono7d3e12c2007-10-26 05:25:35 +0000384} pj_symbianos_params;
385
386/**
387 * Specify Symbian OS parameters to be used by PJLIB. This function MUST
388 * be called before #pj_init() is called.
389 *
390 * @param prm Symbian specific parameters.
391 *
392 * @return PJ_SUCCESS if the parameters can be applied
393 * successfully.
394 */
395PJ_DECL(pj_status_t) pj_symbianos_set_params(pj_symbianos_params *prm);
396
Nanang Izzuddin90b83202009-03-02 15:48:45 +0000397/**
398 * Notify PJLIB that the access point connection has been down or unusable
399 * and PJLIB should not try to access the Symbian socket API (especially ones
400 * that send packets). Sending packet when RConnection is reconnected to
401 * different access point may cause the WaitForRequest() for the function to
402 * block indefinitely.
403 *
404 * @param up If set to PJ_FALSE it will cause PJLIB to not try
405 * to access socket API, and error will be returned
406 * immediately instead.
407 */
408PJ_DECL(void) pj_symbianos_set_connection_status(pj_bool_t up);
Benny Prijono7d3e12c2007-10-26 05:25:35 +0000409
Benny Prijono8ab968f2007-07-20 08:08:30 +0000410/**
411 * @}
412 */
413
414/* **************************************************************************/
415/**
Benny Prijono9033e312005-11-21 02:08:39 +0000416 * @defgroup PJ_TLS Thread Local Storage.
417 * @ingroup PJ_OS
418 * @{
419 */
420
421/**
422 * Allocate thread local storage index. The initial value of the variable at
423 * the index is zero.
424 *
425 * @param index Pointer to hold the return value.
426 * @return PJ_SUCCESS on success, or the error code.
427 */
428PJ_DECL(pj_status_t) pj_thread_local_alloc(long *index);
429
430/**
431 * Deallocate thread local variable.
432 *
433 * @param index The variable index.
434 */
435PJ_DECL(void) pj_thread_local_free(long index);
436
437/**
438 * Set the value of thread local variable.
439 *
440 * @param index The index of the variable.
441 * @param value The value.
442 */
443PJ_DECL(pj_status_t) pj_thread_local_set(long index, void *value);
444
445/**
446 * Get the value of thread local variable.
447 *
448 * @param index The index of the variable.
449 * @return The value.
450 */
451PJ_DECL(void*) pj_thread_local_get(long index);
452
453
454/**
455 * @}
456 */
457
458
Benny Prijono92ac4472006-07-22 13:42:56 +0000459/* **************************************************************************/
Benny Prijono9033e312005-11-21 02:08:39 +0000460/**
461 * @defgroup PJ_ATOMIC Atomic Variables
462 * @ingroup PJ_OS
463 * @{
464 *
465 * This module provides API to manipulate atomic variables.
466 *
467 * \section pj_atomic_examples_sec Examples
468 *
469 * For some example codes, please see:
470 * - @ref page_pjlib_atomic_test
471 */
472
473
474/**
475 * Create atomic variable.
476 *
477 * @param pool The pool.
478 * @param initial The initial value of the atomic variable.
479 * @param atomic Pointer to hold the atomic variable upon return.
480 *
481 * @return PJ_SUCCESS on success, or the error code.
482 */
483PJ_DECL(pj_status_t) pj_atomic_create( pj_pool_t *pool,
484 pj_atomic_value_t initial,
485 pj_atomic_t **atomic );
486
487/**
488 * Destroy atomic variable.
489 *
490 * @param atomic_var the atomic variable.
491 *
492 * @return PJ_SUCCESS if success.
493 */
494PJ_DECL(pj_status_t) pj_atomic_destroy( pj_atomic_t *atomic_var );
495
496/**
497 * Set the value of an atomic type, and return the previous value.
498 *
499 * @param atomic_var the atomic variable.
500 * @param value value to be set to the variable.
501 */
502PJ_DECL(void) pj_atomic_set( pj_atomic_t *atomic_var,
503 pj_atomic_value_t value);
504
505/**
506 * Get the value of an atomic type.
507 *
508 * @param atomic_var the atomic variable.
509 *
510 * @return the value of the atomic variable.
511 */
512PJ_DECL(pj_atomic_value_t) pj_atomic_get(pj_atomic_t *atomic_var);
513
514/**
515 * Increment the value of an atomic type.
516 *
517 * @param atomic_var the atomic variable.
518 */
519PJ_DECL(void) pj_atomic_inc(pj_atomic_t *atomic_var);
520
521/**
522 * Increment the value of an atomic type and get the result.
523 *
524 * @param atomic_var the atomic variable.
525 *
526 * @return The incremented value.
527 */
528PJ_DECL(pj_atomic_value_t) pj_atomic_inc_and_get(pj_atomic_t *atomic_var);
529
530/**
531 * Decrement the value of an atomic type.
532 *
533 * @param atomic_var the atomic variable.
534 */
535PJ_DECL(void) pj_atomic_dec(pj_atomic_t *atomic_var);
536
537/**
538 * Decrement the value of an atomic type and get the result.
539 *
540 * @param atomic_var the atomic variable.
541 *
542 * @return The decremented value.
543 */
544PJ_DECL(pj_atomic_value_t) pj_atomic_dec_and_get(pj_atomic_t *atomic_var);
545
546/**
547 * Add a value to an atomic type.
548 *
549 * @param atomic_var The atomic variable.
550 * @param value Value to be added.
551 */
552PJ_DECL(void) pj_atomic_add( pj_atomic_t *atomic_var,
553 pj_atomic_value_t value);
554
555/**
556 * Add a value to an atomic type and get the result.
557 *
558 * @param atomic_var The atomic variable.
559 * @param value Value to be added.
560 *
561 * @return The result after the addition.
562 */
563PJ_DECL(pj_atomic_value_t) pj_atomic_add_and_get( pj_atomic_t *atomic_var,
564 pj_atomic_value_t value);
565
566/**
567 * @}
568 */
569
Benny Prijono92ac4472006-07-22 13:42:56 +0000570/* **************************************************************************/
Benny Prijono9033e312005-11-21 02:08:39 +0000571/**
572 * @defgroup PJ_MUTEX Mutexes.
573 * @ingroup PJ_OS
574 * @{
575 *
576 * Mutex manipulation. Alternatively, application can use higher abstraction
577 * for lock objects, which provides uniform API for all kinds of lock
578 * mechanisms, including mutex. See @ref PJ_LOCK for more information.
579 */
580
581/**
582 * Mutex types:
583 * - PJ_MUTEX_DEFAULT: default mutex type, which is system dependent.
584 * - PJ_MUTEX_SIMPLE: non-recursive mutex.
Benny Prijono8ab968f2007-07-20 08:08:30 +0000585 * - PJ_MUTEX_RECURSE: recursive mutex.
Benny Prijono9033e312005-11-21 02:08:39 +0000586 */
587typedef enum pj_mutex_type_e
588{
589 PJ_MUTEX_DEFAULT,
590 PJ_MUTEX_SIMPLE,
Benny Prijono92ac4472006-07-22 13:42:56 +0000591 PJ_MUTEX_RECURSE
Benny Prijono9033e312005-11-21 02:08:39 +0000592} pj_mutex_type_e;
593
594
595/**
596 * Create mutex of the specified type.
597 *
598 * @param pool The pool.
599 * @param name Name to be associated with the mutex (for debugging).
600 * @param type The type of the mutex, of type #pj_mutex_type_e.
601 * @param mutex Pointer to hold the returned mutex instance.
602 *
603 * @return PJ_SUCCESS on success, or the error code.
604 */
605PJ_DECL(pj_status_t) pj_mutex_create(pj_pool_t *pool,
606 const char *name,
607 int type,
608 pj_mutex_t **mutex);
609
610/**
611 * Create simple, non-recursive mutex.
612 * This function is a simple wrapper for #pj_mutex_create to create
613 * non-recursive mutex.
614 *
615 * @param pool The pool.
616 * @param name Mutex name.
617 * @param mutex Pointer to hold the returned mutex instance.
618 *
619 * @return PJ_SUCCESS on success, or the error code.
620 */
621PJ_DECL(pj_status_t) pj_mutex_create_simple( pj_pool_t *pool, const char *name,
622 pj_mutex_t **mutex );
623
624/**
625 * Create recursive mutex.
626 * This function is a simple wrapper for #pj_mutex_create to create
627 * recursive mutex.
628 *
629 * @param pool The pool.
630 * @param name Mutex name.
631 * @param mutex Pointer to hold the returned mutex instance.
632 *
633 * @return PJ_SUCCESS on success, or the error code.
634 */
635PJ_DECL(pj_status_t) pj_mutex_create_recursive( pj_pool_t *pool,
636 const char *name,
637 pj_mutex_t **mutex );
638
639/**
640 * Acquire mutex lock.
641 *
642 * @param mutex The mutex.
643 * @return PJ_SUCCESS on success, or the error code.
644 */
645PJ_DECL(pj_status_t) pj_mutex_lock(pj_mutex_t *mutex);
646
647/**
648 * Release mutex lock.
649 *
650 * @param mutex The mutex.
651 * @return PJ_SUCCESS on success, or the error code.
652 */
653PJ_DECL(pj_status_t) pj_mutex_unlock(pj_mutex_t *mutex);
654
655/**
656 * Try to acquire mutex lock.
657 *
658 * @param mutex The mutex.
659 * @return PJ_SUCCESS on success, or the error code if the
660 * lock couldn't be acquired.
661 */
662PJ_DECL(pj_status_t) pj_mutex_trylock(pj_mutex_t *mutex);
663
664/**
665 * Destroy mutex.
666 *
667 * @param mutex Te mutex.
668 * @return PJ_SUCCESS on success, or the error code.
669 */
670PJ_DECL(pj_status_t) pj_mutex_destroy(pj_mutex_t *mutex);
671
672/**
673 * Determine whether calling thread is owning the mutex (only available when
674 * PJ_DEBUG is set).
675 * @param mutex The mutex.
676 * @return Non-zero if yes.
677 */
678#if defined(PJ_DEBUG) && PJ_DEBUG != 0
679 PJ_DECL(pj_bool_t) pj_mutex_is_locked(pj_mutex_t *mutex);
680#else
681# define pj_mutex_is_locked(mutex) 1
682#endif
683
684/**
685 * @}
686 */
687
Benny Prijono92ac4472006-07-22 13:42:56 +0000688/* **************************************************************************/
Benny Prijono9033e312005-11-21 02:08:39 +0000689/**
Benny Prijono0ca04b62005-12-30 23:50:15 +0000690 * @defgroup PJ_RW_MUTEX Reader/Writer Mutex
691 * @ingroup PJ_OS
692 * @{
693 * Reader/writer mutex is a classic synchronization object where multiple
694 * readers can acquire the mutex, but only a single writer can acquire the
695 * mutex.
696 */
Benny Prijono294c2532006-06-16 16:52:51 +0000697
698/**
699 * Opaque declaration for reader/writer mutex.
700 * Reader/writer mutex is a classic synchronization object where multiple
701 * readers can acquire the mutex, but only a single writer can acquire the
702 * mutex.
703 */
Benny Prijono0ca04b62005-12-30 23:50:15 +0000704typedef struct pj_rwmutex_t pj_rwmutex_t;
705
706/**
707 * Create reader/writer mutex.
708 *
709 * @param pool Pool to allocate memory for the mutex.
710 * @param name Name to be assigned to the mutex.
711 * @param mutex Pointer to receive the newly created mutex.
712 *
713 * @return PJ_SUCCESS on success, or the error code.
714 */
715PJ_DECL(pj_status_t) pj_rwmutex_create(pj_pool_t *pool, const char *name,
716 pj_rwmutex_t **mutex);
717
718/**
719 * Lock the mutex for reading.
720 *
721 * @param mutex The mutex.
722 * @return PJ_SUCCESS on success, or the error code.
723 */
724PJ_DECL(pj_status_t) pj_rwmutex_lock_read(pj_rwmutex_t *mutex);
725
726/**
727 * Lock the mutex for writing.
728 *
729 * @param mutex The mutex.
730 * @return PJ_SUCCESS on success, or the error code.
731 */
732PJ_DECL(pj_status_t) pj_rwmutex_lock_write(pj_rwmutex_t *mutex);
733
734/**
735 * Release read lock.
736 *
737 * @param mutex The mutex.
738 * @return PJ_SUCCESS on success, or the error code.
739 */
740PJ_DECL(pj_status_t) pj_rwmutex_unlock_read(pj_rwmutex_t *mutex);
741
742/**
743 * Release write lock.
744 *
745 * @param mutex The mutex.
746 * @return PJ_SUCCESS on success, or the error code.
747 */
748PJ_DECL(pj_status_t) pj_rwmutex_unlock_write(pj_rwmutex_t *mutex);
749
750/**
751 * Destroy reader/writer mutex.
752 *
753 * @param mutex The mutex.
754 * @return PJ_SUCCESS on success, or the error code.
755 */
756PJ_DECL(pj_status_t) pj_rwmutex_destroy(pj_rwmutex_t *mutex);
757
758
759/**
760 * @}
761 */
762
763
Benny Prijono92ac4472006-07-22 13:42:56 +0000764/* **************************************************************************/
Benny Prijono0ca04b62005-12-30 23:50:15 +0000765/**
Benny Prijono9033e312005-11-21 02:08:39 +0000766 * @defgroup PJ_CRIT_SEC Critical sections.
767 * @ingroup PJ_OS
768 * @{
769 * Critical section protection can be used to protect regions where:
770 * - mutual exclusion protection is needed.
771 * - it's rather too expensive to create a mutex.
772 * - the time spent in the region is very very brief.
773 *
774 * Critical section is a global object, and it prevents any threads from
775 * entering any regions that are protected by critical section once a thread
776 * is already in the section.
777 *
778 * Critial section is \a not recursive!
779 *
780 * Application <b>MUST NOT</b> call any functions that may cause current
781 * thread to block (such as allocating memory, performing I/O, locking mutex,
782 * etc.) while holding the critical section.
783 */
784/**
785 * Enter critical section.
786 */
787PJ_DECL(void) pj_enter_critical_section(void);
788
789/**
790 * Leave critical section.
791 */
792PJ_DECL(void) pj_leave_critical_section(void);
793
794/**
795 * @}
796 */
797
Benny Prijono92ac4472006-07-22 13:42:56 +0000798/* **************************************************************************/
Benny Prijono9033e312005-11-21 02:08:39 +0000799#if defined(PJ_HAS_SEMAPHORE) && PJ_HAS_SEMAPHORE != 0
800/**
801 * @defgroup PJ_SEM Semaphores.
802 * @ingroup PJ_OS
803 * @{
804 *
805 * This module provides abstraction for semaphores, where available.
806 */
807
808/**
809 * Create semaphore.
810 *
811 * @param pool The pool.
812 * @param name Name to be assigned to the semaphore (for logging purpose)
813 * @param initial The initial count of the semaphore.
814 * @param max The maximum count of the semaphore.
815 * @param sem Pointer to hold the semaphore created.
816 *
817 * @return PJ_SUCCESS on success, or the error code.
818 */
819PJ_DECL(pj_status_t) pj_sem_create( pj_pool_t *pool,
820 const char *name,
821 unsigned initial,
822 unsigned max,
823 pj_sem_t **sem);
824
825/**
826 * Wait for semaphore.
827 *
828 * @param sem The semaphore.
829 *
830 * @return PJ_SUCCESS on success, or the error code.
831 */
832PJ_DECL(pj_status_t) pj_sem_wait(pj_sem_t *sem);
833
834/**
835 * Try wait for semaphore.
836 *
837 * @param sem The semaphore.
838 *
839 * @return PJ_SUCCESS on success, or the error code.
840 */
841PJ_DECL(pj_status_t) pj_sem_trywait(pj_sem_t *sem);
842
843/**
844 * Release semaphore.
845 *
846 * @param sem The semaphore.
847 *
848 * @return PJ_SUCCESS on success, or the error code.
849 */
850PJ_DECL(pj_status_t) pj_sem_post(pj_sem_t *sem);
851
852/**
853 * Destroy semaphore.
854 *
855 * @param sem The semaphore.
856 *
857 * @return PJ_SUCCESS on success, or the error code.
858 */
859PJ_DECL(pj_status_t) pj_sem_destroy(pj_sem_t *sem);
860
861/**
862 * @}
863 */
864#endif /* PJ_HAS_SEMAPHORE */
865
866
Benny Prijono92ac4472006-07-22 13:42:56 +0000867/* **************************************************************************/
Benny Prijono9033e312005-11-21 02:08:39 +0000868#if defined(PJ_HAS_EVENT_OBJ) && PJ_HAS_EVENT_OBJ != 0
869/**
870 * @defgroup PJ_EVENT Event Object.
871 * @ingroup PJ_OS
872 * @{
873 *
874 * This module provides abstraction to event object (e.g. Win32 Event) where
875 * available. Event objects can be used for synchronization among threads.
876 */
877
878/**
879 * Create event object.
880 *
881 * @param pool The pool.
882 * @param name The name of the event object (for logging purpose).
883 * @param manual_reset Specify whether the event is manual-reset
884 * @param initial Specify the initial state of the event object.
885 * @param event Pointer to hold the returned event object.
886 *
887 * @return event handle, or NULL if failed.
888 */
889PJ_DECL(pj_status_t) pj_event_create(pj_pool_t *pool, const char *name,
890 pj_bool_t manual_reset, pj_bool_t initial,
891 pj_event_t **event);
892
893/**
894 * Wait for event to be signaled.
895 *
896 * @param event The event object.
897 *
898 * @return zero if successfull.
899 */
900PJ_DECL(pj_status_t) pj_event_wait(pj_event_t *event);
901
902/**
903 * Try wait for event object to be signalled.
904 *
905 * @param event The event object.
906 *
907 * @return zero if successfull.
908 */
909PJ_DECL(pj_status_t) pj_event_trywait(pj_event_t *event);
910
911/**
912 * Set the event object state to signaled. For auto-reset event, this
913 * will only release the first thread that are waiting on the event. For
914 * manual reset event, the state remains signaled until the event is reset.
915 * If there is no thread waiting on the event, the event object state
916 * remains signaled.
917 *
918 * @param event The event object.
919 *
920 * @return zero if successfull.
921 */
922PJ_DECL(pj_status_t) pj_event_set(pj_event_t *event);
923
924/**
925 * Set the event object to signaled state to release appropriate number of
926 * waiting threads and then reset the event object to non-signaled. For
927 * manual-reset event, this function will release all waiting threads. For
928 * auto-reset event, this function will only release one waiting thread.
929 *
930 * @param event The event object.
931 *
932 * @return zero if successfull.
933 */
934PJ_DECL(pj_status_t) pj_event_pulse(pj_event_t *event);
935
936/**
937 * Set the event object state to non-signaled.
938 *
939 * @param event The event object.
940 *
941 * @return zero if successfull.
942 */
943PJ_DECL(pj_status_t) pj_event_reset(pj_event_t *event);
944
945/**
946 * Destroy the event object.
947 *
948 * @param event The event object.
949 *
950 * @return zero if successfull.
951 */
952PJ_DECL(pj_status_t) pj_event_destroy(pj_event_t *event);
953
954/**
955 * @}
956 */
957#endif /* PJ_HAS_EVENT_OBJ */
958
Benny Prijono92ac4472006-07-22 13:42:56 +0000959/* **************************************************************************/
Benny Prijono9033e312005-11-21 02:08:39 +0000960/**
961 * @addtogroup PJ_TIME Time Data Type and Manipulation.
962 * @ingroup PJ_OS
963 * @{
964 * This module provides API for manipulating time.
965 *
966 * \section pj_time_examples_sec Examples
967 *
968 * For examples, please see:
969 * - \ref page_pjlib_sleep_test
970 */
971
972/**
973 * Get current time of day in local representation.
974 *
975 * @param tv Variable to store the result.
976 *
977 * @return zero if successfull.
978 */
979PJ_DECL(pj_status_t) pj_gettimeofday(pj_time_val *tv);
980
981
982/**
983 * Parse time value into date/time representation.
984 *
985 * @param tv The time.
986 * @param pt Variable to store the date time result.
987 *
988 * @return zero if successfull.
989 */
990PJ_DECL(pj_status_t) pj_time_decode(const pj_time_val *tv, pj_parsed_time *pt);
991
992/**
993 * Encode date/time to time value.
994 *
995 * @param pt The date/time.
996 * @param tv Variable to store time value result.
997 *
998 * @return zero if successfull.
999 */
1000PJ_DECL(pj_status_t) pj_time_encode(const pj_parsed_time *pt, pj_time_val *tv);
1001
1002/**
1003 * Convert local time to GMT.
1004 *
1005 * @param tv Time to convert.
1006 *
1007 * @return zero if successfull.
1008 */
1009PJ_DECL(pj_status_t) pj_time_local_to_gmt(pj_time_val *tv);
1010
1011/**
1012 * Convert GMT to local time.
1013 *
1014 * @param tv Time to convert.
1015 *
1016 * @return zero if successfull.
1017 */
1018PJ_DECL(pj_status_t) pj_time_gmt_to_local(pj_time_val *tv);
1019
1020/**
1021 * @}
1022 */
1023
Benny Prijono92ac4472006-07-22 13:42:56 +00001024/* **************************************************************************/
Benny Prijono9033e312005-11-21 02:08:39 +00001025#if defined(PJ_TERM_HAS_COLOR) && PJ_TERM_HAS_COLOR != 0
1026
1027/**
1028 * @defgroup PJ_TERM Terminal
1029 * @ingroup PJ_OS
1030 * @{
1031 */
1032
1033/**
1034 * Set current terminal color.
1035 *
1036 * @param color The RGB color.
1037 *
1038 * @return zero on success.
1039 */
1040PJ_DECL(pj_status_t) pj_term_set_color(pj_color_t color);
1041
1042/**
1043 * Get current terminal foreground color.
1044 *
1045 * @return RGB color.
1046 */
1047PJ_DECL(pj_color_t) pj_term_get_color(void);
1048
1049/**
1050 * @}
1051 */
1052
1053#endif /* PJ_TERM_HAS_COLOR */
1054
Benny Prijono92ac4472006-07-22 13:42:56 +00001055/* **************************************************************************/
Benny Prijono9033e312005-11-21 02:08:39 +00001056/**
1057 * @defgroup PJ_TIMESTAMP High Resolution Timestamp
1058 * @ingroup PJ_OS
1059 * @{
1060 *
1061 * PJLIB provides <b>High Resolution Timestamp</b> API to access highest
1062 * resolution timestamp value provided by the platform. The API is usefull
1063 * to measure precise elapsed time, and can be used in applications such
1064 * as profiling.
1065 *
1066 * The timestamp value is represented in cycles, and can be related to
1067 * normal time (in seconds or sub-seconds) using various functions provided.
1068 *
1069 * \section pj_timestamp_examples_sec Examples
1070 *
1071 * For examples, please see:
1072 * - \ref page_pjlib_sleep_test
1073 * - \ref page_pjlib_timestamp_test
1074 */
1075
1076/*
1077 * High resolution timer.
1078 */
1079#if defined(PJ_HAS_HIGH_RES_TIMER) && PJ_HAS_HIGH_RES_TIMER != 0
1080
1081/**
Benny Prijono9033e312005-11-21 02:08:39 +00001082 * Acquire high resolution timer value. The time value are stored
1083 * in cycles.
1084 *
1085 * @param ts High resolution timer value.
1086 * @return PJ_SUCCESS or the appropriate error code.
1087 *
1088 * @see pj_get_timestamp_freq().
1089 */
1090PJ_DECL(pj_status_t) pj_get_timestamp(pj_timestamp *ts);
1091
1092/**
1093 * Get high resolution timer frequency, in cycles per second.
1094 *
1095 * @param freq Timer frequency, in cycles per second.
1096 * @return PJ_SUCCESS or the appropriate error code.
1097 */
1098PJ_DECL(pj_status_t) pj_get_timestamp_freq(pj_timestamp *freq);
1099
1100/**
Benny Prijonoc357d642007-01-20 05:14:24 +00001101 * Set timestamp from 32bit values.
1102 * @param t The timestamp to be set.
1103 * @param hi The high 32bit part.
1104 * @param lo The low 32bit part.
1105 */
1106PJ_INLINE(void) pj_set_timestamp32(pj_timestamp *t, pj_uint32_t hi,
1107 pj_uint32_t lo)
1108{
1109 t->u32.hi = hi;
1110 t->u32.lo = lo;
1111}
1112
Benny Prijono6f86e7c2007-04-02 11:28:41 +00001113
1114/**
1115 * Compare timestamp t1 and t2.
1116 * @param t1 t1.
1117 * @param t2 t2.
1118 * @return -1 if (t1 < t2), 1 if (t1 > t2), or 0 if (t1 == t2)
1119 */
1120PJ_INLINE(int) pj_cmp_timestamp(const pj_timestamp *t1, const pj_timestamp *t2)
1121{
1122#if PJ_HAS_INT64
1123 if (t1->u64 < t2->u64)
1124 return -1;
1125 else if (t1->u64 > t2->u64)
1126 return 1;
1127 else
1128 return 0;
1129#else
1130 if (t1->u32.hi < t2->u32.hi ||
1131 (t1->u32.hi == t2->u32.hi && t1->u32.lo < t2->u32.lo))
1132 return -1;
1133 else if (t1->u32.hi > t2->u32.hi ||
1134 (t1->u32.hi == t2->u32.hi && t1->u32.lo > t2->u32.lo))
1135 return 1;
1136 else
1137 return 0;
1138#endif
1139}
1140
1141
Benny Prijonoc357d642007-01-20 05:14:24 +00001142/**
Benny Prijono9033e312005-11-21 02:08:39 +00001143 * Add timestamp t2 to t1.
1144 * @param t1 t1.
1145 * @param t2 t2.
1146 */
1147PJ_INLINE(void) pj_add_timestamp(pj_timestamp *t1, const pj_timestamp *t2)
1148{
1149#if PJ_HAS_INT64
1150 t1->u64 += t2->u64;
1151#else
1152 pj_uint32_t old = t1->u32.lo;
1153 t1->u32.hi += t2->u32.hi;
1154 t1->u32.lo += t2->u32.lo;
1155 if (t1->u32.lo < old)
1156 ++t1->u32.hi;
1157#endif
1158}
1159
1160/**
Benny Prijonoc357d642007-01-20 05:14:24 +00001161 * Add timestamp t2 to t1.
1162 * @param t1 t1.
1163 * @param t2 t2.
1164 */
1165PJ_INLINE(void) pj_add_timestamp32(pj_timestamp *t1, pj_uint32_t t2)
1166{
1167#if PJ_HAS_INT64
1168 t1->u64 += t2;
1169#else
1170 pj_uint32_t old = t1->u32.lo;
1171 t1->u32.lo += t2;
1172 if (t1->u32.lo < old)
1173 ++t1->u32.hi;
1174#endif
1175}
1176
1177/**
Benny Prijono9033e312005-11-21 02:08:39 +00001178 * Substract timestamp t2 from t1.
1179 * @param t1 t1.
1180 * @param t2 t2.
1181 */
1182PJ_INLINE(void) pj_sub_timestamp(pj_timestamp *t1, const pj_timestamp *t2)
1183{
1184#if PJ_HAS_INT64
1185 t1->u64 -= t2->u64;
1186#else
1187 t1->u32.hi -= t2->u32.hi;
1188 if (t1->u32.lo >= t2->u32.lo)
1189 t1->u32.lo -= t2->u32.lo;
1190 else {
1191 t1->u32.lo -= t2->u32.lo;
1192 --t1->u32.hi;
1193 }
1194#endif
1195}
1196
1197/**
Benny Prijonoc357d642007-01-20 05:14:24 +00001198 * Substract timestamp t2 from t1.
1199 * @param t1 t1.
1200 * @param t2 t2.
1201 */
1202PJ_INLINE(void) pj_sub_timestamp32(pj_timestamp *t1, pj_uint32_t t2)
1203{
1204#if PJ_HAS_INT64
1205 t1->u64 -= t2;
1206#else
1207 if (t1->u32.lo >= t2)
1208 t1->u32.lo -= t2;
1209 else {
1210 t1->u32.lo -= t2;
1211 --t1->u32.hi;
1212 }
1213#endif
1214}
1215
1216/**
1217 * Get the timestamp difference between t2 and t1 (that is t2 minus t1),
1218 * and return a 32bit signed integer difference.
1219 */
1220PJ_INLINE(pj_int32_t) pj_timestamp_diff32(const pj_timestamp *t1,
1221 const pj_timestamp *t2)
1222{
1223 /* Be careful with the signess (I think!) */
1224#if PJ_HAS_INT64
1225 pj_int64_t diff = t2->u64 - t1->u64;
1226 return (pj_int32_t) diff;
1227#else
1228 pj_int32 diff = t2->u32.lo - t1->u32.lo;
1229 return diff;
1230#endif
1231}
1232
1233
1234/**
Benny Prijono9033e312005-11-21 02:08:39 +00001235 * Calculate the elapsed time, and store it in pj_time_val.
1236 * This function calculates the elapsed time using highest precision
1237 * calculation that is available for current platform, considering
1238 * whether floating point or 64-bit precision arithmetic is available.
1239 * For maximum portability, application should prefer to use this function
1240 * rather than calculating the elapsed time by itself.
1241 *
1242 * @param start The starting timestamp.
1243 * @param stop The end timestamp.
1244 *
1245 * @return Elapsed time as #pj_time_val.
1246 *
1247 * @see pj_elapsed_usec(), pj_elapsed_cycle(), pj_elapsed_nanosec()
1248 */
1249PJ_DECL(pj_time_val) pj_elapsed_time( const pj_timestamp *start,
1250 const pj_timestamp *stop );
1251
1252/**
Benny Prijono99683ae2005-11-21 16:59:47 +00001253 * Calculate the elapsed time as 32-bit miliseconds.
1254 * This function calculates the elapsed time using highest precision
1255 * calculation that is available for current platform, considering
1256 * whether floating point or 64-bit precision arithmetic is available.
1257 * For maximum portability, application should prefer to use this function
1258 * rather than calculating the elapsed time by itself.
1259 *
1260 * @param start The starting timestamp.
1261 * @param stop The end timestamp.
1262 *
1263 * @return Elapsed time in milisecond.
1264 *
1265 * @see pj_elapsed_time(), pj_elapsed_cycle(), pj_elapsed_nanosec()
1266 */
1267PJ_DECL(pj_uint32_t) pj_elapsed_msec( const pj_timestamp *start,
1268 const pj_timestamp *stop );
1269
1270/**
Benny Prijonof1a47b82009-03-30 18:22:16 +00001271 * Variant of #pj_elapsed_msec() which returns 64bit value.
1272 */
1273PJ_DECL(pj_uint64_t) pj_elapsed_msec64(const pj_timestamp *start,
1274 const pj_timestamp *stop );
1275
1276/**
Benny Prijono9033e312005-11-21 02:08:39 +00001277 * Calculate the elapsed time in 32-bit microseconds.
1278 * This function calculates the elapsed time using highest precision
1279 * calculation that is available for current platform, considering
1280 * whether floating point or 64-bit precision arithmetic is available.
1281 * For maximum portability, application should prefer to use this function
1282 * rather than calculating the elapsed time by itself.
1283 *
1284 * @param start The starting timestamp.
1285 * @param stop The end timestamp.
1286 *
1287 * @return Elapsed time in microsecond.
1288 *
1289 * @see pj_elapsed_time(), pj_elapsed_cycle(), pj_elapsed_nanosec()
1290 */
1291PJ_DECL(pj_uint32_t) pj_elapsed_usec( const pj_timestamp *start,
1292 const pj_timestamp *stop );
1293
1294/**
1295 * Calculate the elapsed time in 32-bit nanoseconds.
1296 * This function calculates the elapsed time using highest precision
1297 * calculation that is available for current platform, considering
1298 * whether floating point or 64-bit precision arithmetic is available.
1299 * For maximum portability, application should prefer to use this function
1300 * rather than calculating the elapsed time by itself.
1301 *
1302 * @param start The starting timestamp.
1303 * @param stop The end timestamp.
1304 *
1305 * @return Elapsed time in nanoseconds.
1306 *
1307 * @see pj_elapsed_time(), pj_elapsed_cycle(), pj_elapsed_usec()
1308 */
1309PJ_DECL(pj_uint32_t) pj_elapsed_nanosec( const pj_timestamp *start,
1310 const pj_timestamp *stop );
1311
1312/**
1313 * Calculate the elapsed time in 32-bit cycles.
1314 * This function calculates the elapsed time using highest precision
1315 * calculation that is available for current platform, considering
1316 * whether floating point or 64-bit precision arithmetic is available.
1317 * For maximum portability, application should prefer to use this function
1318 * rather than calculating the elapsed time by itself.
1319 *
1320 * @param start The starting timestamp.
1321 * @param stop The end timestamp.
1322 *
1323 * @return Elapsed time in cycles.
1324 *
1325 * @see pj_elapsed_usec(), pj_elapsed_time(), pj_elapsed_nanosec()
1326 */
1327PJ_DECL(pj_uint32_t) pj_elapsed_cycle( const pj_timestamp *start,
1328 const pj_timestamp *stop );
1329
1330
1331#endif /* PJ_HAS_HIGH_RES_TIMER */
1332
1333/** @} */
1334
1335
Benny Prijono92ac4472006-07-22 13:42:56 +00001336/* **************************************************************************/
Benny Prijono9033e312005-11-21 02:08:39 +00001337/**
1338 * Internal PJLIB function to initialize the threading subsystem.
1339 * @return PJ_SUCCESS or the appropriate error code.
1340 */
1341pj_status_t pj_thread_init(void);
1342
1343
1344PJ_END_DECL
1345
1346#endif /* __PJ_OS_H__ */
1347