blob: 3ce877afe2ab09766d41f9b623b89c54a215c07e [file] [log] [blame]
Tristan Matthews0a329cc2013-07-17 13:20:14 -04001/* $Id$ */
2/*
3 * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
4 * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
5 *
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.
33 */
34
35
36/* **************************************************************************/
37/**
38 * @defgroup PJ_SYS_INFO System Information
39 * @ingroup PJ_OS
40 * @{
41 */
42
43/**
44 * These enumeration contains constants to indicate support of miscellaneous
45 * system features. These will go in "flags" field of #pj_sys_info structure.
46 */
47typedef enum pj_sys_info_flag
48{
49 /**
50 * Support for Apple iOS background feature.
51 */
52 PJ_SYS_HAS_IOS_BG = 1
53
54} pj_sys_info_flag;
55
56
57/**
58 * This structure contains information about the system. Use #pj_get_sys_info()
59 * to obtain the system information.
60 */
61typedef struct pj_sys_info
62{
63 /**
64 * Null terminated string containing processor information (e.g. "i386",
65 * "x86_64"). It may contain empty string if the value cannot be obtained.
66 */
67 pj_str_t machine;
68
69 /**
70 * Null terminated string identifying the system operation (e.g. "Linux",
71 * "win32", "wince"). It may contain empty string if the value cannot be
72 * obtained.
73 */
74 pj_str_t os_name;
75
76 /**
77 * A number containing the operating system version number. By convention,
78 * this field is divided into four bytes, where the highest order byte
79 * contains the most major version of the OS, the next less significant
80 * byte contains the less major version, and so on. How the OS version
81 * number is mapped into these four bytes would be specific for each OS.
82 * For example, Linux-2.6.32-28 would yield "os_ver" value of 0x0206201c,
83 * while for Windows 7 it will be 0x06010000 (because dwMajorVersion is
84 * 6 and dwMinorVersion is 1 for Windows 7).
85 *
86 * This field may contain zero if the OS version cannot be obtained.
87 */
88 pj_uint32_t os_ver;
89
90 /**
91 * Null terminated string identifying the SDK name that is used to build
92 * the library (e.g. "glibc", "uclibc", "msvc", "wince"). It may contain
93 * empty string if the value cannot eb obtained.
94 */
95 pj_str_t sdk_name;
96
97 /**
98 * A number containing the SDK version, using the numbering convention as
99 * the "os_ver" field. The value will be zero if the version cannot be
100 * obtained.
101 */
102 pj_uint32_t sdk_ver;
103
104 /**
105 * A longer null terminated string identifying the underlying system with
106 * as much information as possible.
107 */
108 pj_str_t info;
109
110 /**
111 * Other flags containing system specific information. The value is
112 * bitmask of #pj_sys_info_flag constants.
113 */
114 pj_uint32_t flags;
115
116} pj_sys_info;
117
118
119/**
120 * Obtain the system information.
121 *
122 * @return System information structure.
123 */
124PJ_DECL(const pj_sys_info*) pj_get_sys_info(void);
125
126/*
127 * @}
128 */
129
130/* **************************************************************************/
131/**
132 * @defgroup PJ_THREAD Threads
133 * @ingroup PJ_OS
134 * @{
135 * This module provides multithreading API.
136 *
137 * \section pj_thread_examples_sec Examples
138 *
139 * For examples, please see:
140 * - \ref page_pjlib_thread_test
141 * - \ref page_pjlib_sleep_test
142 *
143 */
144
145/**
146 * Thread creation flags:
147 * - PJ_THREAD_SUSPENDED: specify that the thread should be created suspended.
148 */
149typedef enum pj_thread_create_flags
150{
151 PJ_THREAD_SUSPENDED = 1
152} pj_thread_create_flags;
153
154
155/**
156 * Type of thread entry function.
157 */
158typedef int (PJ_THREAD_FUNC pj_thread_proc)(void*);
159
160/**
161 * Size of thread struct.
162 */
163#if !defined(PJ_THREAD_DESC_SIZE)
164# define PJ_THREAD_DESC_SIZE (64)
165#endif
166
167/**
168 * Thread structure, to thread's state when the thread is created by external
169 * or native API.
170 */
171typedef long pj_thread_desc[PJ_THREAD_DESC_SIZE];
172
173/**
174 * Get process ID.
175 * @return process ID.
176 */
177PJ_DECL(pj_uint32_t) pj_getpid(void);
178
179/**
180 * Create a new thread.
181 *
182 * @param pool The memory pool from which the thread record
183 * will be allocated from.
184 * @param thread_name The optional name to be assigned to the thread.
185 * @param proc Thread entry function.
186 * @param arg Argument to be passed to the thread entry function.
187 * @param stack_size The size of the stack for the new thread, or ZERO or
188 * PJ_THREAD_DEFAULT_STACK_SIZE to let the
189 * library choose the reasonable size for the stack.
190 * For some systems, the stack will be allocated from
191 * the pool, so the pool must have suitable capacity.
192 * @param flags Flags for thread creation, which is bitmask combination
193 * from enum pj_thread_create_flags.
194 * @param thread Pointer to hold the newly created thread.
195 *
196 * @return PJ_SUCCESS on success, or the error code.
197 */
198PJ_DECL(pj_status_t) pj_thread_create( pj_pool_t *pool,
199 const char *thread_name,
200 pj_thread_proc *proc,
201 void *arg,
202 pj_size_t stack_size,
203 unsigned flags,
204 pj_thread_t **thread );
205
206/**
207 * Register a thread that was created by external or native API to PJLIB.
208 * This function must be called in the context of the thread being registered.
209 * When the thread is created by external function or API call,
210 * it must be 'registered' to PJLIB using pj_thread_register(), so that it can
211 * cooperate with PJLIB's framework. During registration, some data needs to
212 * be maintained, and this data must remain available during the thread's
213 * lifetime.
214 *
215 * @param thread_name The optional name to be assigned to the thread.
216 * @param desc Thread descriptor, which must be available throughout
217 * the lifetime of the thread.
218 * @param thread Pointer to hold the created thread handle.
219 *
220 * @return PJ_SUCCESS on success, or the error code.
221 */
222PJ_DECL(pj_status_t) pj_thread_register ( const char *thread_name,
223 pj_thread_desc desc,
224 pj_thread_t **thread);
225
226/**
227 * Check if this thread has been registered to PJLIB.
228 *
229 * @return Non-zero if it is registered.
230 */
231PJ_DECL(pj_bool_t) pj_thread_is_registered(void);
232
233
234/**
235 * Get thread priority value for the thread.
236 *
237 * @param thread Thread handle.
238 *
239 * @return Thread priority value, or -1 on error.
240 */
241PJ_DECL(int) pj_thread_get_prio(pj_thread_t *thread);
242
243
244/**
245 * Set the thread priority. The priority value must be in the priority
246 * value range, which can be retrieved with #pj_thread_get_prio_min() and
247 * #pj_thread_get_prio_max() functions.
248 *
249 * @param thread Thread handle.
250 * @param prio New priority to be set to the thread.
251 *
252 * @return PJ_SUCCESS on success or the error code.
253 */
254PJ_DECL(pj_status_t) pj_thread_set_prio(pj_thread_t *thread, int prio);
255
256/**
257 * Get the lowest priority value available for this thread.
258 *
259 * @param thread Thread handle.
260 * @return Minimum thread priority value, or -1 on error.
261 */
262PJ_DECL(int) pj_thread_get_prio_min(pj_thread_t *thread);
263
264
265/**
266 * Get the highest priority value available for this thread.
267 *
268 * @param thread Thread handle.
269 * @return Minimum thread priority value, or -1 on error.
270 */
271PJ_DECL(int) pj_thread_get_prio_max(pj_thread_t *thread);
272
273
274/**
275 * Return native handle from pj_thread_t for manipulation using native
276 * OS APIs.
277 *
278 * @param thread PJLIB thread descriptor.
279 *
280 * @return Native thread handle. For example, when the
281 * backend thread uses pthread, this function will
282 * return pointer to pthread_t, and on Windows,
283 * this function will return HANDLE.
284 */
285PJ_DECL(void*) pj_thread_get_os_handle(pj_thread_t *thread);
286
287/**
288 * Get thread name.
289 *
290 * @param thread The thread handle.
291 *
292 * @return Thread name as null terminated string.
293 */
294PJ_DECL(const char*) pj_thread_get_name(pj_thread_t *thread);
295
296/**
297 * Resume a suspended thread.
298 *
299 * @param thread The thread handle.
300 *
301 * @return zero on success.
302 */
303PJ_DECL(pj_status_t) pj_thread_resume(pj_thread_t *thread);
304
305/**
306 * Get the current thread.
307 *
308 * @return Thread handle of current thread.
309 */
310PJ_DECL(pj_thread_t*) pj_thread_this(void);
311
312/**
313 * Join thread, and block the caller thread until the specified thread exits.
314 * If the specified thread has already been dead, or it does not exist,
315 * the function will return immediately with successfull status.
316 *
317 * @param thread The thread handle.
318 *
319 * @return PJ_SUCCESS on success.
320 */
321PJ_DECL(pj_status_t) pj_thread_join(pj_thread_t *thread);
322
323
324/**
325 * Destroy thread and release resources allocated for the thread.
326 * However, the memory allocated for the pj_thread_t itself will only be released
327 * when the pool used to create the thread is destroyed.
328 *
329 * @param thread The thread handle.
330 *
331 * @return zero on success.
332 */
333PJ_DECL(pj_status_t) pj_thread_destroy(pj_thread_t *thread);
334
335
336/**
337 * Put the current thread to sleep for the specified miliseconds.
338 *
339 * @param msec Miliseconds delay.
340 *
341 * @return zero if successfull.
342 */
343PJ_DECL(pj_status_t) pj_thread_sleep(unsigned msec);
344
345/**
346 * @def PJ_CHECK_STACK()
347 * PJ_CHECK_STACK() macro is used to check the sanity of the stack.
348 * The OS implementation may check that no stack overflow occurs, and
349 * it also may collect statistic about stack usage.
350 */
351#if defined(PJ_OS_HAS_CHECK_STACK) && PJ_OS_HAS_CHECK_STACK!=0
352
353# define PJ_CHECK_STACK() pj_thread_check_stack(__FILE__, __LINE__)
354
355/** @internal
356 * The implementation of stack checking.
357 */
358PJ_DECL(void) pj_thread_check_stack(const char *file, int line);
359
360/** @internal
361 * Get maximum stack usage statistic.
362 */
363PJ_DECL(pj_uint32_t) pj_thread_get_stack_max_usage(pj_thread_t *thread);
364
365/** @internal
366 * Dump thread stack status.
367 */
368PJ_DECL(pj_status_t) pj_thread_get_stack_info(pj_thread_t *thread,
369 const char **file,
370 int *line);
371#else
372
373# define PJ_CHECK_STACK()
374/** pj_thread_get_stack_max_usage() for the thread */
375# define pj_thread_get_stack_max_usage(thread) 0
376/** pj_thread_get_stack_info() for the thread */
377# define pj_thread_get_stack_info(thread,f,l) (*(f)="",*(l)=0)
378#endif /* PJ_OS_HAS_CHECK_STACK */
379
380/**
381 * @}
382 */
383
384/* **************************************************************************/
385/**
386 * @defgroup PJ_SYMBIAN_OS Symbian OS Specific
387 * @ingroup PJ_OS
388 * @{
389 * Functionalities specific to Symbian OS.
390 *
391 * Symbian OS strongly discourages the use of polling since this wastes
392 * CPU power, and instead provides Active Object and Active Scheduler
393 * pattern to allow application (in this case, PJLIB) to register asynchronous
394 * tasks. PJLIB port for Symbian complies to this recommended behavior.
395 * As the result, few things have been changed in PJLIB for Symbian:
396 * - the timer heap (see @ref PJ_TIMER) is implemented with active
397 * object framework, and each timer entry registered to the timer
398 * heap will register an Active Object to the Active Scheduler.
399 * Because of this, polling the timer heap with pj_timer_heap_poll()
400 * is no longer necessary, and this function will just evaluate
401 * to nothing.
402 * - the ioqueue (see @ref PJ_IOQUEUE) is also implemented with
403 * active object framework, with each asynchronous operation will
404 * register an Active Object to the Active Scheduler. Because of
405 * this, polling the ioqueue with pj_ioqueue_poll() is no longer
406 * necessary, and this function will just evaluate to nothing.
407 *
408 * Since timer heap and ioqueue polling are no longer necessary, Symbian
409 * application can now poll for all events by calling
410 * \a User::WaitForAnyRequest() and \a CActiveScheduler::RunIfReady().
411 * PJLIB provides a thin wrapper which calls these two functions,
412 * called pj_symbianos_poll().
413 */
414
415/**
416 * Wait the completion of any Symbian active objects. When the timeout
417 * value is not specified (the \a ms_timeout argument is -1), this
418 * function is a thin wrapper which calls \a User::WaitForAnyRequest()
419 * and \a CActiveScheduler::RunIfReady(). If the timeout value is
420 * specified, this function will schedule a timer entry to the timer
421 * heap (which is an Active Object), to limit the wait time for event
422 * occurences. Scheduling a timer entry is an expensive operation,
423 * therefore application should only specify a timeout value when it's
424 * really necessary (for example, when it's not sure there are other
425 * Active Objects currently running in the application).
426 *
427 * @param priority The minimum priority of the Active Objects to
428 * poll, which values are from CActive::TPriority
429 * constants. If -1 is given, CActive::EPriorityStandard.
430 * priority will be used.
431 * @param ms_timeout Optional timeout to wait. Application should
432 * specify -1 to let the function wait indefinitely
433 * for any events.
434 *
435 * @return PJ_TRUE if there have been any events executed
436 * during the polling. This function will only return
437 * PJ_FALSE if \a ms_timeout argument is specified
438 * (i.e. the value is not -1) and there was no event
439 * executed when the timeout timer elapsed.
440 */
441PJ_DECL(pj_bool_t) pj_symbianos_poll(int priority, int ms_timeout);
442
443
444/**
445 * This structure declares Symbian OS specific parameters that can be
446 * specified when calling #pj_symbianos_set_params().
447 */
448typedef struct pj_symbianos_params
449{
450 /**
451 * Optional RSocketServ instance to be used by PJLIB. If this
452 * value is NULL, PJLIB will create a new RSocketServ instance
453 * when pj_init() is called.
454 */
455 void *rsocketserv;
456
457 /**
458 * Optional RConnection instance to be used by PJLIB when creating
459 * sockets. If this value is NULL, no RConnection will be
460 * specified when creating sockets.
461 */
462 void *rconnection;
463
464 /**
465 * Optional RHostResolver instance to be used by PJLIB. If this value
466 * is NULL, a new RHostResolver instance will be created when
467 * pj_init() is called.
468 */
469 void *rhostresolver;
470
471 /**
472 * Optional RHostResolver for IPv6 instance to be used by PJLIB.
473 * If this value is NULL, a new RHostResolver instance will be created
474 * when pj_init() is called.
475 */
476 void *rhostresolver6;
477
478} pj_symbianos_params;
479
480/**
481 * Specify Symbian OS parameters to be used by PJLIB. This function MUST
482 * be called before #pj_init() is called.
483 *
484 * @param prm Symbian specific parameters.
485 *
486 * @return PJ_SUCCESS if the parameters can be applied
487 * successfully.
488 */
489PJ_DECL(pj_status_t) pj_symbianos_set_params(pj_symbianos_params *prm);
490
491/**
492 * Notify PJLIB that the access point connection has been down or unusable
493 * and PJLIB should not try to access the Symbian socket API (especially ones
494 * that send packets). Sending packet when RConnection is reconnected to
495 * different access point may cause the WaitForRequest() for the function to
496 * block indefinitely.
497 *
498 * @param up If set to PJ_FALSE it will cause PJLIB to not try
499 * to access socket API, and error will be returned
500 * immediately instead.
501 */
502PJ_DECL(void) pj_symbianos_set_connection_status(pj_bool_t up);
503
504/**
505 * @}
506 */
507
508/* **************************************************************************/
509/**
510 * @defgroup PJ_TLS Thread Local Storage.
511 * @ingroup PJ_OS
512 * @{
513 */
514
515/**
516 * Allocate thread local storage index. The initial value of the variable at
517 * the index is zero.
518 *
519 * @param index Pointer to hold the return value.
520 * @return PJ_SUCCESS on success, or the error code.
521 */
522PJ_DECL(pj_status_t) pj_thread_local_alloc(long *index);
523
524/**
525 * Deallocate thread local variable.
526 *
527 * @param index The variable index.
528 */
529PJ_DECL(void) pj_thread_local_free(long index);
530
531/**
532 * Set the value of thread local variable.
533 *
534 * @param index The index of the variable.
535 * @param value The value.
536 */
537PJ_DECL(pj_status_t) pj_thread_local_set(long index, void *value);
538
539/**
540 * Get the value of thread local variable.
541 *
542 * @param index The index of the variable.
543 * @return The value.
544 */
545PJ_DECL(void*) pj_thread_local_get(long index);
546
547
548/**
549 * @}
550 */
551
552
553/* **************************************************************************/
554/**
555 * @defgroup PJ_ATOMIC Atomic Variables
556 * @ingroup PJ_OS
557 * @{
558 *
559 * This module provides API to manipulate atomic variables.
560 *
561 * \section pj_atomic_examples_sec Examples
562 *
563 * For some example codes, please see:
564 * - @ref page_pjlib_atomic_test
565 */
566
567
568/**
569 * Create atomic variable.
570 *
571 * @param pool The pool.
572 * @param initial The initial value of the atomic variable.
573 * @param atomic Pointer to hold the atomic variable upon return.
574 *
575 * @return PJ_SUCCESS on success, or the error code.
576 */
577PJ_DECL(pj_status_t) pj_atomic_create( pj_pool_t *pool,
578 pj_atomic_value_t initial,
579 pj_atomic_t **atomic );
580
581/**
582 * Destroy atomic variable.
583 *
584 * @param atomic_var the atomic variable.
585 *
586 * @return PJ_SUCCESS if success.
587 */
588PJ_DECL(pj_status_t) pj_atomic_destroy( pj_atomic_t *atomic_var );
589
590/**
591 * Set the value of an atomic type, and return the previous value.
592 *
593 * @param atomic_var the atomic variable.
594 * @param value value to be set to the variable.
595 */
596PJ_DECL(void) pj_atomic_set( pj_atomic_t *atomic_var,
597 pj_atomic_value_t value);
598
599/**
600 * Get the value of an atomic type.
601 *
602 * @param atomic_var the atomic variable.
603 *
604 * @return the value of the atomic variable.
605 */
606PJ_DECL(pj_atomic_value_t) pj_atomic_get(pj_atomic_t *atomic_var);
607
608/**
609 * Increment the value of an atomic type.
610 *
611 * @param atomic_var the atomic variable.
612 */
613PJ_DECL(void) pj_atomic_inc(pj_atomic_t *atomic_var);
614
615/**
616 * Increment the value of an atomic type and get the result.
617 *
618 * @param atomic_var the atomic variable.
619 *
620 * @return The incremented value.
621 */
622PJ_DECL(pj_atomic_value_t) pj_atomic_inc_and_get(pj_atomic_t *atomic_var);
623
624/**
625 * Decrement the value of an atomic type.
626 *
627 * @param atomic_var the atomic variable.
628 */
629PJ_DECL(void) pj_atomic_dec(pj_atomic_t *atomic_var);
630
631/**
632 * Decrement the value of an atomic type and get the result.
633 *
634 * @param atomic_var the atomic variable.
635 *
636 * @return The decremented value.
637 */
638PJ_DECL(pj_atomic_value_t) pj_atomic_dec_and_get(pj_atomic_t *atomic_var);
639
640/**
641 * Add a value to an atomic type.
642 *
643 * @param atomic_var The atomic variable.
644 * @param value Value to be added.
645 */
646PJ_DECL(void) pj_atomic_add( pj_atomic_t *atomic_var,
647 pj_atomic_value_t value);
648
649/**
650 * Add a value to an atomic type and get the result.
651 *
652 * @param atomic_var The atomic variable.
653 * @param value Value to be added.
654 *
655 * @return The result after the addition.
656 */
657PJ_DECL(pj_atomic_value_t) pj_atomic_add_and_get( pj_atomic_t *atomic_var,
658 pj_atomic_value_t value);
659
660/**
661 * @}
662 */
663
664/* **************************************************************************/
665/**
666 * @defgroup PJ_MUTEX Mutexes.
667 * @ingroup PJ_OS
668 * @{
669 *
670 * Mutex manipulation. Alternatively, application can use higher abstraction
671 * for lock objects, which provides uniform API for all kinds of lock
672 * mechanisms, including mutex. See @ref PJ_LOCK for more information.
673 */
674
675/**
676 * Mutex types:
677 * - PJ_MUTEX_DEFAULT: default mutex type, which is system dependent.
678 * - PJ_MUTEX_SIMPLE: non-recursive mutex.
679 * - PJ_MUTEX_RECURSE: recursive mutex.
680 */
681typedef enum pj_mutex_type_e
682{
683 PJ_MUTEX_DEFAULT,
684 PJ_MUTEX_SIMPLE,
685 PJ_MUTEX_RECURSE
686} pj_mutex_type_e;
687
688
689/**
690 * Create mutex of the specified type.
691 *
692 * @param pool The pool.
693 * @param name Name to be associated with the mutex (for debugging).
694 * @param type The type of the mutex, of type #pj_mutex_type_e.
695 * @param mutex Pointer to hold the returned mutex instance.
696 *
697 * @return PJ_SUCCESS on success, or the error code.
698 */
699PJ_DECL(pj_status_t) pj_mutex_create(pj_pool_t *pool,
700 const char *name,
701 int type,
702 pj_mutex_t **mutex);
703
704/**
705 * Create simple, non-recursive mutex.
706 * This function is a simple wrapper for #pj_mutex_create to create
707 * non-recursive mutex.
708 *
709 * @param pool The pool.
710 * @param name Mutex name.
711 * @param mutex Pointer to hold the returned mutex instance.
712 *
713 * @return PJ_SUCCESS on success, or the error code.
714 */
715PJ_DECL(pj_status_t) pj_mutex_create_simple( pj_pool_t *pool, const char *name,
716 pj_mutex_t **mutex );
717
718/**
719 * Create recursive mutex.
720 * This function is a simple wrapper for #pj_mutex_create to create
721 * recursive mutex.
722 *
723 * @param pool The pool.
724 * @param name Mutex name.
725 * @param mutex Pointer to hold the returned mutex instance.
726 *
727 * @return PJ_SUCCESS on success, or the error code.
728 */
729PJ_DECL(pj_status_t) pj_mutex_create_recursive( pj_pool_t *pool,
730 const char *name,
731 pj_mutex_t **mutex );
732
733/**
734 * Acquire mutex lock.
735 *
736 * @param mutex The mutex.
737 * @return PJ_SUCCESS on success, or the error code.
738 */
739PJ_DECL(pj_status_t) pj_mutex_lock(pj_mutex_t *mutex);
740
741/**
742 * Release mutex lock.
743 *
744 * @param mutex The mutex.
745 * @return PJ_SUCCESS on success, or the error code.
746 */
747PJ_DECL(pj_status_t) pj_mutex_unlock(pj_mutex_t *mutex);
748
749/**
750 * Try to acquire mutex lock.
751 *
752 * @param mutex The mutex.
753 * @return PJ_SUCCESS on success, or the error code if the
754 * lock couldn't be acquired.
755 */
756PJ_DECL(pj_status_t) pj_mutex_trylock(pj_mutex_t *mutex);
757
758/**
759 * Destroy mutex.
760 *
761 * @param mutex Te mutex.
762 * @return PJ_SUCCESS on success, or the error code.
763 */
764PJ_DECL(pj_status_t) pj_mutex_destroy(pj_mutex_t *mutex);
765
766/**
767 * Determine whether calling thread is owning the mutex (only available when
768 * PJ_DEBUG is set).
769 * @param mutex The mutex.
770 * @return Non-zero if yes.
771 */
772PJ_DECL(pj_bool_t) pj_mutex_is_locked(pj_mutex_t *mutex);
773
774/**
775 * @}
776 */
777
778/* **************************************************************************/
779/**
780 * @defgroup PJ_RW_MUTEX Reader/Writer Mutex
781 * @ingroup PJ_OS
782 * @{
783 * Reader/writer mutex is a classic synchronization object where multiple
784 * readers can acquire the mutex, but only a single writer can acquire the
785 * mutex.
786 */
787
788/**
789 * Opaque declaration for reader/writer mutex.
790 * Reader/writer mutex is a classic synchronization object where multiple
791 * readers can acquire the mutex, but only a single writer can acquire the
792 * mutex.
793 */
794typedef struct pj_rwmutex_t pj_rwmutex_t;
795
796/**
797 * Create reader/writer mutex.
798 *
799 * @param pool Pool to allocate memory for the mutex.
800 * @param name Name to be assigned to the mutex.
801 * @param mutex Pointer to receive the newly created mutex.
802 *
803 * @return PJ_SUCCESS on success, or the error code.
804 */
805PJ_DECL(pj_status_t) pj_rwmutex_create(pj_pool_t *pool, const char *name,
806 pj_rwmutex_t **mutex);
807
808/**
809 * Lock the mutex for reading.
810 *
811 * @param mutex The mutex.
812 * @return PJ_SUCCESS on success, or the error code.
813 */
814PJ_DECL(pj_status_t) pj_rwmutex_lock_read(pj_rwmutex_t *mutex);
815
816/**
817 * Lock the mutex for writing.
818 *
819 * @param mutex The mutex.
820 * @return PJ_SUCCESS on success, or the error code.
821 */
822PJ_DECL(pj_status_t) pj_rwmutex_lock_write(pj_rwmutex_t *mutex);
823
824/**
825 * Release read lock.
826 *
827 * @param mutex The mutex.
828 * @return PJ_SUCCESS on success, or the error code.
829 */
830PJ_DECL(pj_status_t) pj_rwmutex_unlock_read(pj_rwmutex_t *mutex);
831
832/**
833 * Release write lock.
834 *
835 * @param mutex The mutex.
836 * @return PJ_SUCCESS on success, or the error code.
837 */
838PJ_DECL(pj_status_t) pj_rwmutex_unlock_write(pj_rwmutex_t *mutex);
839
840/**
841 * Destroy reader/writer mutex.
842 *
843 * @param mutex The mutex.
844 * @return PJ_SUCCESS on success, or the error code.
845 */
846PJ_DECL(pj_status_t) pj_rwmutex_destroy(pj_rwmutex_t *mutex);
847
848
849/**
850 * @}
851 */
852
853
854/* **************************************************************************/
855/**
856 * @defgroup PJ_CRIT_SEC Critical sections.
857 * @ingroup PJ_OS
858 * @{
859 * Critical section protection can be used to protect regions where:
860 * - mutual exclusion protection is needed.
861 * - it's rather too expensive to create a mutex.
862 * - the time spent in the region is very very brief.
863 *
864 * Critical section is a global object, and it prevents any threads from
865 * entering any regions that are protected by critical section once a thread
866 * is already in the section.
867 *
868 * Critial section is \a not recursive!
869 *
870 * Application <b>MUST NOT</b> call any functions that may cause current
871 * thread to block (such as allocating memory, performing I/O, locking mutex,
872 * etc.) while holding the critical section.
873 */
874/**
875 * Enter critical section.
876 */
877PJ_DECL(void) pj_enter_critical_section(void);
878
879/**
880 * Leave critical section.
881 */
882PJ_DECL(void) pj_leave_critical_section(void);
883
884/**
885 * @}
886 */
887
888/* **************************************************************************/
889#if defined(PJ_HAS_SEMAPHORE) && PJ_HAS_SEMAPHORE != 0
890/**
891 * @defgroup PJ_SEM Semaphores.
892 * @ingroup PJ_OS
893 * @{
894 *
895 * This module provides abstraction for semaphores, where available.
896 */
897
898/**
899 * Create semaphore.
900 *
901 * @param pool The pool.
902 * @param name Name to be assigned to the semaphore (for logging purpose)
903 * @param initial The initial count of the semaphore.
904 * @param max The maximum count of the semaphore.
905 * @param sem Pointer to hold the semaphore created.
906 *
907 * @return PJ_SUCCESS on success, or the error code.
908 */
909PJ_DECL(pj_status_t) pj_sem_create( pj_pool_t *pool,
910 const char *name,
911 unsigned initial,
912 unsigned max,
913 pj_sem_t **sem);
914
915/**
916 * Wait for semaphore.
917 *
918 * @param sem The semaphore.
919 *
920 * @return PJ_SUCCESS on success, or the error code.
921 */
922PJ_DECL(pj_status_t) pj_sem_wait(pj_sem_t *sem);
923
924/**
925 * Try wait for semaphore.
926 *
927 * @param sem The semaphore.
928 *
929 * @return PJ_SUCCESS on success, or the error code.
930 */
931PJ_DECL(pj_status_t) pj_sem_trywait(pj_sem_t *sem);
932
933/**
934 * Release semaphore.
935 *
936 * @param sem The semaphore.
937 *
938 * @return PJ_SUCCESS on success, or the error code.
939 */
940PJ_DECL(pj_status_t) pj_sem_post(pj_sem_t *sem);
941
942/**
943 * Destroy semaphore.
944 *
945 * @param sem The semaphore.
946 *
947 * @return PJ_SUCCESS on success, or the error code.
948 */
949PJ_DECL(pj_status_t) pj_sem_destroy(pj_sem_t *sem);
950
951/**
952 * @}
953 */
954#endif /* PJ_HAS_SEMAPHORE */
955
956
957/* **************************************************************************/
958#if defined(PJ_HAS_EVENT_OBJ) && PJ_HAS_EVENT_OBJ != 0
959/**
960 * @defgroup PJ_EVENT Event Object.
961 * @ingroup PJ_OS
962 * @{
963 *
964 * This module provides abstraction to event object (e.g. Win32 Event) where
965 * available. Event objects can be used for synchronization among threads.
966 */
967
968/**
969 * Create event object.
970 *
971 * @param pool The pool.
972 * @param name The name of the event object (for logging purpose).
973 * @param manual_reset Specify whether the event is manual-reset
974 * @param initial Specify the initial state of the event object.
975 * @param event Pointer to hold the returned event object.
976 *
977 * @return event handle, or NULL if failed.
978 */
979PJ_DECL(pj_status_t) pj_event_create(pj_pool_t *pool, const char *name,
980 pj_bool_t manual_reset, pj_bool_t initial,
981 pj_event_t **event);
982
983/**
984 * Wait for event to be signaled.
985 *
986 * @param event The event object.
987 *
988 * @return zero if successfull.
989 */
990PJ_DECL(pj_status_t) pj_event_wait(pj_event_t *event);
991
992/**
993 * Try wait for event object to be signalled.
994 *
995 * @param event The event object.
996 *
997 * @return zero if successfull.
998 */
999PJ_DECL(pj_status_t) pj_event_trywait(pj_event_t *event);
1000
1001/**
1002 * Set the event object state to signaled. For auto-reset event, this
1003 * will only release the first thread that are waiting on the event. For
1004 * manual reset event, the state remains signaled until the event is reset.
1005 * If there is no thread waiting on the event, the event object state
1006 * remains signaled.
1007 *
1008 * @param event The event object.
1009 *
1010 * @return zero if successfull.
1011 */
1012PJ_DECL(pj_status_t) pj_event_set(pj_event_t *event);
1013
1014/**
1015 * Set the event object to signaled state to release appropriate number of
1016 * waiting threads and then reset the event object to non-signaled. For
1017 * manual-reset event, this function will release all waiting threads. For
1018 * auto-reset event, this function will only release one waiting thread.
1019 *
1020 * @param event The event object.
1021 *
1022 * @return zero if successfull.
1023 */
1024PJ_DECL(pj_status_t) pj_event_pulse(pj_event_t *event);
1025
1026/**
1027 * Set the event object state to non-signaled.
1028 *
1029 * @param event The event object.
1030 *
1031 * @return zero if successfull.
1032 */
1033PJ_DECL(pj_status_t) pj_event_reset(pj_event_t *event);
1034
1035/**
1036 * Destroy the event object.
1037 *
1038 * @param event The event object.
1039 *
1040 * @return zero if successfull.
1041 */
1042PJ_DECL(pj_status_t) pj_event_destroy(pj_event_t *event);
1043
1044/**
1045 * @}
1046 */
1047#endif /* PJ_HAS_EVENT_OBJ */
1048
1049/* **************************************************************************/
1050/**
1051 * @addtogroup PJ_TIME Time Data Type and Manipulation.
1052 * @ingroup PJ_OS
1053 * @{
1054 * This module provides API for manipulating time.
1055 *
1056 * \section pj_time_examples_sec Examples
1057 *
1058 * For examples, please see:
1059 * - \ref page_pjlib_sleep_test
1060 */
1061
1062/**
1063 * Get current time of day in local representation.
1064 *
1065 * @param tv Variable to store the result.
1066 *
1067 * @return zero if successfull.
1068 */
1069PJ_DECL(pj_status_t) pj_gettimeofday(pj_time_val *tv);
1070
1071
1072/**
1073 * Parse time value into date/time representation.
1074 *
1075 * @param tv The time.
1076 * @param pt Variable to store the date time result.
1077 *
1078 * @return zero if successfull.
1079 */
1080PJ_DECL(pj_status_t) pj_time_decode(const pj_time_val *tv, pj_parsed_time *pt);
1081
1082/**
1083 * Encode date/time to time value.
1084 *
1085 * @param pt The date/time.
1086 * @param tv Variable to store time value result.
1087 *
1088 * @return zero if successfull.
1089 */
1090PJ_DECL(pj_status_t) pj_time_encode(const pj_parsed_time *pt, pj_time_val *tv);
1091
1092/**
1093 * Convert local time to GMT.
1094 *
1095 * @param tv Time to convert.
1096 *
1097 * @return zero if successfull.
1098 */
1099PJ_DECL(pj_status_t) pj_time_local_to_gmt(pj_time_val *tv);
1100
1101/**
1102 * Convert GMT to local time.
1103 *
1104 * @param tv Time to convert.
1105 *
1106 * @return zero if successfull.
1107 */
1108PJ_DECL(pj_status_t) pj_time_gmt_to_local(pj_time_val *tv);
1109
1110/**
1111 * @}
1112 */
1113
1114/* **************************************************************************/
1115#if defined(PJ_TERM_HAS_COLOR) && PJ_TERM_HAS_COLOR != 0
1116
1117/**
1118 * @defgroup PJ_TERM Terminal
1119 * @ingroup PJ_OS
1120 * @{
1121 */
1122
1123/**
1124 * Set current terminal color.
1125 *
1126 * @param color The RGB color.
1127 *
1128 * @return zero on success.
1129 */
1130PJ_DECL(pj_status_t) pj_term_set_color(pj_color_t color);
1131
1132/**
1133 * Get current terminal foreground color.
1134 *
1135 * @return RGB color.
1136 */
1137PJ_DECL(pj_color_t) pj_term_get_color(void);
1138
1139/**
1140 * @}
1141 */
1142
1143#endif /* PJ_TERM_HAS_COLOR */
1144
1145/* **************************************************************************/
1146/**
1147 * @defgroup PJ_TIMESTAMP High Resolution Timestamp
1148 * @ingroup PJ_OS
1149 * @{
1150 *
1151 * PJLIB provides <b>High Resolution Timestamp</b> API to access highest
1152 * resolution timestamp value provided by the platform. The API is usefull
1153 * to measure precise elapsed time, and can be used in applications such
1154 * as profiling.
1155 *
1156 * The timestamp value is represented in cycles, and can be related to
1157 * normal time (in seconds or sub-seconds) using various functions provided.
1158 *
1159 * \section pj_timestamp_examples_sec Examples
1160 *
1161 * For examples, please see:
1162 * - \ref page_pjlib_sleep_test
1163 * - \ref page_pjlib_timestamp_test
1164 */
1165
1166/*
1167 * High resolution timer.
1168 */
1169#if defined(PJ_HAS_HIGH_RES_TIMER) && PJ_HAS_HIGH_RES_TIMER != 0
1170
1171/**
1172 * Get monotonic time since some unspecified starting point.
1173 *
1174 * @param tv Variable to store the result.
1175 *
1176 * @return PJ_SUCCESS if successful.
1177 */
1178PJ_DECL(pj_status_t) pj_gettickcount(pj_time_val *tv);
1179
1180/**
1181 * Acquire high resolution timer value. The time value are stored
1182 * in cycles.
1183 *
1184 * @param ts High resolution timer value.
1185 * @return PJ_SUCCESS or the appropriate error code.
1186 *
1187 * @see pj_get_timestamp_freq().
1188 */
1189PJ_DECL(pj_status_t) pj_get_timestamp(pj_timestamp *ts);
1190
1191/**
1192 * Get high resolution timer frequency, in cycles per second.
1193 *
1194 * @param freq Timer frequency, in cycles per second.
1195 * @return PJ_SUCCESS or the appropriate error code.
1196 */
1197PJ_DECL(pj_status_t) pj_get_timestamp_freq(pj_timestamp *freq);
1198
1199/**
1200 * Set timestamp from 32bit values.
1201 * @param t The timestamp to be set.
1202 * @param hi The high 32bit part.
1203 * @param lo The low 32bit part.
1204 */
1205PJ_INLINE(void) pj_set_timestamp32(pj_timestamp *t, pj_uint32_t hi,
1206 pj_uint32_t lo)
1207{
1208 t->u32.hi = hi;
1209 t->u32.lo = lo;
1210}
1211
1212
1213/**
1214 * Compare timestamp t1 and t2.
1215 * @param t1 t1.
1216 * @param t2 t2.
1217 * @return -1 if (t1 < t2), 1 if (t1 > t2), or 0 if (t1 == t2)
1218 */
1219PJ_INLINE(int) pj_cmp_timestamp(const pj_timestamp *t1, const pj_timestamp *t2)
1220{
1221#if PJ_HAS_INT64
1222 if (t1->u64 < t2->u64)
1223 return -1;
1224 else if (t1->u64 > t2->u64)
1225 return 1;
1226 else
1227 return 0;
1228#else
1229 if (t1->u32.hi < t2->u32.hi ||
1230 (t1->u32.hi == t2->u32.hi && t1->u32.lo < t2->u32.lo))
1231 return -1;
1232 else if (t1->u32.hi > t2->u32.hi ||
1233 (t1->u32.hi == t2->u32.hi && t1->u32.lo > t2->u32.lo))
1234 return 1;
1235 else
1236 return 0;
1237#endif
1238}
1239
1240
1241/**
1242 * Add timestamp t2 to t1.
1243 * @param t1 t1.
1244 * @param t2 t2.
1245 */
1246PJ_INLINE(void) pj_add_timestamp(pj_timestamp *t1, const pj_timestamp *t2)
1247{
1248#if PJ_HAS_INT64
1249 t1->u64 += t2->u64;
1250#else
1251 pj_uint32_t old = t1->u32.lo;
1252 t1->u32.hi += t2->u32.hi;
1253 t1->u32.lo += t2->u32.lo;
1254 if (t1->u32.lo < old)
1255 ++t1->u32.hi;
1256#endif
1257}
1258
1259/**
1260 * Add timestamp t2 to t1.
1261 * @param t1 t1.
1262 * @param t2 t2.
1263 */
1264PJ_INLINE(void) pj_add_timestamp32(pj_timestamp *t1, pj_uint32_t t2)
1265{
1266#if PJ_HAS_INT64
1267 t1->u64 += t2;
1268#else
1269 pj_uint32_t old = t1->u32.lo;
1270 t1->u32.lo += t2;
1271 if (t1->u32.lo < old)
1272 ++t1->u32.hi;
1273#endif
1274}
1275
1276/**
1277 * Substract timestamp t2 from t1.
1278 * @param t1 t1.
1279 * @param t2 t2.
1280 */
1281PJ_INLINE(void) pj_sub_timestamp(pj_timestamp *t1, const pj_timestamp *t2)
1282{
1283#if PJ_HAS_INT64
1284 t1->u64 -= t2->u64;
1285#else
1286 t1->u32.hi -= t2->u32.hi;
1287 if (t1->u32.lo >= t2->u32.lo)
1288 t1->u32.lo -= t2->u32.lo;
1289 else {
1290 t1->u32.lo -= t2->u32.lo;
1291 --t1->u32.hi;
1292 }
1293#endif
1294}
1295
1296/**
1297 * Substract timestamp t2 from t1.
1298 * @param t1 t1.
1299 * @param t2 t2.
1300 */
1301PJ_INLINE(void) pj_sub_timestamp32(pj_timestamp *t1, pj_uint32_t t2)
1302{
1303#if PJ_HAS_INT64
1304 t1->u64 -= t2;
1305#else
1306 if (t1->u32.lo >= t2)
1307 t1->u32.lo -= t2;
1308 else {
1309 t1->u32.lo -= t2;
1310 --t1->u32.hi;
1311 }
1312#endif
1313}
1314
1315/**
1316 * Get the timestamp difference between t2 and t1 (that is t2 minus t1),
1317 * and return a 32bit signed integer difference.
1318 */
1319PJ_INLINE(pj_int32_t) pj_timestamp_diff32(const pj_timestamp *t1,
1320 const pj_timestamp *t2)
1321{
1322 /* Be careful with the signess (I think!) */
1323#if PJ_HAS_INT64
1324 pj_int64_t diff = t2->u64 - t1->u64;
1325 return (pj_int32_t) diff;
1326#else
1327 pj_int32 diff = t2->u32.lo - t1->u32.lo;
1328 return diff;
1329#endif
1330}
1331
1332
1333/**
1334 * Calculate the elapsed time, and store it in pj_time_val.
1335 * This function calculates the elapsed time using highest precision
1336 * calculation that is available for current platform, considering
1337 * whether floating point or 64-bit precision arithmetic is available.
1338 * For maximum portability, application should prefer to use this function
1339 * rather than calculating the elapsed time by itself.
1340 *
1341 * @param start The starting timestamp.
1342 * @param stop The end timestamp.
1343 *
1344 * @return Elapsed time as #pj_time_val.
1345 *
1346 * @see pj_elapsed_usec(), pj_elapsed_cycle(), pj_elapsed_nanosec()
1347 */
1348PJ_DECL(pj_time_val) pj_elapsed_time( const pj_timestamp *start,
1349 const pj_timestamp *stop );
1350
1351/**
1352 * Calculate the elapsed time as 32-bit miliseconds.
1353 * This function calculates the elapsed time using highest precision
1354 * calculation that is available for current platform, considering
1355 * whether floating point or 64-bit precision arithmetic is available.
1356 * For maximum portability, application should prefer to use this function
1357 * rather than calculating the elapsed time by itself.
1358 *
1359 * @param start The starting timestamp.
1360 * @param stop The end timestamp.
1361 *
1362 * @return Elapsed time in milisecond.
1363 *
1364 * @see pj_elapsed_time(), pj_elapsed_cycle(), pj_elapsed_nanosec()
1365 */
1366PJ_DECL(pj_uint32_t) pj_elapsed_msec( const pj_timestamp *start,
1367 const pj_timestamp *stop );
1368
1369/**
1370 * Variant of #pj_elapsed_msec() which returns 64bit value.
1371 */
1372PJ_DECL(pj_uint64_t) pj_elapsed_msec64(const pj_timestamp *start,
1373 const pj_timestamp *stop );
1374
1375/**
1376 * Calculate the elapsed time in 32-bit microseconds.
1377 * This function calculates the elapsed time using highest precision
1378 * calculation that is available for current platform, considering
1379 * whether floating point or 64-bit precision arithmetic is available.
1380 * For maximum portability, application should prefer to use this function
1381 * rather than calculating the elapsed time by itself.
1382 *
1383 * @param start The starting timestamp.
1384 * @param stop The end timestamp.
1385 *
1386 * @return Elapsed time in microsecond.
1387 *
1388 * @see pj_elapsed_time(), pj_elapsed_cycle(), pj_elapsed_nanosec()
1389 */
1390PJ_DECL(pj_uint32_t) pj_elapsed_usec( const pj_timestamp *start,
1391 const pj_timestamp *stop );
1392
1393/**
1394 * Calculate the elapsed time in 32-bit nanoseconds.
1395 * This function calculates the elapsed time using highest precision
1396 * calculation that is available for current platform, considering
1397 * whether floating point or 64-bit precision arithmetic is available.
1398 * For maximum portability, application should prefer to use this function
1399 * rather than calculating the elapsed time by itself.
1400 *
1401 * @param start The starting timestamp.
1402 * @param stop The end timestamp.
1403 *
1404 * @return Elapsed time in nanoseconds.
1405 *
1406 * @see pj_elapsed_time(), pj_elapsed_cycle(), pj_elapsed_usec()
1407 */
1408PJ_DECL(pj_uint32_t) pj_elapsed_nanosec( const pj_timestamp *start,
1409 const pj_timestamp *stop );
1410
1411/**
1412 * Calculate the elapsed time in 32-bit cycles.
1413 * This function calculates the elapsed time using highest precision
1414 * calculation that is available for current platform, considering
1415 * whether floating point or 64-bit precision arithmetic is available.
1416 * For maximum portability, application should prefer to use this function
1417 * rather than calculating the elapsed time by itself.
1418 *
1419 * @param start The starting timestamp.
1420 * @param stop The end timestamp.
1421 *
1422 * @return Elapsed time in cycles.
1423 *
1424 * @see pj_elapsed_usec(), pj_elapsed_time(), pj_elapsed_nanosec()
1425 */
1426PJ_DECL(pj_uint32_t) pj_elapsed_cycle( const pj_timestamp *start,
1427 const pj_timestamp *stop );
1428
1429
1430#endif /* PJ_HAS_HIGH_RES_TIMER */
1431
1432/** @} */
1433
1434
1435/* **************************************************************************/
1436/**
1437 * @defgroup PJ_APP_OS Application execution
1438 * @ingroup PJ_OS
1439 * @{
1440 */
1441
1442/* Type for main function. */
1443typedef int (*pj_main_func_ptr)(int argc, char *argv[]);
1444
1445/**
1446 * Run the application. This function has to be called in the main thread
1447 * and after doing the necessary initialization according to the flags
1448 * provided, it will call main_func() function.
1449 *
1450 * @param main_func Application's main function.
1451 * @param argc Number of arguments from the main() function, which
1452 * will be passed to main_func() function.
1453 * @param argv The arguments from the main() function, which will
1454 * be passed to main_func() function.
1455 * @param flags Flags for application execution, currently must be 0.
1456 *
1457 * @return main_func()'s return value.
1458 */
1459int pj_run_app(pj_main_func_ptr main_func, int argc, char *argv[],
1460 unsigned flags);
1461
1462/** @} */
1463
1464
1465/* **************************************************************************/
1466/**
1467 * Internal PJLIB function to initialize the threading subsystem.
1468 * @return PJ_SUCCESS or the appropriate error code.
1469 */
1470pj_status_t pj_thread_init(void);
1471
1472
1473PJ_END_DECL
1474
1475#endif /* __PJ_OS_H__ */
1476