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