free allocated stack by execution thread
[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_attr_setstacksize(&threadAttr, size);
149     pthread_create(threadId, &threadAttr, functionName, params);
150 #endif
151     *threadKey = *threadId;
152 #endif
153 }
154
155 void __WaitThreadDie(__threadId threadId)
156 {
157 #ifdef _MSC_VER
158     ((WaitForSingleObject((threadId),INFINITE)!=WAIT_OBJECT_0) || !CloseHandle(threadId));
159 #else
160     pthread_join(threadId, NULL);
161 #endif
162 }
163
164 void __Terminate(__threadId threadId)
165 {
166 #ifdef _MSC_VER
167     TerminateThread(threadId, 0);
168 #else
169     pthread_cancel(threadId);
170 #endif
171 }
172
173 __threadId __GetCurrentThreadId()
174 {
175 #ifdef _MSC_VER
176     return GetCurrentThread();
177 #else
178     return pthread_self();
179 #endif
180 }
181
182 __threadKey __GetCurrentThreadKey()
183 {
184 #ifdef _MSC_VER
185     return GetCurrentThreadId();
186 #else
187     return pthread_self();
188 #endif
189 }
190
191 void __SuspendThread(__threadId ThreadId)
192 {
193 #ifdef _MSC_VER
194     SuspendThread(ThreadId);
195 #else
196     pthread_kill(ThreadId, SIGUSR1);
197 #endif
198 }
199
200 void __ResumeThread(__threadId ThreadId)
201 {
202 #ifdef _MSC_VER
203     ResumeThread(ThreadId);
204 #else
205     pthread_kill(ThreadId, SIGUSR2);
206 #endif
207 }
208