Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
52868 views
1
/*
2
* Copyright (c) 2011 KO Myung-Hun <[email protected]>
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
40
typedef struct {
41
TID tid;
42
void *(*start_routine)(void *);
43
void *arg;
44
void *result;
45
} pthread_t;
46
47
typedef void pthread_attr_t;
48
49
typedef HMTX pthread_mutex_t;
50
typedef void pthread_mutexattr_t;
51
52
typedef struct {
53
HEV event_sem;
54
HEV ack_sem;
55
volatile unsigned wait_count;
56
} pthread_cond_t;
57
58
typedef void pthread_condattr_t;
59
60
typedef struct {
61
volatile int done;
62
_fmutex mtx;
63
} pthread_once_t;
64
65
#define PTHREAD_ONCE_INIT {0, _FMUTEX_INITIALIZER}
66
67
static void thread_entry(void *arg)
68
{
69
pthread_t *thread = arg;
70
71
thread->result = thread->start_routine(thread->arg);
72
}
73
74
static 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
88
static 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
98
static 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
106
static av_always_inline int pthread_mutex_destroy(pthread_mutex_t *mutex)
107
{
108
DosCloseMutexSem(*(PHMTX)mutex);
109
110
return 0;
111
}
112
113
static 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
120
static av_always_inline int pthread_mutex_unlock(pthread_mutex_t *mutex)
121
{
122
DosReleaseMutexSem(*(PHMTX)mutex);
123
124
return 0;
125
}
126
127
static 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
138
static 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
146
static 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
156
static 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
164
static 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
182
static 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
203