expand implicit list in cell, like c={1:3} -> c={[1 2 3]}
[scilab.git] / scilab / modules / threads / src / cpp / Thread_Wrapper.cpp
1 /*
2  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  *  Copyright (C) 2008-2008 - INRIA - Bruno JOFRET
4  *  Copyright (C) 2008-2008 - INRIA - Allan CORNET
5  *  Copyright (C) 2011-2011 - DIGITEO - Bruno JOFRET
6  *
7  *  This file must be used under the terms of the CeCILL.
8  *  This source file is licensed as described in the file COPYING, which
9  *  you should have received as part of this distribution.  The terms
10  *  are also available at
11  *  http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
12  *
13  */
14
15 extern "C"
16 {
17 #include "Thread_Wrapper.h"
18 }
19
20 void __InitLock(__threadLock *lockName)
21 {
22 #ifdef _MSC_VER
23     *(lockName)=CreateMutex(NULL, FALSE, NULL);
24 #else
25     pthread_mutex_init(lockName, NULL);
26 #endif
27 }
28
29 void __Lock(__threadLock *lockName)
30 {
31 #ifdef _MSC_VER
32     WaitForSingleObject(*lockName, INFINITE);
33 #else
34     pthread_mutex_lock(lockName);
35 #endif
36 }
37
38 void __UnLock(__threadLock *lockName)
39 {
40 #ifdef _MSC_VER
41     ReleaseMutex(*lockName);
42 #else
43     pthread_mutex_unlock(lockName);
44 #endif
45 }
46
47 void __InitSignalLock(__threadSignalLock *lockName)
48 {
49 #ifdef _MSC_VER
50     InitializeCriticalSection(lockName);
51 #else
52 /* PTHREAD_MUTEX_ERRORCHECK needed for a safe release atexit when we try to release without knowing if we own the lock
53    PTHREAD_PROCESS_SHARED needed for interprocess synch (plus alloc in shared mem thread_mutexattr_settype
54    Linux uses PTHREAD_MUTEX_ERRORCHECK_NP other Posix use PTHREAD_MUTEX_ERRORCHECK
55 */
56 #ifndef PTHREAD_MUTEX_ERRORCHECK
57 #define PTHREAD_MUTEX_ERRORCHECK PTHREAD_MUTEX_ERRORCHECK_NP
58 #endif
59     pthread_mutexattr_t attr;
60     pthread_mutexattr_init (&attr);
61     pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
62     pthread_mutexattr_setpshared (&attr, PTHREAD_PROCESS_SHARED);
63     pthread_mutex_init(lockName, NULL);
64     pthread_mutexattr_destroy(&attr);
65 #endif
66 }
67
68
69 void __LockSignal(__threadSignalLock *lockName)
70 {
71 #ifdef _MSC_VER
72     EnterCriticalSection(lockName);
73 #else
74     pthread_mutex_lock(lockName);
75 #endif
76 }
77
78 void __UnLockSignal(__threadSignalLock *lockName)
79 {
80 #ifdef _MSC_VER
81     LeaveCriticalSection(lockName);
82 #else
83     pthread_mutex_unlock(lockName);
84 #endif
85 }
86
87 void __InitSignal(__threadSignal *signalName)
88 {
89 #ifdef _MSC_VER
90     *signalName = CreateEvent(NULL, FALSE, FALSE, NULL);
91 #else
92     pthread_cond_init(signalName, NULL);
93 #endif
94 }
95
96 void __Signal(__threadSignal *signalName)
97 {
98 #ifdef _MSC_VER
99     SetEvent(*signalName);
100 #else
101     pthread_cond_signal(signalName);
102 #endif
103 }
104
105 void __Wait(__threadSignal *signalName, __threadSignalLock *lockName)
106 {
107 #ifdef _MSC_VER
108     ResetEvent(*signalName);
109     __UnLockSignal(lockName);
110     WaitForSingleObject(*signalName, INFINITE);
111     __LockSignal(lockName);
112 #else
113     pthread_cond_wait(signalName, lockName);
114 #endif
115 }
116
117 void __CreateThread(__threadId *threadId, __threadKey *threadKey, void *(*functionName) (void *))
118 {
119     __CreateThreadWithParams(threadId, threadKey, functionName, NULL);
120 }
121
122 void __CreateThreadWithParams(__threadId *threadId, __threadKey *threadKey, void *(*functionName) (void *), void *params)
123 {
124 #ifdef _MSC_VER
125     size_t size = 128 * 1024 * 1024;
126     *(threadId) = CreateThread(NULL, size, (LPTHREAD_START_ROUTINE)functionName, params, 0, threadKey);
127 #else
128
129     /*
130     ** We need to increase call stack under MacOSX && LINUX.
131     ** The default one is too small...
132     */
133     pthread_attr_t threadAttr;
134 #ifdef __APPLE__
135     size_t size = 128 * 1024 * 1024;
136     void *stackbase = (void *) malloc(size);
137     pthread_attr_init(&threadAttr);
138
139     pthread_attr_setstacksize(&threadAttr, size);
140     pthread_attr_setstackaddr(&threadAttr, stackbase);
141     pthread_create(threadId, &threadAttr, functionName, params);
142 #else //Linux
143     size_t size = 128 * 1024 * 1024;
144     void *stackbase = (void *) malloc(size);
145     pthread_attr_init(&threadAttr);
146
147     pthread_attr_setstack(&threadAttr, stackbase, size);
148     pthread_create(threadId, &threadAttr, functionName, params);
149 #endif
150     *threadKey = *threadId;
151 #endif
152 }
153
154 void __WaitThreadDie(__threadId threadId)
155 {
156 #ifdef _MSC_VER
157     ((WaitForSingleObject((threadId),INFINITE)!=WAIT_OBJECT_0) || !CloseHandle(threadId));
158 #else
159     pthread_join(threadId, NULL);
160 #endif
161 }
162
163 void __Terminate(__threadId threadId)
164 {
165 #ifdef _MSC_VER
166     TerminateThread(threadId, 0);
167 #else
168     pthread_cancel(threadId);
169 #endif
170 }
171
172 __threadId __GetCurrentThreadId()
173 {
174 #ifdef _MSC_VER
175     return GetCurrentThread();
176 #else
177     return pthread_self();
178 #endif
179 }
180
181 __threadKey __GetCurrentThreadKey()
182 {
183 #ifdef _MSC_VER
184     return GetCurrentThreadId();
185 #else
186     return pthread_self();
187 #endif
188 }
189
190 void __SuspendThread(__threadId ThreadId)
191 {
192 #ifdef _MSC_VER
193     SuspendThread(ThreadId);
194 #else
195     pthread_kill(ThreadId, SIGUSR1);
196 #endif
197 }
198
199 void __ResumeThread(__threadId ThreadId)
200 {
201 #ifdef _MSC_VER
202     ResumeThread(ThreadId);
203 #else
204     pthread_kill(ThreadId, SIGUSR2);
205 #endif
206 }
207