~ubuntu-branches/ubuntu/wily/sflphone/wily

« back to all changes in this revision

Viewing changes to daemon/libs/pjproject-2.0.1/pjlib/include/pj/os.h

  • Committer: Package Import Robot
  • Author(s): Mark Purcell
  • Date: 2014-01-28 18:23:36 UTC
  • mfrom: (1.1.11)
  • mto: This revision was merged to the branch mainline in revision 24.
  • Revision ID: package-import@ubuntu.com-20140128182336-3xenud1kbnwmf3mz
* New upstream release 
  - Fixes "New Upstream Release" (Closes: #735846)
  - Fixes "Ringtone does not stop" (Closes: #727164)
  - Fixes "[sflphone-kde] crash on startup" (Closes: #718178)
  - Fixes "sflphone GUI crashes when call is hung up" (Closes: #736583)
* Build-Depends: ensure GnuTLS 2.6
  - libucommon-dev (>= 6.0.7-1.1), libccrtp-dev (>= 2.0.6-3)
  - Fixes "FTBFS Build-Depends libgnutls{26,28}-dev" (Closes: #722040)
* Fix "boost 1.49 is going away" unversioned Build-Depends: (Closes: #736746)
* Add Build-Depends: libsndfile-dev, nepomuk-core-dev

Show diffs side-by-side

added added

removed removed

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