3 * @author aurelien.morelle@parrot.fr
11 #include <VP_Os/vp_os_types.h>
12 #include <VP_Os/vp_os_thread.h>
13 #include <VP_Os/vp_os_signal.h>
14 #include <VP_Os/vp_os_malloc.h>
16 #define SIGRESUME SIGUSR1
17 #define SIGSUSPEND SIGUSR2
19 typedef struct _pthread_data_t
26 static const THREAD_HANDLE NULL_THREAD_HANDLE = 0;
28 static uint32_t threadTabSize = 128;
29 //static uint32_t numCreatedThread = 0;
30 static pthread_data_t* threadTab = NULL;
32 static pthread_once_t once;
33 static vp_os_mutex_t thread_mutex;
36 static void suspendSignalHandler(int sig)
40 /* Block all signals except PTHREAD_RESUME while suspended. */
41 sigfillset(&signal_set);
42 sigdelset(&signal_set, SIGRESUME);
43 sigsuspend(&signal_set);
46 static void resumeSignalHandler(int sig)
50 static void init_thread(void)
52 struct sigaction sigsuspend, sigresume;
54 vp_os_mutex_init(&thread_mutex);
56 sigresume.sa_flags = 0;
57 sigsuspend.sa_flags = 0;
59 sigemptyset(&sigresume.sa_mask);
60 sigemptyset(&sigsuspend.sa_mask);
61 sigaddset(&sigsuspend.sa_mask, SIGSUSPEND);
62 sigaddset(&sigresume.sa_mask, SIGRESUME);
64 sigresume.sa_handler = resumeSignalHandler;
65 sigsuspend.sa_handler = suspendSignalHandler;
67 sigaction(SIGRESUME,&sigresume,NULL);
68 sigaction(SIGSUSPEND,&sigsuspend,NULL);
71 static pthread_data_t* findThread(THREAD_HANDLE handle)
78 for(i = 0;i < threadTabSize;i++)
80 if( pthread_equal(handle,threadTab[i].handle) )
88 vp_os_thread_create(THREAD_ROUTINE f, THREAD_PARAMS parameters, THREAD_HANDLE *handle, ...)
90 pthread_data_t* freeSlot = NULL;
92 pthread_once(&once,&init_thread);
94 vp_os_mutex_lock(&thread_mutex);
96 freeSlot = findThread( NULL_THREAD_HANDLE );
97 while(freeSlot == NULL)
99 threadTab = ( pthread_data_t* )vp_os_realloc( threadTab, 2 * threadTabSize * sizeof( pthread_data_t ) );
100 vp_os_memset( threadTab + threadTabSize, 0, threadTabSize * sizeof( pthread_data_t ) );
104 freeSlot = findThread( NULL_THREAD_HANDLE );
107 pthread_attr_init( &freeSlot->attr );
108 pthread_create( &freeSlot->handle, &freeSlot->attr, f, parameters);
110 *handle = freeSlot->handle;
112 vp_os_mutex_unlock(&thread_mutex);
116 vp_os_thread_join(THREAD_HANDLE handle)
118 vp_os_mutex_lock(&thread_mutex);
120 pthread_data_t* freeSlot = findThread( handle );
122 if( freeSlot != NULL )
126 vp_os_memset(freeSlot, 0, sizeof(pthread_data_t));
127 pthread_join( handle, &res);
130 vp_os_mutex_unlock(&thread_mutex);
134 vp_os_thread_self(void)
136 return pthread_self();
140 vp_os_thread_suspend(THREAD_HANDLE handle)
142 vp_os_mutex_lock(&thread_mutex);
144 pthread_data_t* freeSlot = findThread( handle );
146 if( freeSlot != NULL )
148 if(!freeSlot->isSleeping)
150 freeSlot->isSleeping = 1;
151 pthread_kill(handle,SIGSUSPEND);
155 vp_os_mutex_unlock(&thread_mutex);
159 vp_os_thread_resume(THREAD_HANDLE handle)
161 vp_os_mutex_lock(&thread_mutex);
163 pthread_data_t* freeSlot = findThread( handle );
165 if( freeSlot != NULL )
167 if(freeSlot->isSleeping)
169 pthread_kill(handle,SIGRESUME);
170 freeSlot->isSleeping = 0;
174 vp_os_mutex_unlock(&thread_mutex);
178 vp_os_thread_yield(void)
184 vp_os_thread_priority(THREAD_HANDLE handle, int32_t priority)
186 vp_os_mutex_lock(&thread_mutex);
188 pthread_data_t* freeSlot = findThread( handle );
190 if( freeSlot != NULL )
192 int rc, policy = SCHED_OTHER;
193 struct sched_param param;
195 vp_os_memset(¶m, 0, sizeof(param));
197 rc = pthread_getschedparam(handle, &policy, ¶m);
199 if( policy == SCHED_OTHER )
203 param.__sched_priority = priority;
204 rc = pthread_setschedparam(handle, policy, ¶m);
207 vp_os_mutex_unlock(&thread_mutex);