Coverage Report

Created: 2025-10-28 06:39

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