sl@0: /** @file ../inc/pthread.h sl@0: @internalComponent sl@0: */ sl@0: sl@0: /** @def POSIX_THREAD_KEYS_MAX sl@0: sl@0: Represents maximum value sl@0: sl@0: @publishedAll sl@0: @externallyDefinedApi sl@0: */ sl@0: sl@0: /** @def PTHREAD_STACK_MIN sl@0: sl@0: Minimum supported stack size for a thread sl@0: sl@0: @publishedAll sl@0: @externallyDefinedApi sl@0: */ sl@0: sl@0: /** @def POSIX_THREAD_THREADS_MAX sl@0: sl@0: Thread max. Value is 64 sl@0: sl@0: @publishedAll sl@0: @externallyDefinedApi sl@0: */ sl@0: sl@0: /** @def PTHREAD_THREADS_MAX sl@0: sl@0: Maximum number of threads supported per process. Value is 1024 sl@0: sl@0: @publishedAll sl@0: @externallyDefinedApi sl@0: */ sl@0: sl@0: /** @def SEM_VALUE_MAX sl@0: sl@0: Semaphores have a maximum value past which they cannot be incremented. The macro SEM_VALUE_MAX is defined to be this maximum value. sl@0: sl@0: @publishedAll sl@0: @externallyDefinedApi sl@0: */ sl@0: sl@0: /** @def PTHREAD_COND_INITIALIZER sl@0: sl@0: Value is 4. Describes condition initializer. sl@0: sl@0: @publishedAll sl@0: @externallyDefinedApi sl@0: */ sl@0: sl@0: /** @def SEM_NSEMS_MAX sl@0: sl@0: The maximum number of semaphores a process can have.value is 1024 sl@0: sl@0: @publishedAll sl@0: @released sl@0: */ sl@0: sl@0: /** @def POSIX_SEM_NSEMS_MAX sl@0: sl@0: Number of semaphores a process can have. sl@0: sl@0: @publishedAll sl@0: @released sl@0: */ sl@0: sl@0: /** @def POSIX_THREAD_DESTRUCTOR_ITERATIONS sl@0: sl@0: Controlling the iterations of destructors for thread-specific data. sl@0: sl@0: @publishedAll sl@0: @released sl@0: */ sl@0: sl@0: /** @typedef typedef int pthread_once_t sl@0: sl@0: Used for dynamic package initialization. sl@0: sl@0: @publishedAll sl@0: @externallyDefinedApi sl@0: */ sl@0: sl@0: /** @typedef typedef struct _pthread_condattr_t* pthread_condattr_t sl@0: sl@0: Used to identify a condition attribute object sl@0: sl@0: @publishedAll sl@0: @externallyDefinedApi sl@0: */ sl@0: sl@0: /** @struct pthread_mutex_t sl@0: sl@0: Thread mutex type. Used for mutexes. sl@0: sl@0: @publishedAll sl@0: @externallyDefinedApi sl@0: */ sl@0: sl@0: /** @struct pthread_mutexattr_t sl@0: sl@0: Used to identify a mutex attribute object. sl@0: sl@0: @publishedAll sl@0: @externallyDefinedApi sl@0: */ sl@0: sl@0: /** @struct pthread_cond_t sl@0: sl@0: Used for condition variables. sl@0: sl@0: @publishedAll sl@0: @externallyDefinedApi sl@0: */ sl@0: sl@0: /** @fn pthread_create(pthread_t *threadhdl, pthread_attr_t *attrib, thread_begin_routine begin_routine, void *param) sl@0: @param threadhdl sl@0: @param attrib sl@0: @param begin_routine sl@0: @param *param sl@0: @return If successful, the pthread_create function will return zero. sl@0: Otherwise an error number will be returned to sl@0: indicate the error. sl@0: sl@0: The pthread_create function is used to create a new thread, with attributes specified by attrib , sl@0: within a process. sl@0: If attrib is NULL , sl@0: the default attributes are used. sl@0: If the attributes specified by attrib are modified later, the thread's attributes are not affected. sl@0: Upon sl@0: successful completion pthread_create will store the ID of the created thread in the location specified by threadhdl . sl@0: sl@0: The thread is created executing begin_routine with param as its sole argument. sl@0: If the begin_routine returns, the effect is as if there was an implicit call to pthread_exit using the return value of start_routine as the exit status. sl@0: Note that the thread in which main was originally invoked differs from this. sl@0: When it returns from main , sl@0: the effect is as if there was an implicit call to exit using the return value of main as the exit status. sl@0: sl@0: sl@0: sl@0: Examples: sl@0: @code sl@0: void *a_thread_func_1_1(void*) sl@0: { sl@0: return NULL; sl@0: } sl@0: int XYZ() sl@0: { sl@0: pthread_t new_th; sl@0: if(pthread_create(&new;_th, NULL, a_thread_func_1_1, NULL) != 0) sl@0: { sl@0: perror("Error creating thread sl@0: "); sl@0: return -1; sl@0: } sl@0: } sl@0: sl@0: @endcode sl@0: @see pthread_exit() sl@0: @see pthread_join() sl@0: sl@0: sl@0: sl@0: sl@0: @publishedAll sl@0: @externallyDefinedApi sl@0: */ sl@0: sl@0: /** @fn pthread_self(void) sl@0: sl@0: @return The pthread_self function returns the thread ID of the calling thread. sl@0: sl@0: The pthread_self function returns the thread ID of the calling thread. sl@0: sl@0: sl@0: sl@0: Examples: sl@0: @code sl@0: pthread_t new_th2; sl@0: new_th2=pthread_self(); sl@0: sl@0: @endcode sl@0: @see pthread_create() sl@0: @see pthread_equal() sl@0: sl@0: sl@0: sl@0: sl@0: @publishedAll sl@0: @externallyDefinedApi sl@0: */ sl@0: sl@0: /** @fn pthread_equal(pthread_t t1, pthread_t t2) sl@0: @param t1 sl@0: @param t2 sl@0: @return The pthread_equal function will return non-zero if the thread IDs t1 and t2 correspond to the same thread, otherwise it will return zero. sl@0: sl@0: The pthread_equal function compares the thread IDs t1 and t2 . sl@0: sl@0: Examples: sl@0: @code sl@0: void *a_thread_func_1_2(void*) sl@0: { sl@0: pthread_exit(0); sl@0: return NULL; sl@0: } sl@0: void XYZ() sl@0: { sl@0: pthread_t new_th1, new_th2; sl@0: /* Create a new thread. */ sl@0: if(pthread_create(&new;_th1, NULL, a_thread_func_1_2, NULL) != 0) sl@0: { sl@0: perror("Error creating thread sl@0: "); sl@0: return -1; sl@0: } sl@0: /* Create another new thread. */ sl@0: if(pthread_create(&new;_th2, NULL, a_thread_func_1_2, NULL) != 0) sl@0: { sl@0: perror("Error creating thread sl@0: "); sl@0: return -1; sl@0: } sl@0: /* Call pthread_equal() and pass to it the 2 new threads. sl@0: * It should return a zero value, indicating that sl@0: * they are not equal. */ sl@0: if(pthread_equal(new_th1, new_th2) != 0) sl@0: { sl@0: printf("pthread_equal FAILED sl@0: "); sl@0: return -1; sl@0: } sl@0: } sl@0: sl@0: @endcode sl@0: @see pthread_create() sl@0: @see pthread_exit() sl@0: sl@0: sl@0: sl@0: sl@0: @publishedAll sl@0: @externallyDefinedApi sl@0: */ sl@0: sl@0: /** @fn pthread_join(pthread_t thrHandle, void **retValPtr) sl@0: @param thrHandle sl@0: @param retValPtr sl@0: @return If successful, the pthread_join function will return zero. sl@0: Otherwise an error number will be returned to sl@0: indicate the error. sl@0: sl@0: The pthread_join function suspends execution of the calling thread until the target thrHandle terminates unless the target thrHandle has already terminated. sl@0: sl@0: On return from a successful pthread_join call with a non-NULL retValPtr argument, the value passed to pthread_exit by the terminating thread is stored in the location referenced by retValPtr . sl@0: When a pthread_join returns successfully, the target thread has been terminated. sl@0: The results sl@0: of multiple simultaneous calls to pthread_join specifying the same target thread are undefined. sl@0: sl@0: sl@0: sl@0: Examples: sl@0: @code sl@0: /* Thread's function. */ sl@0: void *a_thread_func_1_1(void*) sl@0: { sl@0: int i; sl@0: printf("Wait for 3 seconds for thread to finish execution:0); sl@0: for(i=1;i<4;i++) sl@0: { sl@0: printf("Waited (%d) second0, i); sl@0: sleep(1); sl@0: } sl@0: return NULL; sl@0: } sl@0: int XYZ() sl@0: { sl@0: pthread_t new_th; sl@0: /* Create a new thread. */ sl@0: if(pthread_create(&new;_th, NULL, a_thread_func_1_1, NULL) != 0) sl@0: { sl@0: perror("Error creating thread sl@0: "); sl@0: return -1; sl@0: } sl@0: /* Wait for thread to return */ sl@0: if(pthread_join(new_th, NULL) != 0) sl@0: { sl@0: perror("Error in pthread_join() sl@0: "); sl@0: return -1; sl@0: } sl@0: sl@0: @endcode sl@0: @see wait() sl@0: @see pthread_create() sl@0: sl@0: sl@0: sl@0: sl@0: @publishedAll sl@0: @externallyDefinedApi sl@0: */ sl@0: sl@0: /** @fn pthread_detach(pthread_t thrHandle) sl@0: @param thrHandle sl@0: @return If successful, the pthread_detach function will return zero. sl@0: Otherwise an error number will be returned to sl@0: indicate the error. sl@0: sl@0: The pthread_detach function is used to indicate to the implementation that storage for the sl@0: thread thrHandle can be reclaimed when the thread terminates. sl@0: If thrHandle has not terminated, pthread_detach will not cause it to terminate. sl@0: The effect of multiple pthread_detach calls on the same target thread is unspecified. sl@0: sl@0: Examples: sl@0: @code sl@0: void *a_thread_func_1_1(void*) sl@0: { sl@0: sleep(10); sl@0: return NULL; sl@0: } sl@0: int main_1_1() sl@0: { sl@0: pthread_attr_t new_attr; sl@0: pthread_t new_th; sl@0: int ret; sl@0: /* Initialize attribute */ sl@0: if(pthread_attr_init(&new;_attr) != 0) sl@0: { sl@0: perror("Cannot initialize attribute object sl@0: "); sl@0: return -1; sl@0: } sl@0: /* Set the attribute object to be joinable */ sl@0: if(pthread_attr_setdetachstate(&new;_attr, PTHREAD_CREATE_JOINABLE) != 0) sl@0: { sl@0: perror("Error in pthread_attr_setdetachstate() sl@0: "); sl@0: return -1; sl@0: } sl@0: /* Create the thread */ sl@0: if(pthread_create(&new;_th, &new;_attr, a_thread_func_1_1, NULL) != 0) sl@0: { sl@0: perror("Error creating thread sl@0: "); sl@0: return -1; sl@0: } sl@0: /* Detach the thread. */ sl@0: if(pthread_detach(new_th) != 0) sl@0: { sl@0: printf("Error detaching thread sl@0: "); sl@0: return -1; sl@0: } sl@0: sl@0: @endcode sl@0: @see pthread_join() sl@0: sl@0: sl@0: sl@0: sl@0: @publishedAll sl@0: @externallyDefinedApi sl@0: */ sl@0: sl@0: /** @fn pthread_exit(void *retValPtr) sl@0: @param retValPtr sl@0: @return The pthread_exit function cannot return to its caller. sl@0: sl@0: The pthread_exit function terminates the calling thread and makes the value retValPtr available to any successful join with the terminating thread. sl@0: Thread termination does not release any application sl@0: visible process resources, including, but not limited to, mutexes and sl@0: file descriptors, nor does it perform any process level cleanup sl@0: actions, including, but not limited to, calling atexit routines that may exist. sl@0: sl@0: An implicit call to pthread_exit is made when a thread other than the thread in which main was first invoked returns from the start routine that was used to create sl@0: it. sl@0: The function's return value serves as the thread's exit status. sl@0: sl@0: The behavior of pthread_exit is undefined if called from a cancellation handler or destructor function sl@0: that was invoked as the result of an implicit or explicit call to pthread_exit . sl@0: sl@0: After a thread has terminated, the result of access to local (auto) sl@0: variables of the thread is undefined. sl@0: Thus, references to local variables sl@0: of the exiting thread should not be used for the pthread_exit retValPtr parameter value. sl@0: sl@0: The process will exit with an exit status of 0 after the last thread has sl@0: been terminated. sl@0: The behavior is as if the implementation called exit with a zero argument at thread termination time. sl@0: sl@0: Examples: sl@0: @code sl@0: /* Thread's function. */ sl@0: void *a_thread_func_1_1(void*) sl@0: { sl@0: /* .. Do some thing .. */ sl@0: pthread_exit((void*)RETURN_CODE); sl@0: } sl@0: sl@0: @endcode sl@0: @see _exit() sl@0: @see exit() sl@0: @see pthread_create() sl@0: @see pthread_join() sl@0: sl@0: sl@0: sl@0: sl@0: @publishedAll sl@0: @externallyDefinedApi sl@0: */ sl@0: sl@0: /** @fn pthread_attr_init(pthread_attr_t *attrib) sl@0: @param attrib sl@0: sl@0: Note: This description also covers the following functions - sl@0: pthread_attr_destroy() pthread_attr_setstacksize() pthread_attr_getstacksize() pthread_attr_setdetachstate() pthread_attr_getdetachstate() pthread_attr_setschedparam() pthread_attr_getschedparam() pthread_attr_setschedpolicy() pthread_attr_getschedpolicy() pthread_attr_setscope() pthread_attr_getscope() sl@0: sl@0: @return If successful, these functions return 0. sl@0: Otherwise, an error number is returned to indicate the error. sl@0: sl@0: Thread attributes are used to specify parameters to pthread_create . sl@0: One attribute object can be used in multiple calls to pthread_create , sl@0: with or without modifications between calls. sl@0: sl@0: The pthread_attr_init function initializes attrib with all the default thread attributes. sl@0: sl@0: The pthread_attr_destroy function destroys attrib . sl@0: sl@0: The pthread_attr_set* functions set the attribute that corresponds to each function name. sl@0: sl@0: The pthread_attr_get* functions copy the value of the attribute that corresponds to each function name sl@0: to the location pointed to by the second function parameter. sl@0: sl@0: Examples: sl@0: @code sl@0: /* ***************************************************** */ sl@0: /* Example for pthread_attr_init & pthread_attr_destroy */ sl@0: /* ***************************************************** */ sl@0: pthread_attr_t new_attr; sl@0: /* Initialize attribute */ sl@0: if(pthread_attr_init(&new;_attr) != 0) sl@0: { sl@0: printf("Cannot initialize attribute object sl@0: "); sl@0: return -1; /* or exit */ sl@0: } sl@0: /* Create thread */ sl@0: /* Destroy attribute */ sl@0: if(pthread_attr_destroy(&new;_attr) != 0) sl@0: { sl@0: perror("Cannot destroy the attribute object sl@0: "); sl@0: return -1; /* or exit*/ sl@0: } sl@0: sl@0: @endcode sl@0: @code sl@0: /* ***************************************************** */ sl@0: /* Example for pthread_attr_getdetachstate */ sl@0: /* ***************************************************** */ sl@0: pthread_attr_t new_attr; sl@0: int detach_state; sl@0: /* Initialize attribute */ sl@0: if(pthread_attr_init(&new;_attr) != 0) sl@0: { sl@0: printf("Cannot initialize attribute object sl@0: "); sl@0: return -1; sl@0: } sl@0: if(pthread_attr_getdetachstate(&new;_attr, &detach;_state) != 0) sl@0: { sl@0: printf("Cannot get the state sl@0: "); sl@0: return -1; sl@0: } sl@0: if(detach_state == PTHREAD_CREATE_JOINABLE) sl@0: { sl@0: printf("State is joinable sl@0: "); sl@0: } sl@0: else sl@0: { sl@0: printf("State is detached sl@0: "); sl@0: } sl@0: /* Create thread */ sl@0: /* Destroy attribute */ sl@0: sl@0: @endcode sl@0: @code sl@0: /* ***************************************************** */ sl@0: /* Example for pthread_attr_getschedpolicy */ sl@0: /* ***************************************************** */ sl@0: pthread_attr_t new_attr; sl@0: int rc; sl@0: int policy; sl@0: /* Initialize attribute */ sl@0: if(pthread_attr_init(&new;_attr) != 0) sl@0: { sl@0: printf("Cannot initialize attribute object sl@0: "); sl@0: return -1; /* or exit */ sl@0: } sl@0: rc = pthread_attr_getschedpolicy(new_attr, &policy;); sl@0: if( rc != 0) { sl@0: printf("pthread_attr_getschedpolicy failed sl@0: "); sl@0: return -1; sl@0: } sl@0: switch(policy) { sl@0: case SCHED_FIFO: sl@0: printf("Scheduling policy: SCHED_FIFO 0); sl@0: break; sl@0: case SCHED_RR: sl@0: printf("Scheduling policy: SCHED_RR sl@0: "); sl@0: break; sl@0: case SCHED_OTHER: sl@0: printf("Scheduling policy: SCHED_OTHER sl@0: "); sl@0: break; sl@0: } sl@0: /* Create thread */ sl@0: /* Destroy attribute */ sl@0: sl@0: @endcode sl@0: @code sl@0: /* ***************************************************** */ sl@0: /* Example for pthread_attr_getscope */ sl@0: /* ***************************************************** */ sl@0: pthread_attr_t new_attr; sl@0: int rc; sl@0: int scope; sl@0: /* Initialize attribute */ sl@0: if(pthread_attr_init(&new;_attr) != 0) sl@0: { sl@0: printf("Cannot initialize attribute object sl@0: "); sl@0: return -1; /* or exit */ sl@0: } sl@0: rc = pthread_attr_getscope(new_attr, &scope;); sl@0: if( rc != 0) { sl@0: printf("pthread_attr_getscope failed"); sl@0: return -1; sl@0: } sl@0: switch(scope) { sl@0: case SYSTEMSCOPE: sl@0: printf("scope: System sl@0: "); sl@0: break; sl@0: case PROCESSSCOPE: sl@0: printf("scope: Process sl@0: "); sl@0: break; sl@0: } sl@0: /* Create thread */ sl@0: /* Destroy attribute */ sl@0: sl@0: @endcode sl@0: @code sl@0: /* ***************************************************** */ sl@0: /* Example for pthread_attr_getstacksize */ sl@0: /* ***************************************************** */ sl@0: pthread_attr_t new_attr; sl@0: size_t ssize; sl@0: int rc; sl@0: /* Initialize attribute */ sl@0: if(pthread_attr_init(&new;_attr) != 0) sl@0: { sl@0: printf("Cannot initialize attribute object sl@0: "); sl@0: return -1; /* or exit */ sl@0: } sl@0: /* Get the default stack_size value */ sl@0: rc = pthread_attr_getstacksize(&new;_attr, &stack;_size); sl@0: if( rc != 0) { sl@0: printf("pthread_attr_getstacksize failed"); sl@0: return -1; sl@0: } sl@0: printf("ssize = %lu sl@0: ", stack_size); sl@0: /* Create thread */ sl@0: /* Destroy attribute */ sl@0: sl@0: @endcode sl@0: @code sl@0: /* ***************************************************** */ sl@0: /* Example for pthread_attr_getschedparam */ sl@0: /* ***************************************************** */ sl@0: pthread_attr_t attr; sl@0: int rc=0; sl@0: struct sched_param param; sl@0: struct sched_param param2; sl@0: rc = pthread_attr_init(&attr;); sl@0: if(rc != 0) { sl@0: printf("pthread_attr_init failed sl@0: "); sl@0: return -1; sl@0: } sl@0: param.sched_priority = 50; sl@0: rc = pthread_attr_setschedparam(&attr;, & param); sl@0: if(rc != 0) { sl@0: printf("pthread_attr_setschedparam failed sl@0: "); sl@0: return -1; sl@0: } sl@0: rc = pthread_attr_getschedparam(&attr;, & param2); sl@0: if(rc != 0) { sl@0: printf("pthread_attr_getschedparam failed sl@0: "); sl@0: return -1; sl@0: } sl@0: /* priority will be stored in param2.sched_priority */ sl@0: /* Create thread */ sl@0: /* Destroy attribute */ sl@0: sl@0: @endcode sl@0: @code sl@0: /* ***************************************************** */ sl@0: /* Example for pthread_attr_setdetachstate */ sl@0: /* ***************************************************** */ sl@0: pthread_attr_t new_attr; sl@0: int detach_state; sl@0: /* Initialize attribute */ sl@0: if(pthread_attr_init(&new;_attr) != 0) sl@0: { sl@0: perror("Cannot initialize attribute object sl@0: "); sl@0: return -1; sl@0: } sl@0: /* Set the attribute object to PTHREAD_CREATE_JOINABLE. */ sl@0: if(pthread_attr_setdetachstate(&new;_attr, PTHREAD_CREATE_JOINABLE) != 0) sl@0: { sl@0: perror("Error in pthread_attr_setdetachstate() sl@0: "); sl@0: return -1; sl@0: } sl@0: /* Create thread */ sl@0: /* Destroy attribute */ sl@0: sl@0: @endcode sl@0: @code sl@0: /* ***************************************************** */ sl@0: /* Example for pthread_attr_setschedparam */ sl@0: /* ***************************************************** */ sl@0: pthread_attr_t attr; sl@0: int rc=0; sl@0: struct sched_param param; sl@0: rc = pthread_attr_init(&attr;); sl@0: if(rc != 0) { sl@0: printf("pthread_attr_init failed sl@0: "); sl@0: return -1; sl@0: } sl@0: param.sched_priority = 50; sl@0: rc = pthread_attr_setschedparam(&attr;, & param); sl@0: if(rc != 0) { sl@0: printf("pthread_attr_setschedparam failed sl@0: "); sl@0: return -1; sl@0: } sl@0: /* Create thread */ sl@0: /* Destroy attribute */ sl@0: sl@0: @endcode sl@0: @code sl@0: /* ***************************************************** */ sl@0: /* Example for pthread_attr_setschedpolicy */ sl@0: /* ***************************************************** */ sl@0: pthread_attr_t attr; sl@0: int rc; sl@0: int policy = SCHED_RR; sl@0: if(pthread_attr_init(&attr;) != 0) { sl@0: printf("Error on pthread_attr_init() sl@0: "); sl@0: return -1; sl@0: } sl@0: sl@0: if((rc=pthread_attr_setschedpolicy(&attr;,policy)) != 0) { sl@0: printf("Error on pthread_attr_setschedpolicy() rc=%d sl@0: ", rc); sl@0: return -1; sl@0: } sl@0: /* Create thread */ sl@0: /* Destroy attribute */ sl@0: sl@0: @endcode sl@0: @code sl@0: /* ***************************************************** */ sl@0: /* Example for pthread_attr_setstacksize */ sl@0: /* ***************************************************** */ sl@0: pthread_attr_t attr; sl@0: int rc; sl@0: int policy = SCHED_RR; sl@0: if(pthread_attr_init(&attr;) != 0) { sl@0: printf("Error on pthread_attr_init() sl@0: "); sl@0: return -1; sl@0: } sl@0: sl@0: if((rc=pthread_attr_setstacksize(&attr;,8192)) != 0) { sl@0: printf("Error on pthread_attr_setstacksize() rc=%d sl@0: ", rc); sl@0: return -1; sl@0: } sl@0: /* Create thread */ sl@0: /* Destroy attribute */ sl@0: sl@0: @endcode sl@0: @code sl@0: /* ***************************************************** */ sl@0: /* Example for pthread_attr_setscope */ sl@0: /* ***************************************************** */ sl@0: pthread_attr_t attr; sl@0: int rc; sl@0: /* Initialize attr */ sl@0: rc = pthread_attr_init(&attr;); sl@0: if( rc != 0) { sl@0: perror("pthread_attr_init failed"); sl@0: return -1; sl@0: } sl@0: rc = pthread_attr_setscope(&attr;, PTHREAD_SCOPE_SYSTEM); sl@0: if (rc != 0 ) { sl@0: perror("PTHREAD_SCOPE_SYSTEM is not supported"); sl@0: return -1; sl@0: } sl@0: /* Create thread */ sl@0: /* Destroy attribute */ sl@0: sl@0: @endcode sl@0: @see pthread_create() sl@0: sl@0: sl@0: sl@0: sl@0: @publishedAll sl@0: @externallyDefinedApi sl@0: */ sl@0: sl@0: /** @fn pthread_attr_destroy(pthread_attr_t *attrib) sl@0: @param attrib sl@0: Refer pthread_attr_init() for the documentation sl@0: @see pthread_create() sl@0: sl@0: sl@0: sl@0: sl@0: @publishedAll sl@0: @externallyDefinedApi sl@0: */ sl@0: sl@0: /** @fn pthread_attr_getdetachstate(const pthread_attr_t *attrib, int *detState) sl@0: @param attrib sl@0: @param detState sl@0: Refer pthread_attr_init() for the documentation sl@0: @see pthread_create() sl@0: sl@0: sl@0: sl@0: sl@0: @publishedAll sl@0: @externallyDefinedApi sl@0: */ sl@0: sl@0: /** @fn pthread_attr_setdetachstate(pthread_attr_t *attrib, int detState) sl@0: @param attrib sl@0: @param detState sl@0: Refer pthread_attr_init() for the documentation sl@0: @see pthread_create() sl@0: sl@0: sl@0: sl@0: sl@0: @publishedAll sl@0: @externallyDefinedApi sl@0: */ sl@0: sl@0: /** @fn pthread_attr_getstacksize(const pthread_attr_t *attrib, size_t *stkSize) sl@0: @param attrib sl@0: @param stkSize sl@0: Refer pthread_attr_init() for the documentation sl@0: @see pthread_create() sl@0: sl@0: sl@0: sl@0: sl@0: @publishedAll sl@0: @externallyDefinedApi sl@0: */ sl@0: sl@0: /** @fn pthread_attr_setstacksize(pthread_attr_t *attrib, size_t stkSize) sl@0: @param attrib sl@0: @param stkSize sl@0: Refer pthread_attr_init() for the documentation sl@0: @see pthread_create() sl@0: sl@0: sl@0: sl@0: sl@0: @publishedAll sl@0: @externallyDefinedApi sl@0: */ sl@0: sl@0: /** @fn pthread_once(pthread_once_t *once_control, thread_init_routine init_routine) sl@0: @param once_control sl@0: @param init_routine sl@0: @return If successful, the pthread_once function will return zero. sl@0: Otherwise an error number will be returned to sl@0: indicate the error. sl@0: sl@0: The first call to pthread_once by any thread in a process, with a given once_control , sl@0: will call the init_routine with no arguments. sl@0: Subsequent calls to pthread_once with the same once_control will not call the init_routine . sl@0: On return from pthread_once , sl@0: it is guaranteed that init_routine has completed. sl@0: The once_control parameter is used to determine whether the associated initialization sl@0: routine has been called. sl@0: sl@0: The constant PTHREAD_ONCE_INIT is defined by header \#include \ . sl@0: sl@0: The behavior of pthread_once is undefined if once_control has automatic storage duration or is not initialized by PTHREAD_ONCE_INIT . sl@0: sl@0: Examples: sl@0: @code sl@0: /* The init function that pthread_once calls */ sl@0: void an_init_func_1_1() sl@0: { sl@0: printf (" Initialized .. sl@0: "); sl@0: } sl@0: int XYZ() sl@0: { sl@0: pthread_once_t once_control = PTHREAD_ONCE_INIT; sl@0: /* Call pthread_once, passing it the once_control */ sl@0: pthread_once(&once;_control, an_init_func_1_1); sl@0: /* Call pthread_once again. The init function should not be sl@0: * called. */ sl@0: pthread_once(&once;_control, an_init_func_1_1); sl@0: } sl@0: sl@0: @endcode sl@0: sl@0: sl@0: @publishedAll sl@0: @externallyDefinedApi sl@0: */ sl@0: sl@0: /** @fn pthread_mutexattr_init(pthread_mutexattr_t *attr) sl@0: @param attr sl@0: Note: This description also covers the following functions - sl@0: pthread_mutexattr_destroy() pthread_mutexattr_settype() pthread_mutexattr_gettype() pthread_mutexattr_getpshared() pthread_mutexattr_setpshared() sl@0: sl@0: @return If successful, these functions return 0. sl@0: Otherwise, an error number is returned to indicate the error. sl@0: sl@0: Mutex attributes are used to specify parameters to pthread_mutex_init . sl@0: One attribute object can be used in multiple calls to pthread_mutex_init , sl@0: with or without modifications between calls. sl@0: sl@0: The pthread_mutexattr_init function initializes attr with all the default mutex attributes. sl@0: sl@0: The pthread_mutexattr_destroy function destroys attr . sl@0: sl@0: The pthread_mutexattr_set* functions set the attribute that corresponds to each function name. sl@0: sl@0: The pthread_mutexattr_get* functions copy the value of the attribute that corresponds to each function name sl@0: to the location pointed to by the second function parameter. sl@0: sl@0: Examples: sl@0: @code sl@0: pthread_mutexattr_t mta; sl@0: int rc; sl@0: /* Initialize a mutex attributes object */ sl@0: if((rc=pthread_mutexattr_init(&mta;)) != 0) sl@0: { sl@0: fprintf(stderr,"Cannot initialize mutex attributes object sl@0: "); sl@0: return -1; sl@0: } sl@0: /* Destroy the mutex attributes object */ sl@0: if(pthread_mutexattr_destroy(&mta;) != 0) sl@0: { sl@0: fprintf(stderr,"Error at pthread_mutexattr_destroy(), rc=%d sl@0: ", rc); sl@0: return -1; sl@0: } sl@0: sl@0: @endcode sl@0: @code sl@0: pthread_mutexattr_t mta; sl@0: int pshared; sl@0: /* Initialize a mutex attributes object */ sl@0: if(pthread_mutexattr_init(&mta;) != 0) sl@0: { sl@0: perror("Error at pthread_mutexattr_init() sl@0: "); sl@0: return -1; sl@0: } sl@0: /* The default 'pshared' attribute is PTHREAD_PROCESS_PRIVATE */ sl@0: if(pthread_mutexattr_getpshared(&mta;, &pshared;) != 0) sl@0: { sl@0: fprintf(stderr,"Error obtaining the attribute process-shared sl@0: "); sl@0: return -1; sl@0: } sl@0: if (pshared != PTHREAD_PROCESS_PRIVATE) sl@0: printf (" pshared is NOT PTHREAD_PROCESS_PRIVATE sl@0: "); sl@0: sl@0: @endcode sl@0: @code sl@0: pthread_mutexattr_t mta; sl@0: int type; sl@0: /* Initialize a mutex attributes object */ sl@0: if(pthread_mutexattr_init(&mta;) != 0) sl@0: { sl@0: perror("Error at pthread_mutexattr_init() sl@0: "); sl@0: return -1; sl@0: } sl@0: /* The default 'type' attribute is PTHREAD_MUTEX_DEFAULT */ sl@0: if(pthread_mutexattr_gettype(&mta;, &type;) != 0) sl@0: { sl@0: fprintf(stderr,"pthread_mutexattr_gettype(): Error obtaining the attribute 'type' sl@0: "); sl@0: return -1; sl@0: } sl@0: if(type != PTHREAD_MUTEX_DEFAULT) sl@0: { sl@0: printf("FAILED: Incorrect default mutexattr 'type' value: %d sl@0: ", type); sl@0: return -1; sl@0: } sl@0: sl@0: @endcode sl@0: @code sl@0: pthread_mutexattr_t mta; sl@0: int rc; sl@0: /* Initialize a mutex attributes object */ sl@0: if((rc=pthread_mutexattr_init(&mta;)) != 0) sl@0: { sl@0: fprintf(stderr,"Cannot initialize mutex attributes object sl@0: "); sl@0: return -1; sl@0: } sl@0: /* Destroy the mutex attributes object */ sl@0: if(pthread_mutexattr_destroy(&mta;) != 0) sl@0: { sl@0: fprintf(stderr,"Error at pthread_mutexattr_destroy(), rc=%d sl@0: ", rc); sl@0: return -1; sl@0: } sl@0: sl@0: @endcode sl@0: @code sl@0: pthread_mutexattr_t mta; sl@0: int ret; sl@0: /* Initialize a mutex attributes object */ sl@0: if(pthread_mutexattr_init(&mta;) != 0) sl@0: { sl@0: perror("Error at pthread_mutexattr_init() sl@0: "); sl@0: return -1; sl@0: } sl@0: /* Set the 'pshared' attribute to PTHREAD_PROCESS_PRIVATE */ sl@0: if((ret=pthread_mutexattr_setpshared(&mta;, PTHREAD_PROCESS_PRIVATE)) != 0) sl@0: { sl@0: printf("FAILED: Cannot set pshared attribute to PTHREAD_PROCESS_PRIVATE. Error: %d sl@0: ", ret); sl@0: return -1; sl@0: } sl@0: sl@0: @endcode sl@0: @code sl@0: pthread_mutexattr_t mta; sl@0: int type; sl@0: /* Initialize a mutex attributes object */ sl@0: if(pthread_mutexattr_init(&mta;) != 0) sl@0: { sl@0: perror("Error at pthread_mutexattr_init() sl@0: "); sl@0: return -1; sl@0: } sl@0: if(pthread_mutexattr_gettype(&mta;, &type;) != 0) sl@0: { sl@0: printf("Error getting the attribute 'type' sl@0: "); sl@0: return -1; sl@0: } sl@0: if(type != PTHREAD_MUTEX_DEFAULT) sl@0: { sl@0: printf("FAILED: Default value of the 'type' attribute is not PTHREAD_MUTEX_DEFAULT sl@0: "); sl@0: return -1; sl@0: } sl@0: if(pthread_mutexattr_settype(&mta;, PTHREAD_MUTEX_NORMAL) != 0) sl@0: { sl@0: printf("FAILED: Error setting the attribute 'type' sl@0: "); sl@0: return -1; sl@0: } sl@0: sl@0: @endcode sl@0: @see pthread_mutex_init() sl@0: sl@0: sl@0: sl@0: sl@0: @publishedAll sl@0: @externallyDefinedApi sl@0: */ sl@0: sl@0: /** @fn pthread_mutexattr_destroy(pthread_mutexattr_t *attr) sl@0: @param attr sl@0: Refer pthread_mutexattr_init() for the documentation sl@0: @see pthread_mutex_init() sl@0: sl@0: sl@0: sl@0: sl@0: @publishedAll sl@0: @externallyDefinedApi sl@0: */ sl@0: sl@0: /** @fn pthread_mutexattr_getpshared(const pthread_mutexattr_t *attr, int *pshared) sl@0: @param attr sl@0: @param pshared sl@0: Refer pthread_mutexattr_init() for the documentation sl@0: @see pthread_mutex_init() sl@0: sl@0: sl@0: sl@0: sl@0: @publishedAll sl@0: @externallyDefinedApi sl@0: */ sl@0: sl@0: /** @fn pthread_mutexattr_gettype(pthread_mutexattr_t *attr, int *type) sl@0: @param attr sl@0: @param type sl@0: Refer pthread_mutexattr_init() for the documentation sl@0: @see pthread_mutex_init() sl@0: sl@0: sl@0: sl@0: sl@0: @publishedAll sl@0: @externallyDefinedApi sl@0: */ sl@0: sl@0: /** @fn pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type) sl@0: @param attr sl@0: @param type # use integer valuses between 1 and 10 sl@0: Refer pthread_mutexattr_init() for the documentation sl@0: @see pthread_mutex_init() sl@0: sl@0: sl@0: sl@0: sl@0: @publishedAll sl@0: @externallyDefinedApi sl@0: */ sl@0: sl@0: /** @fn pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr) sl@0: @param mutex sl@0: @param attr sl@0: @return If successful, pthread_mutex_init will return zero and put the new mutex id into mutex , sl@0: otherwise an error number will be returned to indicate the error. sl@0: sl@0: The pthread_mutex_init function creates a new mutex, with attributes specified with attr . sl@0: If attr is NULL the default attributes are used. sl@0: sl@0: Examples: sl@0: @code sl@0: pthread_mutex_t mutex; sl@0: int XYZ() sl@0: { sl@0: int rc; sl@0: /* Initialize a mutex object with the default mutex attributes */ sl@0: if((rc=pthread_mutex_init(&mutex;,NULL)) != 0) sl@0: { sl@0: fprintf(stderr,"Error at pthread_mutex_init(), rc=%d0,rc); sl@0: return -1; sl@0: } sl@0: } sl@0: sl@0: @endcode sl@0: @see pthread_mutex_destroy() sl@0: @see pthread_mutex_lock() sl@0: @see pthread_mutex_trylock() sl@0: @see pthread_mutex_unlock() sl@0: sl@0: sl@0: sl@0: sl@0: @publishedAll sl@0: @externallyDefinedApi sl@0: */ sl@0: sl@0: /** @fn pthread_mutex_destroy(pthread_mutex_t *mutex) sl@0: @param mutex sl@0: @return If successful, pthread_mutex_destroy will return zero, otherwise an error number will be returned to sl@0: indicate the error. sl@0: sl@0: The pthread_mutex_destroy function frees the resources allocated for mutex . sl@0: sl@0: Examples: sl@0: @code sl@0: pthread_mutexattr_t mta; sl@0: int rc; sl@0: /* Initialize a mutex attributes object */ sl@0: if((rc=pthread_mutexattr_init(&mta;)) != 0) { sl@0: fprintf(stderr,"Error at pthread_mutexattr_init(), rc=%d sl@0: ",rc); sl@0: return -1; sl@0: } sl@0: /* Destroy the mutex attributes object */ sl@0: if((rc=pthread_mutexattr_destroy(&mta;)) != 0) { sl@0: fprintf(stderr,"Error at pthread_mutexattr_destroy(), rc=%d sl@0: ",rc); sl@0: return -1; sl@0: } sl@0: sl@0: @endcode sl@0: @see pthread_mutex_init() sl@0: @see pthread_mutex_lock() sl@0: @see pthread_mutex_trylock() sl@0: @see pthread_mutex_unlock() sl@0: sl@0: sl@0: sl@0: sl@0: @publishedAll sl@0: @externallyDefinedApi sl@0: */ sl@0: sl@0: /** @fn pthread_mutex_lock(pthread_mutex_t *mutex) sl@0: @param mutex sl@0: @return If successful, pthread_mutex_lock will return zero, otherwise an error number will be returned to sl@0: indicate the error. sl@0: sl@0: The pthread_mutex_lock function locks mutex . sl@0: If the mutex is already locked, the calling thread will block until the sl@0: mutex becomes available. sl@0: sl@0: Examples: sl@0: @code sl@0: pthread_mutex_t mutex; sl@0: int XYZ() sl@0: { sl@0: int rc; sl@0: /* Initialize a mutex object with the default mutex attributes */ sl@0: if((rc=pthread_mutex_init(&mutex;,NULL)) != 0) { sl@0: fprintf(stderr,"Error at pthread_mutex_init(), rc=%d sl@0: ",rc); sl@0: return -1; sl@0: } sl@0: /* Lock the mutex using pthread_mutex_lock() */ sl@0: if((rc=pthread_mutex_lock(&mutex;)) == 0) { sl@0: printf(" lock is successful sl@0: "); sl@0: } sl@0: } sl@0: sl@0: @endcode sl@0: @see pthread_mutex_destroy() sl@0: @see pthread_mutex_init() sl@0: @see pthread_mutex_trylock() sl@0: @see pthread_mutex_unlock() sl@0: sl@0: sl@0: sl@0: sl@0: @publishedAll sl@0: @externallyDefinedApi sl@0: */ sl@0: sl@0: /** @fn pthread_mutex_timedlock(pthread_mutex_t *mutex, const struct timespec *abstime) sl@0: @param mutex sl@0: @param abstime sl@0: @return If successful, pthread_mutex_timedlock will return zero, otherwise an error number will be returned to sl@0: indicate the error. sl@0: sl@0: The pthread_mutex_timedlock function will lock mutex . sl@0: If it is already locked the calling thread will block until sl@0: the mutex becomes available or sl@0: the timeout, sl@0: specified by abstime, sl@0: expires. sl@0: The time of the timeout is an absolute time and sl@0: is not relative to the current time. sl@0: sl@0: Examples: sl@0: @code sl@0: #include sl@0: #define TIMEOUT 3 sl@0: /* 3 seconds of timeout time for pthread_mutex_timedlock(). */ sl@0: struct timespec timeout; sl@0: struct timeval currsec1; sl@0: int rc; sl@0: pthread_mutex_t mutex; sl@0: sl@0: sl@0: /* Get the current time before the mutex locked. */ sl@0: gettimeofday(&currsec1;, NULL); sl@0: /* Absolute time, not relative. */ sl@0: timeout.tv_sec = currsec1.tv_sec + TIMEOUT; sl@0: timeout.tv_nsec = currsec1.tv_usec * 1000; sl@0: printf("Timed mutex lock will block for %d seconds starting from: %ld.%06ld sl@0: ", TIMEOUT, (long)currsec1.tv_sec, (long)currsec1.tv_usec); sl@0: rc = pthread_mutex_timedlock(&mutex;, &timeout;); sl@0: if(rc != 0) { sl@0: if (rc == ETIMEDOUT) { sl@0: fprintf(stderr,"Thread stops waiting when time is out sl@0: "); sl@0: } sl@0: else { sl@0: fprintf(stderr,"pthread_mutex_timedwait return %d sl@0: ", rc); sl@0: } sl@0: } sl@0: fprintf(stderr,"Thread wakened up sl@0: "); sl@0: sl@0: @endcode sl@0: @see pthread_mutex_destroy() sl@0: @see pthread_mutex_init() sl@0: @see pthread_mutex_lock() sl@0: @see pthread_mutex_trylock() sl@0: @see pthread_mutex_unlock() sl@0: sl@0: sl@0: sl@0: sl@0: @publishedAll sl@0: @externallyDefinedApi sl@0: */ sl@0: sl@0: /** @fn pthread_mutex_trylock(pthread_mutex_t *mutex) sl@0: @param mutex sl@0: @return If successful, pthread_mutex_trylock will return zero, otherwise an error number will be returned to sl@0: indicate the error. sl@0: sl@0: The pthread_mutex_trylock function locks mutex . sl@0: If the mutex is already locked, pthread_mutex_trylock will not block waiting for the mutex, but will return an error condition. sl@0: sl@0: Examples: sl@0: @code sl@0: int rc; sl@0: pthread_mutex_t mutex; sl@0: rc = pthread_mutex_trylock(&mutex;); sl@0: switch (rc) sl@0: { sl@0: case 0: sl@0: printf ("Locked successfully sl@0: "); sl@0: break; sl@0: case EAGAIN: sl@0: printf ("could not lock, try later..... sl@0: "); sl@0: break; sl@0: } sl@0: sl@0: @endcode sl@0: @see pthread_mutex_destroy() sl@0: @see pthread_mutex_init() sl@0: @see pthread_mutex_lock() sl@0: @see pthread_mutex_unlock() sl@0: sl@0: sl@0: sl@0: sl@0: @publishedAll sl@0: @externallyDefinedApi sl@0: */ sl@0: sl@0: /** @fn pthread_mutex_unlock(pthread_mutex_t *mutex) sl@0: @param mutex sl@0: @return If successful, pthread_mutex_unlock will return zero, otherwise an error number will be returned to sl@0: indicate the error. sl@0: sl@0: If the current thread holds the lock on mutex , sl@0: then the pthread_mutex_unlock function unlocks mutex . sl@0: sl@0: Examples: sl@0: @code sl@0: static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; sl@0: int XYZ() sl@0: { sl@0: int rc; sl@0: /* Get the mutex using pthread_mutex_lock() */ sl@0: if((rc=pthread_mutex_lock(&mutex;)) != 0) { sl@0: fprintf(stderr,"Error at pthread_mutex_lock(), rc=%d sl@0: ",rc); sl@0: return -1; sl@0: } sl@0: /* Release the mutex using pthread_mutex_unlock() */ sl@0: if((rc=pthread_mutex_unlock(&mutex;)) != 0) { sl@0: printf("unlock failed sl@0: "); sl@0: return -1; sl@0: } sl@0: sl@0: @endcode sl@0: @see pthread_mutex_destroy() sl@0: @see pthread_mutex_init() sl@0: @see pthread_mutex_lock() sl@0: @see pthread_mutex_trylock() sl@0: sl@0: sl@0: sl@0: sl@0: @publishedAll sl@0: @externallyDefinedApi sl@0: */ sl@0: sl@0: /** @fn pthread_condattr_init(pthread_condattr_t *) sl@0: sl@0: Note: This description also covers the following functions - sl@0: pthread_condattr_destroy() sl@0: sl@0: @return If successful, these functions return 0. sl@0: Otherwise, an error number is returned to indicate the error. sl@0: sl@0: Condition attribute objects are used to specify parameters to pthread_cond_init . sl@0: Current implementation of conditional variables does not support any sl@0: attributes, so these functions are not very useful. sl@0: sl@0: The pthread_condattr_init function initializes a condition attribute object with the default sl@0: attributes.(As of now None) sl@0: sl@0: The pthread_condattr_destroy function destroys a condition attribute object. sl@0: sl@0: Examples: sl@0: @code sl@0: pthread_condattr_t condattr; sl@0: int rc; sl@0: /* Initialize a condition variable attributes object */ sl@0: if((rc=pthread_condattr_init(&condattr;)) != 0) sl@0: { sl@0: fprintf(stderr,"Cannot initialize condition variable attributes object sl@0: "); sl@0: return -1; sl@0: } sl@0: /* Destroy the condition variable attributes object */ sl@0: if(pthread_condattr_destroy(&condattr;) != 0) sl@0: { sl@0: fprintf(stderr,"Error at pthread_condattr_destroy(), rc=%d sl@0: ", rc); sl@0: return -1; sl@0: } sl@0: sl@0: @endcode sl@0: @see pthread_cond_init() sl@0: sl@0: sl@0: sl@0: sl@0: @publishedAll sl@0: @externallyDefinedApi sl@0: */ sl@0: sl@0: /** @fn pthread_condattr_destroy(pthread_condattr_t *) sl@0: sl@0: Refer pthread_condattr_init() for the documentation sl@0: @see pthread_cond_init() sl@0: sl@0: sl@0: sl@0: sl@0: @publishedAll sl@0: @externallyDefinedApi sl@0: */ sl@0: sl@0: /** @fn pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *) sl@0: @param cond sl@0: @param # represents the parameter attr sl@0: @return If successful, the pthread_cond_init function will return zero and put the new condition variable id into cond , sl@0: otherwise an error number will be returned to indicate the error. sl@0: sl@0: The pthread_cond_init function creates a new condition variable referenced sl@0: by cond with attributes referenced by attr. If attr is NULL, the default condition variable attributes will be used. sl@0: Upon successful initialization, the state of the condition variable will be initialized. sl@0: sl@0: Examples: sl@0: @code sl@0: int rc; sl@0: struct testdata sl@0: { sl@0: pthread_mutex_t mutex; sl@0: pthread_cond_t cond; sl@0: }; sl@0: static struct testdata td; sl@0: int function1() sl@0: { sl@0: /* Initialize a condition variable object */ sl@0: if (pthread_cond_init(&td.cond;, NULL) != 0) { sl@0: fprintf(stderr,"Fail to initialize cond sl@0: "); sl@0: return -1; sl@0: } sl@0: /* ... Use it for wait, signal, broadcast */ sl@0: /* Destroy the condition variable object */ sl@0: if((rc=pthread_cond_destroy(&td.cond;)) != 0) sl@0: { sl@0: fprintf(stderr,"Error at pthread_cond_destroy(), rc=%d sl@0: ",rc); sl@0: return -1; sl@0: } sl@0: } sl@0: sl@0: @endcode sl@0: @see pthread_cond_broadcast() sl@0: @see pthread_cond_destroy() sl@0: @see pthread_cond_signal() sl@0: @see pthread_cond_timedwait() sl@0: @see pthread_cond_wait() sl@0: sl@0: sl@0: sl@0: sl@0: @publishedAll sl@0: @externallyDefinedApi sl@0: */ sl@0: sl@0: /** @fn pthread_cond_destroy(pthread_cond_t *cond) sl@0: @param cond sl@0: @return If successful, the pthread_cond_destroy function will return zero, otherwise an error number will be returned sl@0: to indicate the error. sl@0: sl@0: The pthread_cond_destroy function frees the resources allocated by the condition variable cond . sl@0: sl@0: Examples: sl@0: @code sl@0: int rc; sl@0: struct testdata sl@0: { sl@0: pthread_mutex_t mutex; sl@0: pthread_cond_t cond; sl@0: }; sl@0: static struct testdata td; sl@0: int function1() sl@0: { sl@0: /* Initialize a condition variable object */ sl@0: if (pthread_cond_init(&td.cond;, NULL) != 0) { sl@0: fprintf(stderr,"Fail to initialize cond sl@0: "); sl@0: return -1; sl@0: } sl@0: /* ... Use it for wait, signal, broadcast */ sl@0: /* Destroy the condition variable object */ sl@0: if((rc=pthread_cond_destroy(&td.cond;)) != 0) sl@0: { sl@0: fprintf(stderr,"Error at pthread_cond_destroy(), rc=%d sl@0: ",rc); sl@0: return -1; sl@0: } sl@0: } sl@0: sl@0: @endcode sl@0: @see pthread_cond_broadcast() sl@0: @see pthread_cond_init() sl@0: @see pthread_cond_signal() sl@0: @see pthread_cond_timedwait() sl@0: @see pthread_cond_wait() sl@0: sl@0: sl@0: sl@0: sl@0: @publishedAll sl@0: @externallyDefinedApi sl@0: */ sl@0: sl@0: /** @fn pthread_cond_destroy(pthread_cond_t *cond) sl@0: @param cond sl@0: @return If successful, the pthread_cond_destroy function will return zero, otherwise an error number will be returned sl@0: to indicate the error. sl@0: sl@0: The pthread_cond_destroy function frees the resources allocated by the condition variable cond . sl@0: sl@0: Examples: sl@0: @code sl@0: int rc; sl@0: struct testdata sl@0: { sl@0: pthread_mutex_t mutex; sl@0: pthread_cond_t cond; sl@0: }; sl@0: static struct testdata td; sl@0: int function1() sl@0: { sl@0: /* Initialize a condition variable object */ sl@0: if (pthread_cond_init(&td.cond;, NULL) != 0) { sl@0: fprintf(stderr,"Fail to initialize cond sl@0: "); sl@0: return -1; sl@0: } sl@0: /* ... Use it for wait, signal, broadcast */ sl@0: /* Destroy the condition variable object */ sl@0: if((rc=pthread_cond_destroy(&td.cond;)) != 0) sl@0: { sl@0: fprintf(stderr,"Error at pthread_cond_destroy(), rc=%d sl@0: ",rc); sl@0: return -1; sl@0: } sl@0: } sl@0: sl@0: @endcode sl@0: @see pthread_cond_broadcast() sl@0: @see pthread_cond_init() sl@0: @see pthread_cond_signal() sl@0: @see pthread_cond_timedwait() sl@0: @see pthread_cond_wait() sl@0: sl@0: sl@0: sl@0: sl@0: @publishedAll sl@0: @externallyDefinedApi sl@0: */ sl@0: sl@0: /** @fn pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) sl@0: @param cond sl@0: @param mutex sl@0: @return If successful, the pthread_cond_wait function will return zero. sl@0: Otherwise an error number will be returned to sl@0: indicate the error. sl@0: sl@0: The pthread_cond_wait function atomically blocks the current thread waiting on the condition sl@0: variable specified by cond , sl@0: and unblocks the mutex specified by mutex . sl@0: The waiting thread unblocks only after another thread calls pthread_cond_signal , sl@0: or pthread_cond_broadcast with the same condition variable, and the current thread reacquires the lock sl@0: on mutex . sl@0: sl@0: Examples: sl@0: @code sl@0: struct testdata sl@0: { sl@0: pthread_mutex_t mutex; sl@0: pthread_cond_t cond; sl@0: }; sl@0: static struct testdata td; sl@0: int rc; sl@0: /* mutex and conditional variable must be initialized */ sl@0: if (pthread_mutex_lock(&td.mutex;) != 0) { sl@0: fprintf(stderr,"Thread failed to acquire mutex sl@0: "); sl@0: return -1; sl@0: } sl@0: fprintf(stderr,"Thread started sl@0: "); sl@0: fprintf(stderr,"Thread is waiting for the cond sl@0: "); sl@0: rc = pthread_cond_wait(&td.cond;, &td.mutex;); sl@0: if (rc != 0) { sl@0: fprintf(stderr,"pthread_cond_wait return %d sl@0: ", rc); sl@0: return -1; sl@0: } sl@0: fprintf(stderr,"Thread wakened sl@0: "); sl@0: pthread_mutex_unlock(&td.mutex;); sl@0: sl@0: @endcode sl@0: @see pthread_cond_broadcast() sl@0: @see pthread_cond_destroy() sl@0: @see pthread_cond_init() sl@0: @see pthread_cond_signal() sl@0: @see pthread_cond_timedwait() sl@0: sl@0: sl@0: sl@0: sl@0: @publishedAll sl@0: @externallyDefinedApi sl@0: */ sl@0: sl@0: /** @fn pthread_cond_signal(pthread_cond_t *cond) sl@0: @param cond sl@0: @return If successful, the pthread_cond_signal function will return zero, otherwise an error number will be returned sl@0: to indicate the error. sl@0: sl@0: The pthread_cond_signal function unblocks one thread waiting for the condition variable cond . sl@0: sl@0: Examples: sl@0: @code sl@0: int rc; sl@0: struct testdata sl@0: { sl@0: pthread_mutex_t mutex; sl@0: pthread_cond_t cond; sl@0: }; sl@0: static struct testdata td; sl@0: int function1() sl@0: { sl@0: if (pthread_mutex_init(&td.mutex;, NULL) != 0) { sl@0: fprintf(stderr,"Fail to initialize mutex sl@0: "); sl@0: return -1; sl@0: } sl@0: if (pthread_cond_init(&td.cond;, NULL) != 0) { sl@0: fprintf(stderr,"Fail to initialize cond sl@0: "); sl@0: return -1; sl@0: } sl@0: /* ....... other thread wait for signal */ sl@0: /* Acquire the mutex to make sure that all waiters are currently sl@0: blocked on pthread_cond_wait */ sl@0: if (pthread_mutex_lock(&td.mutex;) != 0) { sl@0: fprintf(stderr,"Main: Fail to acquire mutex sl@0: "); sl@0: return -1; sl@0: } sl@0: if (pthread_mutex_unlock(&td.mutex;) != 0) { sl@0: fprintf(stderr,"Main: Fail to release mutex sl@0: "); sl@0: return -1; sl@0: } sl@0: /* signal the condition to wake up all waiters */ sl@0: fprintf(stderr," signal the condition sl@0: "); sl@0: rc = pthread_cond_signal(&td.cond;); sl@0: if (rc != 0) { sl@0: fprintf(stderr," failed to signal the condition sl@0: "); sl@0: return -1; sl@0: } sl@0: } sl@0: sl@0: @endcode sl@0: @see pthread_cond_broadcast() sl@0: @see pthread_cond_destroy() sl@0: @see pthread_cond_init() sl@0: @see pthread_cond_timedwait() sl@0: @see pthread_cond_wait() sl@0: sl@0: sl@0: sl@0: sl@0: @publishedAll sl@0: @externallyDefinedApi sl@0: */ sl@0: sl@0: /** @fn pthread_cond_broadcast(pthread_cond_t *cond) sl@0: @param cond sl@0: @return If successful, the pthread_cond_broadcast function will return zero, otherwise an error number will be returned sl@0: to indicate the error. sl@0: sl@0: The pthread_cond_broadcast function unblocks all threads waiting for the condition variable cond . sl@0: sl@0: Examples: sl@0: @code sl@0: int rc; sl@0: struct testdata sl@0: { sl@0: pthread_mutex_t mutex; sl@0: pthread_cond_t cond; sl@0: }; sl@0: static struct testdata td; sl@0: if (pthread_mutex_init(&td.mutex;, NULL) != 0) { sl@0: fprintf(stderr,"Fail to initialize mutex sl@0: "); sl@0: return -1; sl@0: } sl@0: if (pthread_cond_init(&td.cond;, NULL) != 0) { sl@0: fprintf(stderr,"Fail to initialize cond sl@0: "); sl@0: return -1; sl@0: } sl@0: /* ....... other thread wait for signal */ sl@0: /* Acquire the mutex to make sure that all waiters are currently sl@0: blocked on pthread_cond_wait */ sl@0: if (pthread_mutex_lock(&td.mutex;) != 0) { sl@0: fprintf(stderr,"Main: Fail to acquire mutex sl@0: "); sl@0: return -1; sl@0: } sl@0: if (pthread_mutex_unlock(&td.mutex;) != 0) { sl@0: fprintf(stderr,"Main: Fail to release mutex sl@0: "); sl@0: return -1; sl@0: } sl@0: /* signal the condition to wake up all waiters */ sl@0: fprintf(stderr," signal the condition0); sl@0: rc = pthread_cond_broadcast(&td.cond;); sl@0: if (rc != 0) { sl@0: fprintf(stderr," failed to signal the condition sl@0: "); sl@0: return -1; sl@0: } sl@0: sl@0: @endcode sl@0: @see pthread_cond_destroy() sl@0: @see pthread_cond_init() sl@0: @see pthread_cond_signal() sl@0: @see pthread_cond_timedwait() sl@0: @see pthread_cond_wait() sl@0: sl@0: sl@0: sl@0: sl@0: @publishedAll sl@0: @externallyDefinedApi sl@0: */ sl@0: sl@0: /** @fn pthread_key_create(pthread_key_t *key, destructor_routine dest) sl@0: @param key sl@0: @param dest sl@0: @return If successful, the pthread_key_create function will store the newly created key value at the location specified by key and returns zero. sl@0: Otherwise an error number will be returned to indicate sl@0: the error. sl@0: sl@0: The pthread_key_create function creates a thread-specific data key visible to all threads in the sl@0: process. sl@0: Key values provided by pthread_key_create are opaque objects used to locate thread-specific data. sl@0: Although the same sl@0: key value may be used by different threads, the values bound to the key sl@0: by pthread_setspecific are maintained on a per-thread basis and persist for the life of the calling sl@0: thread. sl@0: sl@0: Upon key creation, the value NULL is associated with the new key in all sl@0: active threads. sl@0: Upon thread creation, the value NULL is associated with all sl@0: defined keys in the new thread. sl@0: sl@0: An optional destructor function dest may be associated with each key value. sl@0: At sl@0: thread exit, if a key value has a non-NULL destructor pointer, and the sl@0: thread has a non-NULL value associated with the key, the function pointed sl@0: to is called with the current associated value as its sole argument. sl@0: The sl@0: order of destructor calls is unspecified if more than one destructor exists sl@0: for a thread when it exits. sl@0: sl@0: If, after all the destructors have been called for all non-NULL values sl@0: with associated destructors, there are still some non-NULL values with sl@0: associated destructors, then the process is repeated. sl@0: If, after at least sl@0: [PTHREAD_DESTRUCTOR_ITERATIONS] iterations of destructor calls for sl@0: outstanding non-NULL values, there are still some non-NULL values with sl@0: associated destructors, the implementation stops calling destructors. sl@0: sl@0: Examples: sl@0: @code sl@0: pthread_key_t keys; sl@0: if(pthread_key_create(&keys;, NULL) != 0) sl@0: { sl@0: printf("Error: pthread_key_create() failed sl@0: "); sl@0: return -1; sl@0: } sl@0: sl@0: @endcode sl@0: @see pthread_getspecific() sl@0: @see pthread_key_delete() sl@0: @see pthread_setspecific() sl@0: sl@0: sl@0: sl@0: sl@0: @publishedAll sl@0: @externallyDefinedApi sl@0: */ sl@0: sl@0: /** @fn pthread_key_delete(pthread_key_t key) sl@0: @param key sl@0: @return If successful, the pthread_key_delete function will return zero. sl@0: Otherwise an error number will be returned to sl@0: indicate the error. sl@0: sl@0: The pthread_key_delete function deletes a thread-specific data key previously returned by pthread_key_create . sl@0: The thread-specific data values associated with key need not be NULL at the time that pthread_key_delete is called. sl@0: It is the responsibility of the application to free any sl@0: application storage or perform any cleanup actions for data structures sl@0: related to the deleted key or associated thread-specific data in any threads; sl@0: this cleanup can be done either before or after pthread_key_delete is called. sl@0: Any attempt to use key following the call to pthread_key_delete results in undefined behavior. sl@0: sl@0: The pthread_key_delete function is callable from within destructor functions. sl@0: Destructor functions sl@0: are not invoked by pthread_key_delete . sl@0: Any destructor function that may have been associated with key will no longer be called upon thread exit. sl@0: sl@0: Examples: sl@0: @code sl@0: pthread_key_t keys; sl@0: if(pthread_key_create(&keys;, NULL) != 0) sl@0: { sl@0: printf("Error: pthread_key_create() failed sl@0: "); sl@0: return -1; sl@0: } sl@0: if(pthread_key_delete(keys) != 0) sl@0: { sl@0: printf("Error: pthread_key_delete() failed sl@0: "); sl@0: return -1; sl@0: } sl@0: sl@0: @endcode sl@0: @see pthread_getspecific() sl@0: @see pthread_key_create() sl@0: @see pthread_setspecific() sl@0: sl@0: sl@0: sl@0: sl@0: @publishedAll sl@0: @externallyDefinedApi sl@0: */ sl@0: sl@0: /** @fn pthread_setspecific(pthread_key_t key, const void *value) sl@0: @param key sl@0: @param value sl@0: @return If successful, the pthread_setspecific function will return zero. sl@0: Otherwise an error number will be returned to sl@0: indicate the error. sl@0: sl@0: The pthread_setspecific function associates a thread-specific value with a key obtained via a previous call to pthread_key_create . sl@0: Different threads can bind different values to the same key. sl@0: These values are sl@0: typically pointers to blocks of dynamically allocated memory that have been sl@0: reserved for use by the calling thread. sl@0: sl@0: The effect of calling pthread_setspecific with a key value not obtained from pthread_key_create or after key has been deleted with pthread_key_delete is undefined. sl@0: sl@0: The pthread_setspecific function may be called from a thread-specific data destructor function, sl@0: however this may result in lost storage or infinite loops. sl@0: sl@0: Examples: sl@0: @code sl@0: pthread_key_t keys; sl@0: void* rc; sl@0: if(pthread_key_create(&keys;, NULL) != 0) sl@0: { sl@0: printf("Error: pthread_key_create() failed sl@0: "); sl@0: return -1; sl@0: } else sl@0: { sl@0: if(pthread_setspecific(keys, (void *)(long)(100)) != 0) sl@0: { sl@0: printf("Error: pthread_setspecific() failed sl@0: "); sl@0: return -1; sl@0: } sl@0: } sl@0: sl@0: @endcode sl@0: @see pthread_getspecific() sl@0: @see pthread_key_create() sl@0: @see pthread_key_delete() sl@0: sl@0: sl@0: sl@0: sl@0: @publishedAll sl@0: @externallyDefinedApi sl@0: */ sl@0: sl@0: /** @fn pthread_getspecific(pthread_key_t key) sl@0: @param key sl@0: @return The pthread_getspecific function will return the thread-specific data value associated with the given key . sl@0: If no thread-specific data value is associated with key , sl@0: then the value NULL is returned. sl@0: sl@0: The pthread_getspecific function returns the value currently bound to the specified key on behalf of the calling thread. sl@0: sl@0: The effect of calling pthread_getspecific with a key value not obtained from pthread_key_create or after key has been deleted with pthread_key_delete is undefined. sl@0: sl@0: The pthread_getspecific function may be called from a thread-specific data destructor function. sl@0: sl@0: Examples: sl@0: @code sl@0: pthread_key_t keys; sl@0: void* rc; sl@0: if(pthread_key_create(&keys;, NULL) != 0) sl@0: { sl@0: printf("Error: pthread_key_create() failed0); sl@0: return -1; sl@0: } else sl@0: { sl@0: if(pthread_setspecific(keys, (void *)(long)(100)) != 0) sl@0: { sl@0: printf("Error: pthread_setspecific() failed sl@0: "); sl@0: return -1; sl@0: } sl@0: } sl@0: rc = pthread_getspecific(keys); sl@0: if(rc != (void *)(long)(100)) sl@0: { sl@0: printf("getspecific failed sl@0: "); sl@0: return -1; sl@0: } sl@0: sl@0: @endcode sl@0: @see pthread_key_create() sl@0: @see pthread_key_delete() sl@0: @see pthread_setspecific() sl@0: sl@0: sl@0: sl@0: sl@0: @publishedAll sl@0: @externallyDefinedApi sl@0: */ sl@0: sl@0: /** @fn pthread_attr_getscope(const pthread_attr_t *attrib, int *scope) sl@0: @param attrib sl@0: @param scope sl@0: Refer pthread_attr_init() for the documentation sl@0: @see pthread_create() sl@0: sl@0: sl@0: sl@0: sl@0: @publishedAll sl@0: @externallyDefinedApi sl@0: */ sl@0: sl@0: /** @fn pthread_attr_setscope(pthread_attr_t *attrib, int conscope) sl@0: @param attrib sl@0: @param conscope sl@0: Refer pthread_attr_init() for the documentation sl@0: @see pthread_create() sl@0: sl@0: sl@0: sl@0: sl@0: @publishedAll sl@0: @externallyDefinedApi sl@0: */ sl@0: sl@0: /** @fn pthread_attr_setschedpolicy(pthread_attr_t *attrib, int policy) sl@0: @param attrib sl@0: @param policy sl@0: Refer pthread_attr_init() for the documentation sl@0: @see pthread_create() sl@0: sl@0: sl@0: sl@0: sl@0: @publishedAll sl@0: @externallyDefinedApi sl@0: */ sl@0: sl@0: /** @fn pthread_attr_getschedpolicy(const pthread_attr_t *attrib, int *policy) sl@0: @param attrib sl@0: @param policy sl@0: Refer pthread_attr_init() for the documentation sl@0: @see pthread_create() sl@0: sl@0: sl@0: sl@0: sl@0: @publishedAll sl@0: @externallyDefinedApi sl@0: */ sl@0: sl@0: /** @fn pthread_attr_getschedparam(const pthread_attr_t *attrib, struct sched_param *param) sl@0: @param attrib sl@0: @param param sl@0: Refer pthread_attr_init() for the documentation sl@0: @see pthread_create() sl@0: sl@0: sl@0: sl@0: sl@0: @publishedAll sl@0: @externallyDefinedApi sl@0: */ sl@0: sl@0: /** @fn pthread_attr_setschedparam(pthread_attr_t *attrib, const struct sched_param *param) sl@0: @param attrib sl@0: @param param sl@0: Refer pthread_attr_init() for the documentation sl@0: @see pthread_create() sl@0: sl@0: sl@0: sl@0: sl@0: @publishedAll sl@0: @externallyDefinedApi sl@0: */ sl@0: sl@0: /** @fn pthread_getschedparam(pthread_t thr, int *policy, struct sched_param *param) sl@0: @param thr sl@0: @param policy sl@0: @param param sl@0: Refer pthread_setschedparam() for the documentation sl@0: sl@0: sl@0: sl@0: sl@0: @publishedAll sl@0: @externallyDefinedApi sl@0: */ sl@0: sl@0: /** @fn pthread_setschedparam(pthread_t thread, int policy, const struct sched_param *param) sl@0: @param thread sl@0: @param policy sl@0: @param param sl@0: Note: This description also covers the following functions - sl@0: pthread_getschedparam() sl@0: sl@0: @return If successful, these functions return 0. sl@0: Otherwise, an error number is returned to indicate the error. sl@0: sl@0: The pthread_setschedparam and pthread_getschedparam functions set and get the scheduling parameters of individual threads. sl@0: The scheduling policy for a thread will be SCHED_RR (round-robin). ( SCHED_FIFO is not supported) sl@0: The thread priority (accessed via param-\>sched_priority ) sl@0: must be at least PTHREAD_MIN_PRIORITY and no more than PTHREAD_MAX_PRIORITY(as returned by sched_get_priority_max() and sched_get_priority_min() APIs) . sl@0: sl@0: Examples: sl@0: @code sl@0: struct sched_param sparam; sl@0: int policy, priority, policy_1; sl@0: int rc; sl@0: policy = SCHED_RR; sl@0: priority = 50; sl@0: sparam.sched_priority = priority; sl@0: rc = pthread_setschedparam(pthread_self(), policy, &sparam;); sl@0: if (rc != 0) sl@0: { sl@0: printf("Error at pthread_setschedparam: rc=%d sl@0: ", rc); sl@0: return -1; sl@0: } sl@0: sl@0: @endcode sl@0: @code sl@0: int e ; sl@0: struct sched_param param; sl@0: pthread_t thread; // Thread which will be assigned the scheduling priority and the policy. sl@0: pthread_t thread = pthread_self(); sl@0: param.sched_priority = 100; sl@0: sl@0: e = pthread_setschedparam(thread,SCHED_RR, & param); sl@0: if(e != 0) sl@0: { sl@0: printf("setting scheduling policy and priority failed.")); sl@0: return -1; sl@0: } sl@0: sl@0: @endcode sl@0: @code sl@0: int e ; sl@0: struct sched_param param; sl@0: pthread_t thread; // Thread which will be assigned the scheduling priority and the policy. sl@0: int policy; sl@0: pthread_t thread = pthread_self(); sl@0: param.sched_priority = 100; sl@0: sl@0: e = pthread_setschedparam(thread,SCHED_RR, & param); sl@0: if(e != 0) sl@0: { sl@0: printf("setting scheduling policy and priority failed.")); sl@0: return -1; sl@0: } sl@0: e = pthread_getschedparam(thread,&policy;,& param); sl@0: if (e != 0) sl@0: { sl@0: printf("getting scheduling policy and priority failed.")); sl@0: return -1; sl@0: } sl@0: sl@0: @endcode sl@0: sl@0: sl@0: @publishedAll sl@0: @externallyDefinedApi sl@0: */ sl@0: sl@0: sl@0: /** @fn pthread_cond_timedwait(pthread_cond_t * cond,pthread_mutex_t * mutex,const struct timespec *abstime) sl@0: @param cond sl@0: @param mutex sl@0: @param abstime sl@0: @return If successful, the pthread_cond_timedwait function will return zero. sl@0: Otherwise an error number will be returned to sl@0: indicate the error. sl@0: sl@0: The pthread_cond_timedwait function atomically blocks the current thread waiting on the condition, sl@0: specified by the cond,and unblocks the mutex specified by the mutex. sl@0: sl@0: The waiting thread unblocks only after another thread calls pthread_cond_signal,pthread_cond_broadcast with the same condition variable, sl@0: or if the system time reaches the time specified in abstime,and the current thread reacquires the lock on the mutex. sl@0: sl@0: sl@0: sl@0: Examples: sl@0: @code sl@0: struct testdata sl@0: { sl@0: pthread_mutex mutex; sl@0: pthread_cond_t cond; sl@0: }; sl@0: static struct testdata td; sl@0: int rc; sl@0: struct timespec timeout; sl@0: struct timeval curtime; sl@0: if(pthread_mutex_lock(&td.mutex)!=0) sl@0: { sl@0: fprintf(stderr,"fail"); sl@0: return -1; sl@0: } sl@0: if(gettimeofday(&curtime,NULL)!=0) sl@0: { sl@0: fprintf(stderr,"fail"); sl@0: return -1; sl@0: } sl@0: timeout.tv_sec=curtime.tv_sec; sl@0: timeout.tv_nsec=curtime.tv_nsec; sl@0: timeout.tv_sec+=TIMEOUT; sl@0: fprintf(stderr,"thread is waiting on the cond"); sl@0: rc=pthread_cond_timedwait(&td.cond,&td.mutex,&timeout); sl@0: if(rc!=0) sl@0: { sl@0: if(rc==ETIMEDOUT) sl@0: { sl@0: fprintf(stderr,"thread stops when time is out"); sl@0: return -1; sl@0: } sl@0: else sl@0: { sl@0: fprintf(stderr,"pthread_cond_timedwait return"); sl@0: return -1; sl@0: } sl@0: } sl@0: fprintf(stderr,"thread wakened up"); sl@0: pthread_mutex_unlock(&td.mutex); sl@0: @endcode sl@0: @see pthread_exit() sl@0: @see pthread_join() sl@0: sl@0: sl@0: sl@0: sl@0: @publishedAll sl@0: @externallyDefinedApi sl@0: */