!****************************************************************** !* Example 5 : Create a thread with Round_Robin scheduling policy.* !* For simplicity, we do not show any codes for error checking, * !* which would be necessary in a real program. * !****************************************************************** use f_pthread integer(4) ret_val type(f_pthread_attr_t) attr type(f_pthread_t) thr ret_val = f_pthread_attr_init(attr) ret_val = f_pthread_attr_setschedpolicy(attr, SCHED_RR) ret_val = f_pthread_attr_setinheritsched(attr, PTHREAD_EXPLICIT_SCHED) ret_val = f_pthread_create(thr, attr, FLAG_DEFAULT, ent, integer_arg) ret_val = f_pthread_attr_destroy(attr) ......
Before you can manipulate a pthread attribute object, you need to create and initialize it. The appropriate interfaces must be called to manipulate the attribute objects. A call to f_pthread_attr_setschedpolicy sets the scheduling policy attribute to Round_Robin. Note that this does not affect newly created threads that inherit the scheduling property from the creating thread. For these threads, we explicitly call f_pthread_attr_setinheritsched to override the default inheritance attribute. The rest of the code is self-explanatory.
!***************************************************************** !* Example 6 : Thread safety * !* In this example, we show that thread safety can be achieved * !* by using the push-pop cleanup stack for each thread. We * !* assume that the thread is in deferred cancellability-enabled * !* state. This means that any thread-cancel requests will be * !* put on hold until a cancellation point is encountered. * !* Note that f_pthread_cond_wait provides a * !* cancellation point. * !***************************************************************** use f_pthread integer(4) ret_val type(f_pthread_mutex_t) mutex type(f_pthread_cond_t) cond pointer(p, byte) ! Initialize mutex and condition variables before using them. ! For global variables this should be done in a module, so that they ! can be used by all threads. If they are local, other threads ! will not see them. Furthermore, they must be managed carefully ! (for example, destroy them before returning, to avoid dangling and ! undefined objects). mutex = PTHREAD_MUTEX_INITIALIZER cond = PTHREAD_COND_INITIALIZER ...... ! Doing something ...... ! This thread needs to allocate some memory area used to ! synchronize with other threads. However, when it waits on a ! condition variable, this thread may be canceled by another ! thread. The allocated memory may be lost if no measures are ! taken in advance. This will cause memory leakage. ret_val = f_pthread_mutex_lock(mutex) p = malloc(%val(4096)) ! check condition. If it is not true, going to wait for it. ! This should be a loop. ! Since memory has been allocated, cleanup must be registered ! for safety during condition waiting. ret_val = f_pthread_cleanup_push(mycleanup, FLAG_DEFAULT, p) ret_val = f_pthread_cond_wait(cond, mutex) ! If this thread returns from condition waiting, the cleanup ! should be de-registered. call f_pthread_cleanup_pop(0) ! not execute ret_val = f_pthread_mutex_unlock(mutex) ! This thread will take care of p for the rest of its life. ...... ! mycleanup looks like: subroutine mycleanup(passed_in) pointer(passed_in, byte) external free call free(%val(passed_in)) end subroutine mycleanup