Benny Prijono | 0a749f1 | 2005-10-31 21:02:30 +0000 | [diff] [blame^] | 1 | /* $Header: /pjproject-0.3/pjlib/include/pj/os.h 12 10/29/05 11:30a Bennylp $ */
|
| 2 |
|
| 3 | #ifndef __PJ_OS_H__
|
| 4 | #define __PJ_OS_H__
|
| 5 |
|
| 6 | /**
|
| 7 | * @file os.h
|
| 8 | * @brief OS dependent functions
|
| 9 | */
|
| 10 | #include <pj/types.h>
|
| 11 |
|
| 12 | PJ_BEGIN_DECL
|
| 13 |
|
| 14 | /**
|
| 15 | * @defgroup PJ_OS Operating System Dependent Functionality.
|
| 16 | * @ingroup PJ
|
| 17 | */
|
| 18 |
|
| 19 |
|
| 20 | ///////////////////////////////////////////////////////////////////////////////
|
| 21 | /**
|
| 22 | * @defgroup PJ_THREAD Threads
|
| 23 | * @ingroup PJ_OS
|
| 24 | * @{
|
| 25 | * This module provides multithreading API.
|
| 26 | *
|
| 27 | * \section pj_thread_examples_sec Examples
|
| 28 | *
|
| 29 | * For examples, please see:
|
| 30 | * - \ref page_pjlib_thread_test
|
| 31 | * - \ref page_pjlib_sleep_test
|
| 32 | *
|
| 33 | */
|
| 34 |
|
| 35 | /**
|
| 36 | * Thread creation flags:
|
| 37 | * - PJ_THREAD_SUSPENDED: specify that the thread should be created suspended.
|
| 38 | */
|
| 39 | typedef enum pj_thread_create_flags
|
| 40 | {
|
| 41 | PJ_THREAD_SUSPENDED = 1
|
| 42 | } pj_thread_create_flags;
|
| 43 |
|
| 44 |
|
| 45 | /**
|
| 46 | * Specify this as \a stack_size argument in #pj_thread_create() to specify
|
| 47 | * that thread should use default stack size for the current platform.
|
| 48 | */
|
| 49 | #define PJ_THREAD_DEFAULT_STACK_SIZE 0
|
| 50 |
|
| 51 | /**
|
| 52 | * Type of thread entry function.
|
| 53 | */
|
| 54 | typedef int (PJ_THREAD_FUNC pj_thread_proc)(void*);
|
| 55 |
|
| 56 | /**
|
| 57 | * Size of thread struct.
|
| 58 | */
|
| 59 | #if !defined(PJ_THREAD_DESC_SIZE)
|
| 60 | # define PJ_THREAD_DESC_SIZE (PJ_MAX_OBJ_NAME + 10*sizeof(long))
|
| 61 | #endif
|
| 62 |
|
| 63 | /**
|
| 64 | * Thread structure, to thread's state when the thread is created by external
|
| 65 | * or native API.
|
| 66 | */
|
| 67 | typedef pj_uint8_t pj_thread_desc[PJ_THREAD_DESC_SIZE];
|
| 68 |
|
| 69 | /**
|
| 70 | * Get process ID.
|
| 71 | * @return process ID.
|
| 72 | */
|
| 73 | PJ_DECL(pj_uint32_t) pj_getpid(void);
|
| 74 |
|
| 75 | /**
|
| 76 | * Create a new thread.
|
| 77 | *
|
| 78 | * @param pool The memory pool from which the thread record
|
| 79 | * will be allocated from.
|
| 80 | * @param thread_name The optional name to be assigned to the thread.
|
| 81 | * @param proc Thread entry function.
|
| 82 | * @param arg Argument to be passed to the thread entry function.
|
| 83 | * @param stack_size The size of the stack for the new thread, or ZERO or
|
| 84 | * PJ_THREAD_DEFAULT_STACK_SIZE to let the
|
| 85 | * library choose the reasonable size for the stack.
|
| 86 | * For some systems, the stack will be allocated from
|
| 87 | * the pool, so the pool must have suitable capacity.
|
| 88 | * @param flags Flags for thread creation, which is bitmask combination
|
| 89 | * from enum pj_thread_create_flags.
|
| 90 | * @param thread Pointer to hold the newly created thread.
|
| 91 | *
|
| 92 | * @return PJ_SUCCESS on success, or the error code.
|
| 93 | */
|
| 94 | PJ_DECL(pj_status_t) pj_thread_create( pj_pool_t *pool,
|
| 95 | const char *thread_name,
|
| 96 | pj_thread_proc *proc,
|
| 97 | void *arg,
|
| 98 | pj_size_t stack_size,
|
| 99 | unsigned flags,
|
| 100 | pj_thread_t **thread );
|
| 101 |
|
| 102 | /**
|
| 103 | * Register a thread that was created by external or native API to PJLIB.
|
| 104 | * This function must be called in the context of the thread being registered.
|
| 105 | * When the thread is created by external function or API call,
|
| 106 | * it must be 'registered' to PJLIB using pj_thread_register(), so that it can
|
| 107 | * cooperate with PJLIB's framework. During registration, some data needs to
|
| 108 | * be maintained, and this data must remain available during the thread's
|
| 109 | * lifetime.
|
| 110 | *
|
| 111 | * @param thread_name The optional name to be assigned to the thread.
|
| 112 | * @param desc Thread descriptor, which must be available throughout
|
| 113 | * the lifetime of the thread.
|
| 114 | * @param thread Pointer to hold the created thread handle.
|
| 115 | *
|
| 116 | * @return PJ_SUCCESS on success, or the error code.
|
| 117 | */
|
| 118 | PJ_DECL(pj_status_t) pj_thread_register ( const char *thread_name,
|
| 119 | pj_thread_desc desc,
|
| 120 | pj_thread_t **thread);
|
| 121 |
|
| 122 | /**
|
| 123 | * Get thread name.
|
| 124 | *
|
| 125 | * @param thread The thread handle.
|
| 126 | *
|
| 127 | * @return Thread name as null terminated string.
|
| 128 | */
|
| 129 | PJ_DECL(const char*) pj_thread_get_name(pj_thread_t *thread);
|
| 130 |
|
| 131 | /**
|
| 132 | * Resume a suspended thread.
|
| 133 | *
|
| 134 | * @param thread The thread handle.
|
| 135 | *
|
| 136 | * @return zero on success.
|
| 137 | */
|
| 138 | PJ_DECL(pj_status_t) pj_thread_resume(pj_thread_t *thread);
|
| 139 |
|
| 140 | /**
|
| 141 | * Get the current thread.
|
| 142 | *
|
| 143 | * @return Thread handle of current thread.
|
| 144 | */
|
| 145 | PJ_DECL(pj_thread_t*) pj_thread_this(void);
|
| 146 |
|
| 147 | /**
|
| 148 | * Join thread.
|
| 149 | * This function will block the caller thread until the specified thread exits.
|
| 150 | *
|
| 151 | * @param thread The thread handle.
|
| 152 | *
|
| 153 | * @return zero on success.
|
| 154 | */
|
| 155 | PJ_DECL(pj_status_t) pj_thread_join(pj_thread_t *thread);
|
| 156 |
|
| 157 |
|
| 158 | /**
|
| 159 | * Destroy thread and release resources allocated for the thread.
|
| 160 | * However, the memory allocated for the pj_thread_t itself will only be released
|
| 161 | * when the pool used to create the thread is destroyed.
|
| 162 | *
|
| 163 | * @param thread The thread handle.
|
| 164 | *
|
| 165 | * @return zero on success.
|
| 166 | */
|
| 167 | PJ_DECL(pj_status_t) pj_thread_destroy(pj_thread_t *thread);
|
| 168 |
|
| 169 |
|
| 170 | /**
|
| 171 | * Put the current thread to sleep for the specified miliseconds.
|
| 172 | *
|
| 173 | * @param msec Miliseconds delay.
|
| 174 | *
|
| 175 | * @return zero if successfull.
|
| 176 | */
|
| 177 | PJ_DECL(pj_status_t) pj_thread_sleep(unsigned msec);
|
| 178 |
|
| 179 | /**
|
| 180 | * @def PJ_CHECK_STACK()
|
| 181 | * PJ_CHECK_STACK() macro is used to check the sanity of the stack.
|
| 182 | * The OS implementation may check that no stack overflow occurs, and
|
| 183 | * it also may collect statistic about stack usage.
|
| 184 | */
|
| 185 | #if defined(PJ_OS_HAS_CHECK_STACK) && PJ_OS_HAS_CHECK_STACK!=0
|
| 186 |
|
| 187 | # define PJ_CHECK_STACK() pj_thread_check_stack(__FILE__, __LINE__)
|
| 188 |
|
| 189 | /** @internal
|
| 190 | * The implementation of stack checking.
|
| 191 | */
|
| 192 | PJ_DECL(void) pj_thread_check_stack(const char *file, int line);
|
| 193 |
|
| 194 | /** @internal
|
| 195 | * Get maximum stack usage statistic.
|
| 196 | */
|
| 197 | PJ_DECL(pj_uint32_t) pj_thread_get_stack_max_usage(pj_thread_t *thread);
|
| 198 |
|
| 199 | /** @internal
|
| 200 | * Dump thread stack status.
|
| 201 | */
|
| 202 | PJ_DECL(pj_status_t) pj_thread_get_stack_info(pj_thread_t *thread,
|
| 203 | const char **file,
|
| 204 | int *line);
|
| 205 | #else
|
| 206 |
|
| 207 | # define PJ_CHECK_STACK()
|
| 208 | /** pj_thread_get_stack_max_usage() for the thread */
|
| 209 | # define pj_thread_get_stack_max_usage(thread) 0
|
| 210 | /** pj_thread_get_stack_info() for the thread */
|
| 211 | # define pj_thread_get_stack_info(thread,f,l) (*(f)="",*(l)=0)
|
| 212 | #endif /* PJ_OS_HAS_CHECK_STACK */
|
| 213 |
|
| 214 | /**
|
| 215 | * @}
|
| 216 | */
|
| 217 |
|
| 218 | ///////////////////////////////////////////////////////////////////////////////
|
| 219 | /**
|
| 220 | * @defgroup PJ_TLS Thread Local Storage.
|
| 221 | * @ingroup PJ_OS
|
| 222 | * @{
|
| 223 | */
|
| 224 |
|
| 225 | /**
|
| 226 | * Allocate thread local storage index. The initial value of the variable at
|
| 227 | * the index is zero.
|
| 228 | *
|
| 229 | * @param index Pointer to hold the return value.
|
| 230 | * @return PJ_SUCCESS on success, or the error code.
|
| 231 | */
|
| 232 | PJ_DECL(pj_status_t) pj_thread_local_alloc(long *index);
|
| 233 |
|
| 234 | /**
|
| 235 | * Deallocate thread local variable.
|
| 236 | *
|
| 237 | * @param index The variable index.
|
| 238 | */
|
| 239 | PJ_DECL(void) pj_thread_local_free(long index);
|
| 240 |
|
| 241 | /**
|
| 242 | * Set the value of thread local variable.
|
| 243 | *
|
| 244 | * @param index The index of the variable.
|
| 245 | * @param value The value.
|
| 246 | */
|
| 247 | PJ_DECL(void) pj_thread_local_set(long index, void *value);
|
| 248 |
|
| 249 | /**
|
| 250 | * Get the value of thread local variable.
|
| 251 | *
|
| 252 | * @param index The index of the variable.
|
| 253 | * @return The value.
|
| 254 | */
|
| 255 | PJ_DECL(void*) pj_thread_local_get(long index);
|
| 256 |
|
| 257 |
|
| 258 | /**
|
| 259 | * @}
|
| 260 | */
|
| 261 |
|
| 262 |
|
| 263 | ///////////////////////////////////////////////////////////////////////////////
|
| 264 | /**
|
| 265 | * @defgroup PJ_ATOMIC Atomic Variables
|
| 266 | * @ingroup PJ_OS
|
| 267 | * @{
|
| 268 | *
|
| 269 | * This module provides API to manipulate atomic variables.
|
| 270 | *
|
| 271 | * \section pj_atomic_examples_sec Examples
|
| 272 | *
|
| 273 | * For some example codes, please see:
|
| 274 | * - @ref page_pjlib_atomic_test
|
| 275 | */
|
| 276 |
|
| 277 |
|
| 278 | /**
|
| 279 | * Create atomic variable.
|
| 280 | *
|
| 281 | * @param pool The pool.
|
| 282 | * @param initial The initial value of the atomic variable.
|
| 283 | * @param atomic Pointer to hold the atomic variable upon return.
|
| 284 | *
|
| 285 | * @return PJ_SUCCESS on success, or the error code.
|
| 286 | */
|
| 287 | PJ_DECL(pj_status_t) pj_atomic_create( pj_pool_t *pool,
|
| 288 | pj_atomic_value_t initial,
|
| 289 | pj_atomic_t **atomic );
|
| 290 |
|
| 291 | /**
|
| 292 | * Destroy atomic variable.
|
| 293 | *
|
| 294 | * @param atomic_var the atomic variable.
|
| 295 | *
|
| 296 | * @return PJ_SUCCESS if success.
|
| 297 | */
|
| 298 | PJ_DECL(pj_status_t) pj_atomic_destroy( pj_atomic_t *atomic_var );
|
| 299 |
|
| 300 | /**
|
| 301 | * Set the value of an atomic type, and return the previous value.
|
| 302 | *
|
| 303 | * @param atomic_var the atomic variable.
|
| 304 | * @param value value to be set to the variable.
|
| 305 | *
|
| 306 | * @return the previous value of the variable.
|
| 307 | */
|
| 308 | PJ_DECL(pj_atomic_value_t) pj_atomic_set(pj_atomic_t *atomic_var,
|
| 309 | pj_atomic_value_t value);
|
| 310 |
|
| 311 | /**
|
| 312 | * Get the value of an atomic type.
|
| 313 | *
|
| 314 | * @param atomic_var the atomic variable.
|
| 315 | *
|
| 316 | * @return the value of the atomic variable.
|
| 317 | */
|
| 318 | PJ_DECL(pj_atomic_value_t) pj_atomic_get(pj_atomic_t *atomic_var);
|
| 319 |
|
| 320 | /**
|
| 321 | * Increment the value of an atomic type.
|
| 322 | *
|
| 323 | * @param atomic_var the atomic variable.
|
| 324 | *
|
| 325 | * @return the result.
|
| 326 | */
|
| 327 | PJ_DECL(pj_atomic_value_t) pj_atomic_inc(pj_atomic_t *atomic_var);
|
| 328 |
|
| 329 | /**
|
| 330 | * Decrement the value of an atomic type.
|
| 331 | *
|
| 332 | * @param atomic_var the atomic variable.
|
| 333 | *
|
| 334 | * @return the result.
|
| 335 | */
|
| 336 | PJ_DECL(pj_atomic_value_t) pj_atomic_dec(pj_atomic_t *atomic_var);
|
| 337 |
|
| 338 | /**
|
| 339 | * @}
|
| 340 | */
|
| 341 |
|
| 342 | ///////////////////////////////////////////////////////////////////////////////
|
| 343 | /**
|
| 344 | * @defgroup PJ_MUTEX Mutexes.
|
| 345 | * @ingroup PJ_OS
|
| 346 | * @{
|
| 347 | *
|
| 348 | * Mutex manipulation. Alternatively, application can use higher abstraction
|
| 349 | * for lock objects, which provides uniform API for all kinds of lock
|
| 350 | * mechanisms, including mutex. See @ref PJ_LOCK for more information.
|
| 351 | */
|
| 352 |
|
| 353 | /**
|
| 354 | * Mutex types:
|
| 355 | * - PJ_MUTEX_DEFAULT: default mutex type, which is system dependent.
|
| 356 | * - PJ_MUTEX_SIMPLE: non-recursive mutex.
|
| 357 | * - PJ_MUTEX_RECURSIVE: recursive mutex.
|
| 358 | */
|
| 359 | typedef enum pj_mutex_type_e
|
| 360 | {
|
| 361 | PJ_MUTEX_DEFAULT,
|
| 362 | PJ_MUTEX_SIMPLE,
|
| 363 | PJ_MUTEX_RECURSE,
|
| 364 | } pj_mutex_type_e;
|
| 365 |
|
| 366 |
|
| 367 | /**
|
| 368 | * Create mutex of the specified type.
|
| 369 | *
|
| 370 | * @param pool The pool.
|
| 371 | * @param name Name to be associated with the mutex (for debugging).
|
| 372 | * @param type The type of the mutex, of type #pj_mutex_type_e.
|
| 373 | * @param mutex Pointer to hold the returned mutex instance.
|
| 374 | *
|
| 375 | * @return PJ_SUCCESS on success, or the error code.
|
| 376 | */
|
| 377 | PJ_DECL(pj_status_t) pj_mutex_create(pj_pool_t *pool,
|
| 378 | const char *name,
|
| 379 | int type,
|
| 380 | pj_mutex_t **mutex);
|
| 381 |
|
| 382 | /**
|
| 383 | * Create simple, non-recursive mutex.
|
| 384 | * This function is a simple wrapper for #pj_mutex_create to create
|
| 385 | * non-recursive mutex.
|
| 386 | *
|
| 387 | * @param pool The pool.
|
| 388 | * @param name Mutex name.
|
| 389 | * @param mutex Pointer to hold the returned mutex instance.
|
| 390 | *
|
| 391 | * @return PJ_SUCCESS on success, or the error code.
|
| 392 | */
|
| 393 | PJ_DECL(pj_status_t) pj_mutex_create_simple( pj_pool_t *pool, const char *name,
|
| 394 | pj_mutex_t **mutex );
|
| 395 |
|
| 396 | /**
|
| 397 | * Create recursive mutex.
|
| 398 | * This function is a simple wrapper for #pj_mutex_create to create
|
| 399 | * recursive mutex.
|
| 400 | *
|
| 401 | * @param pool The pool.
|
| 402 | * @param name Mutex name.
|
| 403 | * @param mutex Pointer to hold the returned mutex instance.
|
| 404 | *
|
| 405 | * @return PJ_SUCCESS on success, or the error code.
|
| 406 | */
|
| 407 | PJ_DECL(pj_status_t) pj_mutex_create_recursive( pj_pool_t *pool,
|
| 408 | const char *name,
|
| 409 | pj_mutex_t **mutex );
|
| 410 |
|
| 411 | /**
|
| 412 | * Acquire mutex lock.
|
| 413 | *
|
| 414 | * @param mutex The mutex.
|
| 415 | * @return PJ_SUCCESS on success, or the error code.
|
| 416 | */
|
| 417 | PJ_DECL(pj_status_t) pj_mutex_lock(pj_mutex_t *mutex);
|
| 418 |
|
| 419 | /**
|
| 420 | * Release mutex lock.
|
| 421 | *
|
| 422 | * @param mutex The mutex.
|
| 423 | * @return PJ_SUCCESS on success, or the error code.
|
| 424 | */
|
| 425 | PJ_DECL(pj_status_t) pj_mutex_unlock(pj_mutex_t *mutex);
|
| 426 |
|
| 427 | /**
|
| 428 | * Try to acquire mutex lock.
|
| 429 | *
|
| 430 | * @param mutex The mutex.
|
| 431 | * @return PJ_SUCCESS on success, or the error code if the
|
| 432 | * lock couldn't be acquired.
|
| 433 | */
|
| 434 | PJ_DECL(pj_status_t) pj_mutex_trylock(pj_mutex_t *mutex);
|
| 435 |
|
| 436 | /**
|
| 437 | * Destroy mutex.
|
| 438 | *
|
| 439 | * @param mutex Te mutex.
|
| 440 | * @return PJ_SUCCESS on success, or the error code.
|
| 441 | */
|
| 442 | PJ_DECL(pj_status_t) pj_mutex_destroy(pj_mutex_t *mutex);
|
| 443 |
|
| 444 | /**
|
| 445 | * Determine whether calling thread is owning the mutex (only available when
|
| 446 | * PJ_DEBUG is set).
|
| 447 | * @param mutex The mutex.
|
| 448 | * @return Non-zero if yes.
|
| 449 | */
|
| 450 | #if defined(PJ_DEBUG) && PJ_DEBUG != 0
|
| 451 | PJ_DECL(pj_bool_t) pj_mutex_is_locked(pj_mutex_t *mutex);
|
| 452 | #else
|
| 453 | # define pj_mutex_is_locked(mutex) 1
|
| 454 | #endif
|
| 455 |
|
| 456 | /**
|
| 457 | * @}
|
| 458 | */
|
| 459 |
|
| 460 | ///////////////////////////////////////////////////////////////////////////////
|
| 461 | /**
|
| 462 | * @defgroup PJ_CRIT_SEC Critical sections.
|
| 463 | * @ingroup PJ_OS
|
| 464 | * @{
|
| 465 | * Critical section protection can be used to protect regions where:
|
| 466 | * - mutual exclusion protection is needed.
|
| 467 | * - it's rather too expensive to create a mutex.
|
| 468 | * - the time spent in the region is very very brief.
|
| 469 | *
|
| 470 | * Critical section is a global object, and it prevents any threads from
|
| 471 | * entering any regions that are protected by critical section once a thread
|
| 472 | * is already in the section.
|
| 473 | *
|
| 474 | * Critial section is \a not recursive!
|
| 475 | *
|
| 476 | * Application <b>MUST NOT</b> call any functions that may cause current
|
| 477 | * thread to block (such as allocating memory, performing I/O, locking mutex,
|
| 478 | * etc.) while holding the critical section.
|
| 479 | */
|
| 480 | /**
|
| 481 | * Enter critical section.
|
| 482 | */
|
| 483 | PJ_DECL(void) pj_enter_critical_section(void);
|
| 484 |
|
| 485 | /**
|
| 486 | * Leave critical section.
|
| 487 | */
|
| 488 | PJ_DECL(void) pj_leave_critical_section(void);
|
| 489 |
|
| 490 | /**
|
| 491 | * @}
|
| 492 | */
|
| 493 |
|
| 494 | ///////////////////////////////////////////////////////////////////////////////
|
| 495 | #if defined(PJ_HAS_SEMAPHORE) && PJ_HAS_SEMAPHORE != 0
|
| 496 | /**
|
| 497 | * @defgroup PJ_SEM Semaphores.
|
| 498 | * @ingroup PJ_OS
|
| 499 | * @{
|
| 500 | *
|
| 501 | * This module provides abstraction for semaphores, where available.
|
| 502 | */
|
| 503 |
|
| 504 | /**
|
| 505 | * Create semaphore.
|
| 506 | *
|
| 507 | * @param pool The pool.
|
| 508 | * @param name Name to be assigned to the semaphore (for logging purpose)
|
| 509 | * @param initial The initial count of the semaphore.
|
| 510 | * @param max The maximum count of the semaphore.
|
| 511 | * @param sem Pointer to hold the semaphore created.
|
| 512 | *
|
| 513 | * @return PJ_SUCCESS on success, or the error code.
|
| 514 | */
|
| 515 | PJ_DECL(pj_status_t) pj_sem_create( pj_pool_t *pool,
|
| 516 | const char *name,
|
| 517 | unsigned initial,
|
| 518 | unsigned max,
|
| 519 | pj_sem_t **sem);
|
| 520 |
|
| 521 | /**
|
| 522 | * Wait for semaphore.
|
| 523 | *
|
| 524 | * @param sem The semaphore.
|
| 525 | *
|
| 526 | * @return PJ_SUCCESS on success, or the error code.
|
| 527 | */
|
| 528 | PJ_DECL(pj_status_t) pj_sem_wait(pj_sem_t *sem);
|
| 529 |
|
| 530 | /**
|
| 531 | * Try wait for semaphore.
|
| 532 | *
|
| 533 | * @param sem The semaphore.
|
| 534 | *
|
| 535 | * @return PJ_SUCCESS on success, or the error code.
|
| 536 | */
|
| 537 | PJ_DECL(pj_status_t) pj_sem_trywait(pj_sem_t *sem);
|
| 538 |
|
| 539 | /**
|
| 540 | * Release semaphore.
|
| 541 | *
|
| 542 | * @param sem The semaphore.
|
| 543 | *
|
| 544 | * @return PJ_SUCCESS on success, or the error code.
|
| 545 | */
|
| 546 | PJ_DECL(pj_status_t) pj_sem_post(pj_sem_t *sem);
|
| 547 |
|
| 548 | /**
|
| 549 | * Destroy semaphore.
|
| 550 | *
|
| 551 | * @param sem The semaphore.
|
| 552 | *
|
| 553 | * @return PJ_SUCCESS on success, or the error code.
|
| 554 | */
|
| 555 | PJ_DECL(pj_status_t) pj_sem_destroy(pj_sem_t *sem);
|
| 556 |
|
| 557 | /**
|
| 558 | * @}
|
| 559 | */
|
| 560 | #endif /* PJ_HAS_SEMAPHORE */
|
| 561 |
|
| 562 |
|
| 563 | ///////////////////////////////////////////////////////////////////////////////
|
| 564 | #if defined(PJ_HAS_EVENT_OBJ) && PJ_HAS_EVENT_OBJ != 0
|
| 565 | /**
|
| 566 | * @defgroup PJ_EVENT Event Object.
|
| 567 | * @ingroup PJ_OS
|
| 568 | * @{
|
| 569 | *
|
| 570 | * This module provides abstraction to event object (e.g. Win32 Event) where
|
| 571 | * available. Event objects can be used for synchronization among threads.
|
| 572 | */
|
| 573 |
|
| 574 | /**
|
| 575 | * Create event object.
|
| 576 | *
|
| 577 | * @param pool The pool.
|
| 578 | * @param name The name of the event object (for logging purpose).
|
| 579 | * @param manual_reset Specify whether the event is manual-reset
|
| 580 | * @param initial Specify the initial state of the event object.
|
| 581 | * @param event Pointer to hold the returned event object.
|
| 582 | *
|
| 583 | * @return event handle, or NULL if failed.
|
| 584 | */
|
| 585 | PJ_DECL(pj_status_t) pj_event_create(pj_pool_t *pool, const char *name,
|
| 586 | pj_bool_t manual_reset, pj_bool_t initial,
|
| 587 | pj_event_t **event);
|
| 588 |
|
| 589 | /**
|
| 590 | * Wait for event to be signaled.
|
| 591 | *
|
| 592 | * @param event The event object.
|
| 593 | *
|
| 594 | * @return zero if successfull.
|
| 595 | */
|
| 596 | PJ_DECL(pj_status_t) pj_event_wait(pj_event_t *event);
|
| 597 |
|
| 598 | /**
|
| 599 | * Try wait for event object to be signalled.
|
| 600 | *
|
| 601 | * @param event The event object.
|
| 602 | *
|
| 603 | * @return zero if successfull.
|
| 604 | */
|
| 605 | PJ_DECL(pj_status_t) pj_event_trywait(pj_event_t *event);
|
| 606 |
|
| 607 | /**
|
| 608 | * Set the event object state to signaled. For auto-reset event, this
|
| 609 | * will only release the first thread that are waiting on the event. For
|
| 610 | * manual reset event, the state remains signaled until the event is reset.
|
| 611 | * If there is no thread waiting on the event, the event object state
|
| 612 | * remains signaled.
|
| 613 | *
|
| 614 | * @param event The event object.
|
| 615 | *
|
| 616 | * @return zero if successfull.
|
| 617 | */
|
| 618 | PJ_DECL(pj_status_t) pj_event_set(pj_event_t *event);
|
| 619 |
|
| 620 | /**
|
| 621 | * Set the event object to signaled state to release appropriate number of
|
| 622 | * waiting threads and then reset the event object to non-signaled. For
|
| 623 | * manual-reset event, this function will release all waiting threads. For
|
| 624 | * auto-reset event, this function will only release one waiting thread.
|
| 625 | *
|
| 626 | * @param event The event object.
|
| 627 | *
|
| 628 | * @return zero if successfull.
|
| 629 | */
|
| 630 | PJ_DECL(pj_status_t) pj_event_pulse(pj_event_t *event);
|
| 631 |
|
| 632 | /**
|
| 633 | * Set the event object state to non-signaled.
|
| 634 | *
|
| 635 | * @param event The event object.
|
| 636 | *
|
| 637 | * @return zero if successfull.
|
| 638 | */
|
| 639 | PJ_DECL(pj_status_t) pj_event_reset(pj_event_t *event);
|
| 640 |
|
| 641 | /**
|
| 642 | * Destroy the event object.
|
| 643 | *
|
| 644 | * @param event The event object.
|
| 645 | *
|
| 646 | * @return zero if successfull.
|
| 647 | */
|
| 648 | PJ_DECL(pj_status_t) pj_event_destroy(pj_event_t *event);
|
| 649 |
|
| 650 | /**
|
| 651 | * @}
|
| 652 | */
|
| 653 | #endif /* PJ_HAS_EVENT_OBJ */
|
| 654 |
|
| 655 | ///////////////////////////////////////////////////////////////////////////////
|
| 656 | /**
|
| 657 | * @addtogroup PJ_TIME Time Data Type and Manipulation.
|
| 658 | * @ingroup PJ_OS
|
| 659 | * @{
|
| 660 | * This module provides API for manipulating time.
|
| 661 | *
|
| 662 | * \section pj_time_examples_sec Examples
|
| 663 | *
|
| 664 | * For examples, please see:
|
| 665 | * - \ref page_pjlib_sleep_test
|
| 666 | */
|
| 667 |
|
| 668 | /**
|
| 669 | * Get current time of day in local representation.
|
| 670 | *
|
| 671 | * @param tv Variable to store the result.
|
| 672 | *
|
| 673 | * @return zero if successfull.
|
| 674 | */
|
| 675 | PJ_DECL(pj_status_t) pj_gettimeofday(pj_time_val *tv);
|
| 676 |
|
| 677 |
|
| 678 | /**
|
| 679 | * Parse time value into date/time representation.
|
| 680 | *
|
| 681 | * @param tv The time.
|
| 682 | * @param pt Variable to store the date time result.
|
| 683 | *
|
| 684 | * @return zero if successfull.
|
| 685 | */
|
| 686 | PJ_DECL(pj_status_t) pj_time_decode(const pj_time_val *tv, pj_parsed_time *pt);
|
| 687 |
|
| 688 | /**
|
| 689 | * Encode date/time to time value.
|
| 690 | *
|
| 691 | * @param pt The date/time.
|
| 692 | * @param tv Variable to store time value result.
|
| 693 | *
|
| 694 | * @return zero if successfull.
|
| 695 | */
|
| 696 | PJ_DECL(pj_status_t) pj_time_encode(const pj_parsed_time *pt, pj_time_val *tv);
|
| 697 |
|
| 698 | /**
|
| 699 | * Convert local time to GMT.
|
| 700 | *
|
| 701 | * @param tv Time to convert.
|
| 702 | *
|
| 703 | * @return zero if successfull.
|
| 704 | */
|
| 705 | PJ_DECL(pj_status_t) pj_time_local_to_gmt(pj_time_val *tv);
|
| 706 |
|
| 707 | /**
|
| 708 | * Convert GMT to local time.
|
| 709 | *
|
| 710 | * @param tv Time to convert.
|
| 711 | *
|
| 712 | * @return zero if successfull.
|
| 713 | */
|
| 714 | PJ_DECL(pj_status_t) pj_time_gmt_to_local(pj_time_val *tv);
|
| 715 |
|
| 716 | /**
|
| 717 | * @}
|
| 718 | */
|
| 719 |
|
| 720 | ///////////////////////////////////////////////////////////////////////////////
|
| 721 | #if defined(PJ_TERM_HAS_COLOR) && PJ_TERM_HAS_COLOR != 0
|
| 722 |
|
| 723 | /**
|
| 724 | * @defgroup PJ_TERM Terminal
|
| 725 | * @ingroup PJ_OS
|
| 726 | * @{
|
| 727 | */
|
| 728 |
|
| 729 | /**
|
| 730 | * Set current terminal color.
|
| 731 | *
|
| 732 | * @param color The RGB color.
|
| 733 | *
|
| 734 | * @return zero on success.
|
| 735 | */
|
| 736 | PJ_DECL(pj_status_t) pj_term_set_color(pj_color_t color);
|
| 737 |
|
| 738 | /**
|
| 739 | * Get current terminal foreground color.
|
| 740 | *
|
| 741 | * @return RGB color.
|
| 742 | */
|
| 743 | PJ_DECL(pj_color_t) pj_term_get_color(void);
|
| 744 |
|
| 745 | /**
|
| 746 | * @}
|
| 747 | */
|
| 748 |
|
| 749 | #endif /* PJ_TERM_HAS_COLOR */
|
| 750 |
|
| 751 | ///////////////////////////////////////////////////////////////////////////////
|
| 752 | /**
|
| 753 | * @defgroup PJ_TIMESTAMP High Resolution Timestamp
|
| 754 | * @ingroup PJ_OS
|
| 755 | * @{
|
| 756 | *
|
| 757 | * PJLIB provides <b>High Resolution Timestamp</b> API to access highest
|
| 758 | * resolution timestamp value provided by the platform. The API is usefull
|
| 759 | * to measure precise elapsed time, and can be used in applications such
|
| 760 | * as profiling.
|
| 761 | *
|
| 762 | * The timestamp value is represented in cycles, and can be related to
|
| 763 | * normal time (in seconds or sub-seconds) using various functions provided.
|
| 764 | *
|
| 765 | * \section pj_timestamp_examples_sec Examples
|
| 766 | *
|
| 767 | * For examples, please see:
|
| 768 | * - \ref page_pjlib_sleep_test
|
| 769 | * - \ref page_pjlib_timestamp_test
|
| 770 | */
|
| 771 |
|
| 772 | /*
|
| 773 | * High resolution timer.
|
| 774 | */
|
| 775 | #if defined(PJ_HAS_HIGH_RES_TIMER) && PJ_HAS_HIGH_RES_TIMER != 0
|
| 776 |
|
| 777 | /**
|
| 778 | * This structure represents high resolution (64bit) time value. The time
|
| 779 | * values represent time in cycles, which is retrieved by calling
|
| 780 | * #pj_get_timestamp().
|
| 781 | */
|
| 782 | typedef union pj_timestamp
|
| 783 | {
|
| 784 | struct
|
| 785 | {
|
| 786 | pj_uint32_t lo; /**< Low 32-bit value of the 64-bit value. */
|
| 787 | pj_uint32_t hi; /**< high 32-bit value of the 64-bit value. */
|
| 788 | } u32; /**< The 64-bit value as two 32-bit values. */
|
| 789 |
|
| 790 | #if PJ_HAS_INT64
|
| 791 | pj_uint64_t u64; /**< The whole 64-bit value, where available. */
|
| 792 | #endif
|
| 793 | } pj_timestamp;
|
| 794 |
|
| 795 |
|
| 796 | /**
|
| 797 | * Acquire high resolution timer value. The time value are stored
|
| 798 | * in cycles.
|
| 799 | *
|
| 800 | * @param ts High resolution timer value.
|
| 801 | * @return PJ_SUCCESS or the appropriate error code.
|
| 802 | *
|
| 803 | * @see pj_get_timestamp_freq().
|
| 804 | */
|
| 805 | PJ_DECL(pj_status_t) pj_get_timestamp(pj_timestamp *ts);
|
| 806 |
|
| 807 | /**
|
| 808 | * Get high resolution timer frequency, in cycles per second.
|
| 809 | *
|
| 810 | * @param freq Timer frequency, in cycles per second.
|
| 811 | * @return PJ_SUCCESS or the appropriate error code.
|
| 812 | */
|
| 813 | PJ_DECL(pj_status_t) pj_get_timestamp_freq(pj_timestamp *freq);
|
| 814 |
|
| 815 | /**
|
| 816 | * Calculate the elapsed time, and store it in pj_time_val.
|
| 817 | * This function calculates the elapsed time using highest precision
|
| 818 | * calculation that is available for current platform, considering
|
| 819 | * whether floating point or 64-bit precision arithmetic is available.
|
| 820 | * For maximum portability, application should prefer to use this function
|
| 821 | * rather than calculating the elapsed time by itself.
|
| 822 | *
|
| 823 | * @param start The starting timestamp.
|
| 824 | * @param stop The end timestamp.
|
| 825 | *
|
| 826 | * @return Elapsed time as #pj_time_val.
|
| 827 | *
|
| 828 | * @see pj_elapsed_usec(), pj_elapsed_cycle(), pj_elapsed_nanosec()
|
| 829 | */
|
| 830 | PJ_DECL(pj_time_val) pj_elapsed_time( const pj_timestamp *start,
|
| 831 | const pj_timestamp *stop );
|
| 832 |
|
| 833 | /**
|
| 834 | * Calculate the elapsed time in 32-bit microseconds.
|
| 835 | * This function calculates the elapsed time using highest precision
|
| 836 | * calculation that is available for current platform, considering
|
| 837 | * whether floating point or 64-bit precision arithmetic is available.
|
| 838 | * For maximum portability, application should prefer to use this function
|
| 839 | * rather than calculating the elapsed time by itself.
|
| 840 | *
|
| 841 | * @param start The starting timestamp.
|
| 842 | * @param stop The end timestamp.
|
| 843 | *
|
| 844 | * @return Elapsed time in microsecond.
|
| 845 | *
|
| 846 | * @see pj_elapsed_time(), pj_elapsed_cycle(), pj_elapsed_nanosec()
|
| 847 | */
|
| 848 | PJ_DECL(pj_uint32_t) pj_elapsed_usec( const pj_timestamp *start,
|
| 849 | const pj_timestamp *stop );
|
| 850 |
|
| 851 | /**
|
| 852 | * Calculate the elapsed time in 32-bit nanoseconds.
|
| 853 | * This function calculates the elapsed time using highest precision
|
| 854 | * calculation that is available for current platform, considering
|
| 855 | * whether floating point or 64-bit precision arithmetic is available.
|
| 856 | * For maximum portability, application should prefer to use this function
|
| 857 | * rather than calculating the elapsed time by itself.
|
| 858 | *
|
| 859 | * @param start The starting timestamp.
|
| 860 | * @param stop The end timestamp.
|
| 861 | *
|
| 862 | * @return Elapsed time in nanoseconds.
|
| 863 | *
|
| 864 | * @see pj_elapsed_time(), pj_elapsed_cycle(), pj_elapsed_usec()
|
| 865 | */
|
| 866 | PJ_DECL(pj_uint32_t) pj_elapsed_nanosec( const pj_timestamp *start,
|
| 867 | const pj_timestamp *stop );
|
| 868 |
|
| 869 | /**
|
| 870 | * Calculate the elapsed time in 32-bit cycles.
|
| 871 | * This function calculates the elapsed time using highest precision
|
| 872 | * calculation that is available for current platform, considering
|
| 873 | * whether floating point or 64-bit precision arithmetic is available.
|
| 874 | * For maximum portability, application should prefer to use this function
|
| 875 | * rather than calculating the elapsed time by itself.
|
| 876 | *
|
| 877 | * @param start The starting timestamp.
|
| 878 | * @param stop The end timestamp.
|
| 879 | *
|
| 880 | * @return Elapsed time in cycles.
|
| 881 | *
|
| 882 | * @see pj_elapsed_usec(), pj_elapsed_time(), pj_elapsed_nanosec()
|
| 883 | */
|
| 884 | PJ_DECL(pj_uint32_t) pj_elapsed_cycle( const pj_timestamp *start,
|
| 885 | const pj_timestamp *stop );
|
| 886 |
|
| 887 |
|
| 888 | #endif /* PJ_HAS_HIGH_RES_TIMER */
|
| 889 |
|
| 890 | /** @} */
|
| 891 |
|
| 892 |
|
| 893 | ///////////////////////////////////////////////////////////////////////////////
|
| 894 | /**
|
| 895 | * Internal PJLIB function to initialize the threading subsystem.
|
| 896 | * @return PJ_SUCCESS or the appropriate error code.
|
| 897 | */
|
| 898 | pj_status_t pj_thread_init(void);
|
| 899 |
|
| 900 |
|
| 901 | PJ_END_DECL
|
| 902 |
|
| 903 | #endif /* __PJ_OS_H__ */
|
| 904 |
|