c - safe method to wait for all thread timer callbacks completion -



c - safe method to wait for all thread timer callbacks completion -

in case of one-shot timer can utilize semaphore wait timer callback completion. if timer fired several times doesn't help. consider next code:

#include <stdlib.h> #include <stdint.h> #include <stdio.h> #include <signal.h> #include <time.h> #include <unistd.h> #include <pthread.h> #define n 10 void timer_threaded_function(sigval_t si) { uint8_t *shared_resource = si.sival_ptr; sleep(rand() % 7); /* ... manipulate shared_resource */ return; } int main() { struct sigevent sig_ev = {0}; uint8_t *shared_resource = malloc(123); timer_t timer_id; int i; sig_ev.sigev_notify = sigev_thread; sig_ev.sigev_value.sival_ptr = shared_resource; sig_ev.sigev_notify_function = timer_threaded_function; sig_ev.sigev_notify_attributes = null; timer_create(clock_realtime, &sig_ev, &timer_id); (i = 0; < n; i++) { /* arm timer 1 nanosecond */ timer_settime(timer_id, 0, &(struct itimerspec){{0,0},{0,1}}, null); /* sleep little bit, timer fired */ usleep(1); } /* disarms timer, timer callbacks still can running */ timer_delete(timer_id); /* * todo: safe wait callbacks end, shared resource * can freed without races. */ ... free(shared_resource); homecoming 0; }

timer_delete() disarms timer (if armed) , frees assocoated timer resources. timer callbacks still can running. cannot free shared_resource, otherwise race status may occur. there method cope situation?

i thougth reference counting, doesn't help, because doesn't know how much threads seek access shared resource (cause of timer overruns).

it thoroughly unsatisfactory :-(. have looked, , there not seem way find whether sigevent (a) has not been fired, or (b) pending, or (c) running, or (d) has completed.

best can suggest level of indirection, , static point @ shared resource. so:

static foo_t* p_shared ; .... p_shared = shared_resourse ; ..... sig_ev.sigev_value.sival_ptr = &p_shared ;

where foo_t type of shared resource.

now can utilize atomics... in timer_threaded_function():

foo_t** pp_shared ; foo_t* p_locked ; foo_t* p_shared ; pp_shared = so.sival_ptr ; p_locked = (void*)uinptr_max ; p_shared = atomic_swap(pp_shared, p_locked) ; if (p_shared == p_locked) homecoming ; // locked already. if (p_shared == null) homecoming ; // destroyed already. .... proceed usual work ... if (atomic_cmp_swap(pp_shared, &p_locked, p_shared)) homecoming ; // locked , restored assert(p_locked == null) ; ... shared resource needs freed ...

and in controlling thread:

timer_delete(timer_id) ; // no more events, give thanks p_s = atomic_swap(&p_shared, null) ; // stop processing events if (p_s == (void*)uintptr_max) // event beingness processed. if (p_s != null) ... shared resource needs freed ...

when event thread finds shared resourse needs freed, can itself, or signal controlling thread event has been processed, controlling thread can go ahead , free. that's largely matter of taste.

basically, using atomics provide sort of lock, value tri-state: null <=> destroyed ; uintptr_max <=> locked ; else <=> unlocked.

the down-side static p_shared, has remain in existence until timer_threaded_function() has finished , never called again... , since exactly things unknowable, static p_shared is, effectively, fixture :-(.

c linux multithreading timer pthreads

Comments

Popular posts from this blog

javascript - THREE.js reposition vertices for RingGeometry -

javascript - I need to update the text of a paragraph by inline edit -

assembly - What is the addressing mode for ld, add, and rjmp instructions? -