summaryrefslogtreecommitdiff
path: root/compat/os2threads.h (plain)
blob: 40a119ffe1751cdb8e7f00efe5bb78f0c7796c80
1/*
2 * Copyright (c) 2011 KO Myung-Hun <komh@chollian.net>
3 *
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21/**
22 * @file
23 * os2threads to pthreads wrapper
24 */
25
26#ifndef COMPAT_OS2THREADS_H
27#define COMPAT_OS2THREADS_H
28
29#define INCL_DOS
30#include <os2.h>
31
32#undef __STRICT_ANSI__ /* for _beginthread() */
33#include <stdlib.h>
34
35#include <sys/builtin.h>
36#include <sys/fmutex.h>
37
38#include "libavutil/attributes.h"
39
40typedef struct {
41 TID tid;
42 void *(*start_routine)(void *);
43 void *arg;
44 void *result;
45} pthread_t;
46
47typedef void pthread_attr_t;
48
49typedef HMTX pthread_mutex_t;
50typedef void pthread_mutexattr_t;
51
52typedef struct {
53 HEV event_sem;
54 HEV ack_sem;
55 volatile unsigned wait_count;
56} pthread_cond_t;
57
58typedef void pthread_condattr_t;
59
60typedef struct {
61 volatile int done;
62 _fmutex mtx;
63} pthread_once_t;
64
65#define PTHREAD_ONCE_INIT {0, _FMUTEX_INITIALIZER}
66
67static void thread_entry(void *arg)
68{
69 pthread_t *thread = arg;
70
71 thread->result = thread->start_routine(thread->arg);
72}
73
74static av_always_inline int pthread_create(pthread_t *thread,
75 const pthread_attr_t *attr,
76 void *(*start_routine)(void*),
77 void *arg)
78{
79 thread->start_routine = start_routine;
80 thread->arg = arg;
81 thread->result = NULL;
82
83 thread->tid = _beginthread(thread_entry, NULL, 1024 * 1024, thread);
84
85 return 0;
86}
87
88static av_always_inline int pthread_join(pthread_t thread, void **value_ptr)
89{
90 DosWaitThread(&thread.tid, DCWW_WAIT);
91
92 if (value_ptr)
93 *value_ptr = thread.result;
94
95 return 0;
96}
97
98static av_always_inline int pthread_mutex_init(pthread_mutex_t *mutex,
99 const pthread_mutexattr_t *attr)
100{
101 DosCreateMutexSem(NULL, (PHMTX)mutex, 0, FALSE);
102
103 return 0;
104}
105
106static av_always_inline int pthread_mutex_destroy(pthread_mutex_t *mutex)
107{
108 DosCloseMutexSem(*(PHMTX)mutex);
109
110 return 0;
111}
112
113static av_always_inline int pthread_mutex_lock(pthread_mutex_t *mutex)
114{
115 DosRequestMutexSem(*(PHMTX)mutex, SEM_INDEFINITE_WAIT);
116
117 return 0;
118}
119
120static av_always_inline int pthread_mutex_unlock(pthread_mutex_t *mutex)
121{
122 DosReleaseMutexSem(*(PHMTX)mutex);
123
124 return 0;
125}
126
127static av_always_inline int pthread_cond_init(pthread_cond_t *cond,
128 const pthread_condattr_t *attr)
129{
130 DosCreateEventSem(NULL, &cond->event_sem, DCE_POSTONE, FALSE);
131 DosCreateEventSem(NULL, &cond->ack_sem, DCE_POSTONE, FALSE);
132
133 cond->wait_count = 0;
134
135 return 0;
136}
137
138static av_always_inline int pthread_cond_destroy(pthread_cond_t *cond)
139{
140 DosCloseEventSem(cond->event_sem);
141 DosCloseEventSem(cond->ack_sem);
142
143 return 0;
144}
145
146static av_always_inline int pthread_cond_signal(pthread_cond_t *cond)
147{
148 if (!__atomic_cmpxchg32(&cond->wait_count, 0, 0)) {
149 DosPostEventSem(cond->event_sem);
150 DosWaitEventSem(cond->ack_sem, SEM_INDEFINITE_WAIT);
151 }
152
153 return 0;
154}
155
156static av_always_inline int pthread_cond_broadcast(pthread_cond_t *cond)
157{
158 while (!__atomic_cmpxchg32(&cond->wait_count, 0, 0))
159 pthread_cond_signal(cond);
160
161 return 0;
162}
163
164static av_always_inline int pthread_cond_wait(pthread_cond_t *cond,
165 pthread_mutex_t *mutex)
166{
167 __atomic_increment(&cond->wait_count);
168
169 pthread_mutex_unlock(mutex);
170
171 DosWaitEventSem(cond->event_sem, SEM_INDEFINITE_WAIT);
172
173 __atomic_decrement(&cond->wait_count);
174
175 DosPostEventSem(cond->ack_sem);
176
177 pthread_mutex_lock(mutex);
178
179 return 0;
180}
181
182static av_always_inline int pthread_once(pthread_once_t *once_control,
183 void (*init_routine)(void))
184{
185 if (!once_control->done)
186 {
187 _fmutex_request(&once_control->mtx, 0);
188
189 if (!once_control->done)
190 {
191 init_routine();
192
193 once_control->done = 1;
194 }
195
196 _fmutex_release(&once_control->mtx);
197 }
198
199 return 0;
200}
201#endif /* COMPAT_OS2THREADS_H */
202