Coverage Report

Created: 2024-07-23 06:24

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