3 MPDM - Minimum Profit Data Manager
4 Copyright (C) 2003/2010 Angel Ortega <angel@triptico.com>
6 mpdm_t.c - Threading primitives
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 2
11 of the License, or (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 http://www.triptico.com
38 #ifdef CONFOPT_PTHREADS
42 #ifdef CONFOPT_POSIXSEMS
43 #include <semaphore.h>
51 static mpdm_t
t_new_val(int flags
, void *ptr
, int size
)
56 char *ptr2
= malloc(size
);
57 memcpy(ptr2
, ptr
, size
);
59 r
= mpdm_new(MPDM_FREE
| flags
, ptr2
, size
);
67 * mpdm_sleep - Sleeps a number of milliseconds.
68 * @msecs: the milliseconds to sleep
70 * Sleeps a number of milliseconds.
73 void mpdm_sleep(int msecs
)
81 #ifdef CONFOPT_NANOSLEEP
84 ts
.tv_sec
= msecs
/ 1000;
85 ts
.tv_nsec
= (msecs
% 1000) * 1000000;
95 * mpdm_new_mutex - Creates a new mutex.
97 * Creates a new mutex.
100 mpdm_t
mpdm_new_mutex(void)
109 h
= CreateMutex(NULL
, FALSE
, NULL
);
117 #ifdef CONFOPT_PTHREADS
120 if (pthread_mutex_init(&m
, NULL
) == 0) {
127 r
= t_new_val(0, ptr
, size
);
134 * mpdm_mutex_lock - Locks a mutex.
135 * @mutex: the mutex to be locked
137 * Locks a mutex. If the mutex is not already locked,
138 * it waits until it is.
141 void mpdm_mutex_lock(mpdm_t mutex
)
144 HANDLE
*h
= (HANDLE
*)mutex
->data
;
146 WaitForSingleObject(*h
, INFINITE
);
149 #ifdef CONFOPT_PTHREADS
150 pthread_mutex_t
*m
= (pthread_mutex_t
*)mutex
->data
;
152 pthread_mutex_lock(m
);
158 * mpdm_mutex_unlock - Unlocks a mutex.
159 * @mutex: the mutex to be unlocked
161 * Unlocks a previously locked mutex. The thread
162 * unlocking the mutex must be the one who locked it.
165 void mpdm_mutex_unlock(mpdm_t mutex
)
168 HANDLE
*h
= (HANDLE
*)mutex
->data
;
173 #ifdef CONFOPT_PTHREADS
174 pthread_mutex_t
*m
= (pthread_mutex_t
*)mutex
->data
;
176 pthread_mutex_unlock(m
);
184 * mpdm_new_semaphore - Creates a new semaphore.
185 * @init_value: the initial value of the semaphore.
187 * Creates a new semaphore with an @init_value.
190 mpdm_t
mpdm_new_sem(int init_value
)
198 if ((h
= CreateSemaphore(NULL
, init_value
, 0x7fffffff, NULL
)) != NULL
) {
205 #ifdef CONFOPT_POSIXSEMS
208 if (sem_init(&s
, 0, init_value
) == 0) {
215 return t_new_val(0, ptr
, size
);
220 * mpdm_sem_wait - Waits for a semaphore to be ready.
221 * @sem: the semaphore to wait onto
223 * Waits for the value of a semaphore to be > 0. If it's
224 * not, the thread waits until it is.
227 void mpdm_sem_wait(mpdm_t sem
)
230 HANDLE
*h
= (HANDLE
*)sem
->data
;
232 WaitForSingleObject(*h
, INFINITE
);
235 #ifdef CONFOPT_POSIXSEMS
236 sem_t
*s
= (sem_t
*)sem
->data
;
244 * mpdm_sem_post - Increments the value of a semaphore.
245 * @sem: the semaphore to increment
247 * Increments by 1 the value of a semaphore.
250 void mpdm_sem_post(mpdm_t sem
)
253 HANDLE
*h
= (HANDLE
*)sem
->data
;
255 ReleaseSemaphore(*h
, 1, NULL
);
258 #ifdef CONFOPT_POSIXSEMS
259 sem_t
*s
= (sem_t
*)sem
->data
;
268 static void thread_caller(mpdm_t a
)
270 /* ignore return value */
273 mpdm_exec(mpdm_aget(a
, 0), mpdm_aget(a
, 1), mpdm_aget(a
, 2))
277 /* was referenced in mpdm_exec_thread() */
283 DWORD WINAPI
win32_thread(LPVOID param
)
285 thread_caller((mpdm_t
) param
);
291 #ifdef CONFOPT_PTHREADS
292 void *pthreads_thread(void *args
)
294 thread_caller((mpdm_t
) args
);
301 * mpdm_exec_thread - Runs an executable value in a new thread.
302 * @c: the executable value
303 * @args: executable arguments
306 * Runs the @c executable value in a new thread. The code
307 * starts executing immediately. The @args and @ctxt arguments
308 * are sent to the executable value as arguments.
310 * Returns a handle for the thread.
313 mpdm_t
mpdm_exec_thread(mpdm_t c
, mpdm_t args
, mpdm_t ctxt
)
323 /* to be unreferenced at thread stop */
324 a
= mpdm_ref(MPDM_A(3));
327 mpdm_aset(a
, args
, 1);
328 mpdm_aset(a
, ctxt
, 2);
333 t
= CreateThread(NULL
, 0, win32_thread
, a
, 0, NULL
);
342 #ifdef CONFOPT_PTHREADS
345 if (pthread_create(&pt
, NULL
, pthreads_thread
, a
) == 0) {
346 size
= sizeof(pthread_t
);
352 r
= t_new_val(0, ptr
, size
);