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 /*#define SUP_THREAD_MINPRIORITY 31
20 #define SUP_THREAD_INVALID_HANDLE NULL*/
22 typedef struct _pthread_data_t
29 static const THREAD_HANDLE NULL_THREAD_HANDLE = 0;
31 static uint32_t threadTabSize = 0;
32 static pthread_data_t* threadTab = NULL;
34 static pthread_once_t once;
35 static vp_os_mutex_t thread_mutex;
38 #include <VP_Os/vp_os_print.h>
39 static void suspendSignalHandler(int sig)
43 /* Block all signals except PTHREAD_RESUME while suspended. */
44 sigfillset(&signal_set);
45 sigdelset(&signal_set, SIGRESUME);
46 sigsuspend(&signal_set);
49 static void resumeSignalHandler(int sig)
53 static void init_thread(void) {
54 struct sigaction sigsuspend, sigresume;
56 vp_os_mutex_init(&thread_mutex);
58 sigresume.sa_flags = 0;
59 sigsuspend.sa_flags = 0;
61 sigemptyset(&sigresume.sa_mask);
62 sigemptyset(&sigsuspend.sa_mask);
63 sigaddset(&sigsuspend.sa_mask, SIGSUSPEND);
64 sigaddset(&sigresume.sa_mask, SIGRESUME);
66 sigresume.sa_handler = resumeSignalHandler;
67 sigsuspend.sa_handler = suspendSignalHandler;
69 sigaction(SIGRESUME,&sigresume,NULL);
70 sigaction(SIGSUSPEND,&sigsuspend,NULL);
73 static pthread_data_t* findThread(THREAD_HANDLE handle)
80 for(i = 0;i < threadTabSize;i++)
82 if( pthread_equal(handle,threadTab[i].handle) )
90 vp_os_thread_create(THREAD_ROUTINE f, THREAD_PARAMS parameters, THREAD_HANDLE *handle, ...)
95 unsigned int stack_size;
98 pthread_data_t* freeSlot = NULL;
100 pthread_once(&once,&init_thread);
102 vp_os_mutex_lock(&thread_mutex);
104 freeSlot = findThread( NULL_THREAD_HANDLE );
105 while(freeSlot == NULL)
107 /* BUG Fix on 2010/07/19 : some data were written beyond the end of the array */
109 int old_size = threadTabSize;
110 threadTabSize += 128;
111 threadTab = ( pthread_data_t* )vp_os_realloc( threadTab, threadTabSize * sizeof( pthread_data_t ) );
112 vp_os_memset( threadTab + old_size, 0, (threadTabSize-old_size) * sizeof( pthread_data_t ) );
114 freeSlot = findThread( NULL_THREAD_HANDLE );
117 vp_os_mutex_unlock(&thread_mutex);
119 pthread_attr_init( &freeSlot->attr );
121 va_start(va, handle);
122 priority = va_arg(va, int32_t);
123 name = va_arg(va, char *);
124 stack_base = va_arg(va, void *);
125 stack_size = va_arg(va, unsigned int);
126 /* thread = va_arg(va, cyg_thread *);*/
129 pthread_create( &freeSlot->handle, &freeSlot->attr, f, parameters);
131 *handle = freeSlot->handle;
133 vp_os_thread_priority(freeSlot->handle, priority);
137 vp_os_thread_join(THREAD_HANDLE handle)
139 PRINT("vp_os_thread_join\n %d\n", (int)handle);
141 vp_os_mutex_lock(&thread_mutex);
143 pthread_data_t* freeSlot = findThread( handle );
145 vp_os_mutex_unlock(&thread_mutex);
147 if( freeSlot != NULL )
151 vp_os_memset(freeSlot, 0, sizeof(pthread_data_t));
152 pthread_join( handle, &res);
157 vp_os_thread_self(void)
159 return pthread_self();
163 vp_os_thread_suspend(THREAD_HANDLE handle)
165 vp_os_mutex_lock(&thread_mutex);
167 pthread_data_t* freeSlot = findThread( handle );
169 vp_os_mutex_unlock(&thread_mutex);
171 if( freeSlot != NULL )
173 if(!freeSlot->isSleeping)
175 freeSlot->isSleeping = 1;
176 pthread_kill(handle,SIGSUSPEND);
182 vp_os_thread_resume(THREAD_HANDLE handle)
184 vp_os_mutex_lock(&thread_mutex);
186 pthread_data_t* freeSlot = findThread( handle );
188 vp_os_mutex_unlock(&thread_mutex);
190 if( freeSlot != NULL )
192 if(freeSlot->isSleeping)
194 pthread_kill(handle,SIGRESUME);
195 freeSlot->isSleeping = 0;
201 vp_os_thread_yield(void)
207 vp_os_thread_priority(THREAD_HANDLE handle, int32_t priority)
209 vp_os_mutex_lock(&thread_mutex);
211 pthread_data_t* freeSlot = findThread( handle );
213 vp_os_mutex_unlock(&thread_mutex);
215 if( freeSlot != NULL )
217 int rc, policy = SCHED_OTHER;
218 struct sched_param param;
220 vp_os_memset(¶m, 0, sizeof(param));
222 rc = pthread_getschedparam(handle, &policy, ¶m);
224 if( policy == SCHED_OTHER)
228 param.__sched_priority = 99-priority;
229 rc = pthread_setschedparam(handle, policy, ¶m);