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 /* BUG Fix on 2010/07/19 : first half of the array was never initialized. */
101 if (threadTab!=NULL){
102 /* Doubles the size of the array */
103 threadTab = ( pthread_data_t* )vp_os_realloc( threadTab, 2 * threadTabSize * sizeof( pthread_data_t ) );
104 /* Initializes the newly created second half */
105 vp_os_memset( threadTab + threadTabSize, 0, threadTabSize * sizeof( pthread_data_t ) );
109 threadTab = ( pthread_data_t* )vp_os_malloc( threadTabSize * sizeof( pthread_data_t ) );
110 vp_os_memset( threadTab , 0, threadTabSize * sizeof( pthread_data_t ) );
114 freeSlot = findThread( NULL_THREAD_HANDLE );
117 pthread_attr_init( &freeSlot->attr );
118 pthread_create( &freeSlot->handle, &freeSlot->attr, f, parameters);
120 *handle = freeSlot->handle;
122 vp_os_mutex_unlock(&thread_mutex);
126 vp_os_thread_join(THREAD_HANDLE handle)
128 vp_os_mutex_lock(&thread_mutex);
130 pthread_data_t* freeSlot = findThread( handle );
132 if( freeSlot != NULL )
136 vp_os_memset(freeSlot, 0, sizeof(pthread_data_t));
137 pthread_join( handle, &res);
140 vp_os_mutex_unlock(&thread_mutex);
144 vp_os_thread_self(void)
146 return pthread_self();
150 vp_os_thread_suspend(THREAD_HANDLE handle)
152 vp_os_mutex_lock(&thread_mutex);
154 pthread_data_t* freeSlot = findThread( handle );
156 if( freeSlot != NULL )
158 if(!freeSlot->isSleeping)
160 freeSlot->isSleeping = 1;
161 pthread_kill(handle,SIGSUSPEND);
165 vp_os_mutex_unlock(&thread_mutex);
169 vp_os_thread_resume(THREAD_HANDLE handle)
171 vp_os_mutex_lock(&thread_mutex);
173 pthread_data_t* freeSlot = findThread( handle );
175 if( freeSlot != NULL )
177 if(freeSlot->isSleeping)
179 pthread_kill(handle,SIGRESUME);
180 freeSlot->isSleeping = 0;
184 vp_os_mutex_unlock(&thread_mutex);
188 vp_os_thread_yield(void)
194 vp_os_thread_priority(THREAD_HANDLE handle, int32_t priority)
196 vp_os_mutex_lock(&thread_mutex);
198 pthread_data_t* freeSlot = findThread( handle );
200 if( freeSlot != NULL )
202 int rc, policy = SCHED_OTHER;
203 struct sched_param param;
205 vp_os_memset(¶m, 0, sizeof(param));
207 rc = pthread_getschedparam(handle, &policy, ¶m);
209 if( policy == SCHED_OTHER )
213 param.sched_priority = priority;
215 rc = pthread_setschedparam(handle, policy, ¶m);
218 vp_os_mutex_unlock(&thread_mutex);