blob: e1d3c485865c3074db5bda9c067ebedf163b06bf [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 */
Benny Prijonobe6d5db2009-07-22 11:12:35 +0000678PJ_DECL(pj_bool_t) pj_mutex_is_locked(pj_mutex_t *mutex);
Benny Prijono9033e312005-11-21 02:08:39 +0000679
680/**
681 * @}
682 */
683
Benny Prijono92ac4472006-07-22 13:42:56 +0000684/* **************************************************************************/
Benny Prijono9033e312005-11-21 02:08:39 +0000685/**
Benny Prijono0ca04b62005-12-30 23:50:15 +0000686 * @defgroup PJ_RW_MUTEX Reader/Writer Mutex
687 * @ingroup PJ_OS
688 * @{
689 * Reader/writer mutex is a classic synchronization object where multiple
690 * readers can acquire the mutex, but only a single writer can acquire the
691 * mutex.
692 */
Benny Prijono294c2532006-06-16 16:52:51 +0000693
694/**
695 * Opaque declaration for reader/writer mutex.
696 * Reader/writer mutex is a classic synchronization object where multiple
697 * readers can acquire the mutex, but only a single writer can acquire the
698 * mutex.
699 */
Benny Prijono0ca04b62005-12-30 23:50:15 +0000700typedef struct pj_rwmutex_t pj_rwmutex_t;
701
702/**
703 * Create reader/writer mutex.
704 *
705 * @param pool Pool to allocate memory for the mutex.
706 * @param name Name to be assigned to the mutex.
707 * @param mutex Pointer to receive the newly created mutex.
708 *
709 * @return PJ_SUCCESS on success, or the error code.
710 */
711PJ_DECL(pj_status_t) pj_rwmutex_create(pj_pool_t *pool, const char *name,
712 pj_rwmutex_t **mutex);
713
714/**
715 * Lock the mutex for reading.
716 *
717 * @param mutex The mutex.
718 * @return PJ_SUCCESS on success, or the error code.
719 */
720PJ_DECL(pj_status_t) pj_rwmutex_lock_read(pj_rwmutex_t *mutex);
721
722/**
723 * Lock the mutex for writing.
724 *
725 * @param mutex The mutex.
726 * @return PJ_SUCCESS on success, or the error code.
727 */
728PJ_DECL(pj_status_t) pj_rwmutex_lock_write(pj_rwmutex_t *mutex);
729
730/**
731 * Release read lock.
732 *
733 * @param mutex The mutex.
734 * @return PJ_SUCCESS on success, or the error code.
735 */
736PJ_DECL(pj_status_t) pj_rwmutex_unlock_read(pj_rwmutex_t *mutex);
737
738/**
739 * Release write lock.
740 *
741 * @param mutex The mutex.
742 * @return PJ_SUCCESS on success, or the error code.
743 */
744PJ_DECL(pj_status_t) pj_rwmutex_unlock_write(pj_rwmutex_t *mutex);
745
746/**
747 * Destroy reader/writer mutex.
748 *
749 * @param mutex The mutex.
750 * @return PJ_SUCCESS on success, or the error code.
751 */
752PJ_DECL(pj_status_t) pj_rwmutex_destroy(pj_rwmutex_t *mutex);
753
754
755/**
756 * @}
757 */
758
759
Benny Prijono92ac4472006-07-22 13:42:56 +0000760/* **************************************************************************/
Benny Prijono0ca04b62005-12-30 23:50:15 +0000761/**
Benny Prijono9033e312005-11-21 02:08:39 +0000762 * @defgroup PJ_CRIT_SEC Critical sections.
763 * @ingroup PJ_OS
764 * @{
765 * Critical section protection can be used to protect regions where:
766 * - mutual exclusion protection is needed.
767 * - it's rather too expensive to create a mutex.
768 * - the time spent in the region is very very brief.
769 *
770 * Critical section is a global object, and it prevents any threads from
771 * entering any regions that are protected by critical section once a thread
772 * is already in the section.
773 *
774 * Critial section is \a not recursive!
775 *
776 * Application <b>MUST NOT</b> call any functions that may cause current
777 * thread to block (such as allocating memory, performing I/O, locking mutex,
778 * etc.) while holding the critical section.
779 */
780/**
781 * Enter critical section.
782 */
783PJ_DECL(void) pj_enter_critical_section(void);
784
785/**
786 * Leave critical section.
787 */
788PJ_DECL(void) pj_leave_critical_section(void);
789
790/**
791 * @}
792 */
793
Benny Prijono92ac4472006-07-22 13:42:56 +0000794/* **************************************************************************/
Benny Prijono9033e312005-11-21 02:08:39 +0000795#if defined(PJ_HAS_SEMAPHORE) && PJ_HAS_SEMAPHORE != 0
796/**
797 * @defgroup PJ_SEM Semaphores.
798 * @ingroup PJ_OS
799 * @{
800 *
801 * This module provides abstraction for semaphores, where available.
802 */
803
804/**
805 * Create semaphore.
806 *
807 * @param pool The pool.
808 * @param name Name to be assigned to the semaphore (for logging purpose)
809 * @param initial The initial count of the semaphore.
810 * @param max The maximum count of the semaphore.
811 * @param sem Pointer to hold the semaphore created.
812 *
813 * @return PJ_SUCCESS on success, or the error code.
814 */
815PJ_DECL(pj_status_t) pj_sem_create( pj_pool_t *pool,
816 const char *name,
817 unsigned initial,
818 unsigned max,
819 pj_sem_t **sem);
820
821/**
822 * Wait for semaphore.
823 *
824 * @param sem The semaphore.
825 *
826 * @return PJ_SUCCESS on success, or the error code.
827 */
828PJ_DECL(pj_status_t) pj_sem_wait(pj_sem_t *sem);
829
830/**
831 * Try wait for semaphore.
832 *
833 * @param sem The semaphore.
834 *
835 * @return PJ_SUCCESS on success, or the error code.
836 */
837PJ_DECL(pj_status_t) pj_sem_trywait(pj_sem_t *sem);
838
839/**
840 * Release semaphore.
841 *
842 * @param sem The semaphore.
843 *
844 * @return PJ_SUCCESS on success, or the error code.
845 */
846PJ_DECL(pj_status_t) pj_sem_post(pj_sem_t *sem);
847
848/**
849 * Destroy semaphore.
850 *
851 * @param sem The semaphore.
852 *
853 * @return PJ_SUCCESS on success, or the error code.
854 */
855PJ_DECL(pj_status_t) pj_sem_destroy(pj_sem_t *sem);
856
857/**
858 * @}
859 */
860#endif /* PJ_HAS_SEMAPHORE */
861
862
Benny Prijono92ac4472006-07-22 13:42:56 +0000863/* **************************************************************************/
Benny Prijono9033e312005-11-21 02:08:39 +0000864#if defined(PJ_HAS_EVENT_OBJ) && PJ_HAS_EVENT_OBJ != 0
865/**
866 * @defgroup PJ_EVENT Event Object.
867 * @ingroup PJ_OS
868 * @{
869 *
870 * This module provides abstraction to event object (e.g. Win32 Event) where
871 * available. Event objects can be used for synchronization among threads.
872 */
873
874/**
875 * Create event object.
876 *
877 * @param pool The pool.
878 * @param name The name of the event object (for logging purpose).
879 * @param manual_reset Specify whether the event is manual-reset
880 * @param initial Specify the initial state of the event object.
881 * @param event Pointer to hold the returned event object.
882 *
883 * @return event handle, or NULL if failed.
884 */
885PJ_DECL(pj_status_t) pj_event_create(pj_pool_t *pool, const char *name,
886 pj_bool_t manual_reset, pj_bool_t initial,
887 pj_event_t **event);
888
889/**
890 * Wait for event to be signaled.
891 *
892 * @param event The event object.
893 *
894 * @return zero if successfull.
895 */
896PJ_DECL(pj_status_t) pj_event_wait(pj_event_t *event);
897
898/**
899 * Try wait for event object to be signalled.
900 *
901 * @param event The event object.
902 *
903 * @return zero if successfull.
904 */
905PJ_DECL(pj_status_t) pj_event_trywait(pj_event_t *event);
906
907/**
908 * Set the event object state to signaled. For auto-reset event, this
909 * will only release the first thread that are waiting on the event. For
910 * manual reset event, the state remains signaled until the event is reset.
911 * If there is no thread waiting on the event, the event object state
912 * remains signaled.
913 *
914 * @param event The event object.
915 *
916 * @return zero if successfull.
917 */
918PJ_DECL(pj_status_t) pj_event_set(pj_event_t *event);
919
920/**
921 * Set the event object to signaled state to release appropriate number of
922 * waiting threads and then reset the event object to non-signaled. For
923 * manual-reset event, this function will release all waiting threads. For
924 * auto-reset event, this function will only release one waiting thread.
925 *
926 * @param event The event object.
927 *
928 * @return zero if successfull.
929 */
930PJ_DECL(pj_status_t) pj_event_pulse(pj_event_t *event);
931
932/**
933 * Set the event object state to non-signaled.
934 *
935 * @param event The event object.
936 *
937 * @return zero if successfull.
938 */
939PJ_DECL(pj_status_t) pj_event_reset(pj_event_t *event);
940
941/**
942 * Destroy the event object.
943 *
944 * @param event The event object.
945 *
946 * @return zero if successfull.
947 */
948PJ_DECL(pj_status_t) pj_event_destroy(pj_event_t *event);
949
950/**
951 * @}
952 */
953#endif /* PJ_HAS_EVENT_OBJ */
954
Benny Prijono92ac4472006-07-22 13:42:56 +0000955/* **************************************************************************/
Benny Prijono9033e312005-11-21 02:08:39 +0000956/**
957 * @addtogroup PJ_TIME Time Data Type and Manipulation.
958 * @ingroup PJ_OS
959 * @{
960 * This module provides API for manipulating time.
961 *
962 * \section pj_time_examples_sec Examples
963 *
964 * For examples, please see:
965 * - \ref page_pjlib_sleep_test
966 */
967
968/**
969 * Get current time of day in local representation.
970 *
971 * @param tv Variable to store the result.
972 *
973 * @return zero if successfull.
974 */
975PJ_DECL(pj_status_t) pj_gettimeofday(pj_time_val *tv);
976
977
978/**
979 * Parse time value into date/time representation.
980 *
981 * @param tv The time.
982 * @param pt Variable to store the date time result.
983 *
984 * @return zero if successfull.
985 */
986PJ_DECL(pj_status_t) pj_time_decode(const pj_time_val *tv, pj_parsed_time *pt);
987
988/**
989 * Encode date/time to time value.
990 *
991 * @param pt The date/time.
992 * @param tv Variable to store time value result.
993 *
994 * @return zero if successfull.
995 */
996PJ_DECL(pj_status_t) pj_time_encode(const pj_parsed_time *pt, pj_time_val *tv);
997
998/**
999 * Convert local time to GMT.
1000 *
1001 * @param tv Time to convert.
1002 *
1003 * @return zero if successfull.
1004 */
1005PJ_DECL(pj_status_t) pj_time_local_to_gmt(pj_time_val *tv);
1006
1007/**
1008 * Convert GMT to local time.
1009 *
1010 * @param tv Time to convert.
1011 *
1012 * @return zero if successfull.
1013 */
1014PJ_DECL(pj_status_t) pj_time_gmt_to_local(pj_time_val *tv);
1015
1016/**
1017 * @}
1018 */
1019
Benny Prijono92ac4472006-07-22 13:42:56 +00001020/* **************************************************************************/
Benny Prijono9033e312005-11-21 02:08:39 +00001021#if defined(PJ_TERM_HAS_COLOR) && PJ_TERM_HAS_COLOR != 0
1022
1023/**
1024 * @defgroup PJ_TERM Terminal
1025 * @ingroup PJ_OS
1026 * @{
1027 */
1028
1029/**
1030 * Set current terminal color.
1031 *
1032 * @param color The RGB color.
1033 *
1034 * @return zero on success.
1035 */
1036PJ_DECL(pj_status_t) pj_term_set_color(pj_color_t color);
1037
1038/**
1039 * Get current terminal foreground color.
1040 *
1041 * @return RGB color.
1042 */
1043PJ_DECL(pj_color_t) pj_term_get_color(void);
1044
1045/**
1046 * @}
1047 */
1048
1049#endif /* PJ_TERM_HAS_COLOR */
1050
Benny Prijono92ac4472006-07-22 13:42:56 +00001051/* **************************************************************************/
Benny Prijono9033e312005-11-21 02:08:39 +00001052/**
1053 * @defgroup PJ_TIMESTAMP High Resolution Timestamp
1054 * @ingroup PJ_OS
1055 * @{
1056 *
1057 * PJLIB provides <b>High Resolution Timestamp</b> API to access highest
1058 * resolution timestamp value provided by the platform. The API is usefull
1059 * to measure precise elapsed time, and can be used in applications such
1060 * as profiling.
1061 *
1062 * The timestamp value is represented in cycles, and can be related to
1063 * normal time (in seconds or sub-seconds) using various functions provided.
1064 *
1065 * \section pj_timestamp_examples_sec Examples
1066 *
1067 * For examples, please see:
1068 * - \ref page_pjlib_sleep_test
1069 * - \ref page_pjlib_timestamp_test
1070 */
1071
1072/*
1073 * High resolution timer.
1074 */
1075#if defined(PJ_HAS_HIGH_RES_TIMER) && PJ_HAS_HIGH_RES_TIMER != 0
1076
1077/**
Benny Prijono9033e312005-11-21 02:08:39 +00001078 * Acquire high resolution timer value. The time value are stored
1079 * in cycles.
1080 *
1081 * @param ts High resolution timer value.
1082 * @return PJ_SUCCESS or the appropriate error code.
1083 *
1084 * @see pj_get_timestamp_freq().
1085 */
1086PJ_DECL(pj_status_t) pj_get_timestamp(pj_timestamp *ts);
1087
1088/**
1089 * Get high resolution timer frequency, in cycles per second.
1090 *
1091 * @param freq Timer frequency, in cycles per second.
1092 * @return PJ_SUCCESS or the appropriate error code.
1093 */
1094PJ_DECL(pj_status_t) pj_get_timestamp_freq(pj_timestamp *freq);
1095
1096/**
Benny Prijonoc357d642007-01-20 05:14:24 +00001097 * Set timestamp from 32bit values.
1098 * @param t The timestamp to be set.
1099 * @param hi The high 32bit part.
1100 * @param lo The low 32bit part.
1101 */
1102PJ_INLINE(void) pj_set_timestamp32(pj_timestamp *t, pj_uint32_t hi,
1103 pj_uint32_t lo)
1104{
1105 t->u32.hi = hi;
1106 t->u32.lo = lo;
1107}
1108
Benny Prijono6f86e7c2007-04-02 11:28:41 +00001109
1110/**
1111 * Compare timestamp t1 and t2.
1112 * @param t1 t1.
1113 * @param t2 t2.
1114 * @return -1 if (t1 < t2), 1 if (t1 > t2), or 0 if (t1 == t2)
1115 */
1116PJ_INLINE(int) pj_cmp_timestamp(const pj_timestamp *t1, const pj_timestamp *t2)
1117{
1118#if PJ_HAS_INT64
1119 if (t1->u64 < t2->u64)
1120 return -1;
1121 else if (t1->u64 > t2->u64)
1122 return 1;
1123 else
1124 return 0;
1125#else
1126 if (t1->u32.hi < t2->u32.hi ||
1127 (t1->u32.hi == t2->u32.hi && t1->u32.lo < t2->u32.lo))
1128 return -1;
1129 else if (t1->u32.hi > t2->u32.hi ||
1130 (t1->u32.hi == t2->u32.hi && t1->u32.lo > t2->u32.lo))
1131 return 1;
1132 else
1133 return 0;
1134#endif
1135}
1136
1137
Benny Prijonoc357d642007-01-20 05:14:24 +00001138/**
Benny Prijono9033e312005-11-21 02:08:39 +00001139 * Add timestamp t2 to t1.
1140 * @param t1 t1.
1141 * @param t2 t2.
1142 */
1143PJ_INLINE(void) pj_add_timestamp(pj_timestamp *t1, const pj_timestamp *t2)
1144{
1145#if PJ_HAS_INT64
1146 t1->u64 += t2->u64;
1147#else
1148 pj_uint32_t old = t1->u32.lo;
1149 t1->u32.hi += t2->u32.hi;
1150 t1->u32.lo += t2->u32.lo;
1151 if (t1->u32.lo < old)
1152 ++t1->u32.hi;
1153#endif
1154}
1155
1156/**
Benny Prijonoc357d642007-01-20 05:14:24 +00001157 * Add timestamp t2 to t1.
1158 * @param t1 t1.
1159 * @param t2 t2.
1160 */
1161PJ_INLINE(void) pj_add_timestamp32(pj_timestamp *t1, pj_uint32_t t2)
1162{
1163#if PJ_HAS_INT64
1164 t1->u64 += t2;
1165#else
1166 pj_uint32_t old = t1->u32.lo;
1167 t1->u32.lo += t2;
1168 if (t1->u32.lo < old)
1169 ++t1->u32.hi;
1170#endif
1171}
1172
1173/**
Benny Prijono9033e312005-11-21 02:08:39 +00001174 * Substract timestamp t2 from t1.
1175 * @param t1 t1.
1176 * @param t2 t2.
1177 */
1178PJ_INLINE(void) pj_sub_timestamp(pj_timestamp *t1, const pj_timestamp *t2)
1179{
1180#if PJ_HAS_INT64
1181 t1->u64 -= t2->u64;
1182#else
1183 t1->u32.hi -= t2->u32.hi;
1184 if (t1->u32.lo >= t2->u32.lo)
1185 t1->u32.lo -= t2->u32.lo;
1186 else {
1187 t1->u32.lo -= t2->u32.lo;
1188 --t1->u32.hi;
1189 }
1190#endif
1191}
1192
1193/**
Benny Prijonoc357d642007-01-20 05:14:24 +00001194 * Substract timestamp t2 from t1.
1195 * @param t1 t1.
1196 * @param t2 t2.
1197 */
1198PJ_INLINE(void) pj_sub_timestamp32(pj_timestamp *t1, pj_uint32_t t2)
1199{
1200#if PJ_HAS_INT64
1201 t1->u64 -= t2;
1202#else
1203 if (t1->u32.lo >= t2)
1204 t1->u32.lo -= t2;
1205 else {
1206 t1->u32.lo -= t2;
1207 --t1->u32.hi;
1208 }
1209#endif
1210}
1211
1212/**
1213 * Get the timestamp difference between t2 and t1 (that is t2 minus t1),
1214 * and return a 32bit signed integer difference.
1215 */
1216PJ_INLINE(pj_int32_t) pj_timestamp_diff32(const pj_timestamp *t1,
1217 const pj_timestamp *t2)
1218{
1219 /* Be careful with the signess (I think!) */
1220#if PJ_HAS_INT64
1221 pj_int64_t diff = t2->u64 - t1->u64;
1222 return (pj_int32_t) diff;
1223#else
1224 pj_int32 diff = t2->u32.lo - t1->u32.lo;
1225 return diff;
1226#endif
1227}
1228
1229
1230/**
Benny Prijono9033e312005-11-21 02:08:39 +00001231 * Calculate the elapsed time, and store it in pj_time_val.
1232 * This function calculates the elapsed time using highest precision
1233 * calculation that is available for current platform, considering
1234 * whether floating point or 64-bit precision arithmetic is available.
1235 * For maximum portability, application should prefer to use this function
1236 * rather than calculating the elapsed time by itself.
1237 *
1238 * @param start The starting timestamp.
1239 * @param stop The end timestamp.
1240 *
1241 * @return Elapsed time as #pj_time_val.
1242 *
1243 * @see pj_elapsed_usec(), pj_elapsed_cycle(), pj_elapsed_nanosec()
1244 */
1245PJ_DECL(pj_time_val) pj_elapsed_time( const pj_timestamp *start,
1246 const pj_timestamp *stop );
1247
1248/**
Benny Prijono99683ae2005-11-21 16:59:47 +00001249 * Calculate the elapsed time as 32-bit miliseconds.
1250 * This function calculates the elapsed time using highest precision
1251 * calculation that is available for current platform, considering
1252 * whether floating point or 64-bit precision arithmetic is available.
1253 * For maximum portability, application should prefer to use this function
1254 * rather than calculating the elapsed time by itself.
1255 *
1256 * @param start The starting timestamp.
1257 * @param stop The end timestamp.
1258 *
1259 * @return Elapsed time in milisecond.
1260 *
1261 * @see pj_elapsed_time(), pj_elapsed_cycle(), pj_elapsed_nanosec()
1262 */
1263PJ_DECL(pj_uint32_t) pj_elapsed_msec( const pj_timestamp *start,
1264 const pj_timestamp *stop );
1265
1266/**
Benny Prijonof1a47b82009-03-30 18:22:16 +00001267 * Variant of #pj_elapsed_msec() which returns 64bit value.
1268 */
1269PJ_DECL(pj_uint64_t) pj_elapsed_msec64(const pj_timestamp *start,
1270 const pj_timestamp *stop );
1271
1272/**
Benny Prijono9033e312005-11-21 02:08:39 +00001273 * Calculate the elapsed time in 32-bit microseconds.
1274 * This function calculates the elapsed time using highest precision
1275 * calculation that is available for current platform, considering
1276 * whether floating point or 64-bit precision arithmetic is available.
1277 * For maximum portability, application should prefer to use this function
1278 * rather than calculating the elapsed time by itself.
1279 *
1280 * @param start The starting timestamp.
1281 * @param stop The end timestamp.
1282 *
1283 * @return Elapsed time in microsecond.
1284 *
1285 * @see pj_elapsed_time(), pj_elapsed_cycle(), pj_elapsed_nanosec()
1286 */
1287PJ_DECL(pj_uint32_t) pj_elapsed_usec( const pj_timestamp *start,
1288 const pj_timestamp *stop );
1289
1290/**
1291 * Calculate the elapsed time in 32-bit nanoseconds.
1292 * This function calculates the elapsed time using highest precision
1293 * calculation that is available for current platform, considering
1294 * whether floating point or 64-bit precision arithmetic is available.
1295 * For maximum portability, application should prefer to use this function
1296 * rather than calculating the elapsed time by itself.
1297 *
1298 * @param start The starting timestamp.
1299 * @param stop The end timestamp.
1300 *
1301 * @return Elapsed time in nanoseconds.
1302 *
1303 * @see pj_elapsed_time(), pj_elapsed_cycle(), pj_elapsed_usec()
1304 */
1305PJ_DECL(pj_uint32_t) pj_elapsed_nanosec( const pj_timestamp *start,
1306 const pj_timestamp *stop );
1307
1308/**
1309 * Calculate the elapsed time in 32-bit cycles.
1310 * This function calculates the elapsed time using highest precision
1311 * calculation that is available for current platform, considering
1312 * whether floating point or 64-bit precision arithmetic is available.
1313 * For maximum portability, application should prefer to use this function
1314 * rather than calculating the elapsed time by itself.
1315 *
1316 * @param start The starting timestamp.
1317 * @param stop The end timestamp.
1318 *
1319 * @return Elapsed time in cycles.
1320 *
1321 * @see pj_elapsed_usec(), pj_elapsed_time(), pj_elapsed_nanosec()
1322 */
1323PJ_DECL(pj_uint32_t) pj_elapsed_cycle( const pj_timestamp *start,
1324 const pj_timestamp *stop );
1325
1326
1327#endif /* PJ_HAS_HIGH_RES_TIMER */
1328
1329/** @} */
1330
1331
Benny Prijono92ac4472006-07-22 13:42:56 +00001332/* **************************************************************************/
Benny Prijono9033e312005-11-21 02:08:39 +00001333/**
1334 * Internal PJLIB function to initialize the threading subsystem.
1335 * @return PJ_SUCCESS or the appropriate error code.
1336 */
1337pj_status_t pj_thread_init(void);
1338
1339
1340PJ_END_DECL
1341
1342#endif /* __PJ_OS_H__ */
1343