diff options
Diffstat (limited to 'compat/os2threads.h')
-rw-r--r-- | compat/os2threads.h | 201 |
1 files changed, 201 insertions, 0 deletions
diff --git a/compat/os2threads.h b/compat/os2threads.h new file mode 100644 index 0000000000..40a119ffe1 --- /dev/null +++ b/compat/os2threads.h @@ -0,0 +1,201 @@ +/* + * Copyright (c) 2011 KO Myung-Hun <komh@chollian.net> + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * os2threads to pthreads wrapper + */ + +#ifndef COMPAT_OS2THREADS_H +#define COMPAT_OS2THREADS_H + +#define INCL_DOS +#include <os2.h> + +#undef __STRICT_ANSI__ /* for _beginthread() */ +#include <stdlib.h> + +#include <sys/builtin.h> +#include <sys/fmutex.h> + +#include "libavutil/attributes.h" + +typedef struct { + TID tid; + void *(*start_routine)(void *); + void *arg; + void *result; +} pthread_t; + +typedef void pthread_attr_t; + +typedef HMTX pthread_mutex_t; +typedef void pthread_mutexattr_t; + +typedef struct { + HEV event_sem; + HEV ack_sem; + volatile unsigned wait_count; +} pthread_cond_t; + +typedef void pthread_condattr_t; + +typedef struct { + volatile int done; + _fmutex mtx; +} pthread_once_t; + +#define PTHREAD_ONCE_INIT {0, _FMUTEX_INITIALIZER} + +static void thread_entry(void *arg) +{ + pthread_t *thread = arg; + + thread->result = thread->start_routine(thread->arg); +} + +static av_always_inline int pthread_create(pthread_t *thread, + const pthread_attr_t *attr, + void *(*start_routine)(void*), + void *arg) +{ + thread->start_routine = start_routine; + thread->arg = arg; + thread->result = NULL; + + thread->tid = _beginthread(thread_entry, NULL, 1024 * 1024, thread); + + return 0; +} + +static av_always_inline int pthread_join(pthread_t thread, void **value_ptr) +{ + DosWaitThread(&thread.tid, DCWW_WAIT); + + if (value_ptr) + *value_ptr = thread.result; + + return 0; +} + +static av_always_inline int pthread_mutex_init(pthread_mutex_t *mutex, + const pthread_mutexattr_t *attr) +{ + DosCreateMutexSem(NULL, (PHMTX)mutex, 0, FALSE); + + return 0; +} + +static av_always_inline int pthread_mutex_destroy(pthread_mutex_t *mutex) +{ + DosCloseMutexSem(*(PHMTX)mutex); + + return 0; +} + +static av_always_inline int pthread_mutex_lock(pthread_mutex_t *mutex) +{ + DosRequestMutexSem(*(PHMTX)mutex, SEM_INDEFINITE_WAIT); + + return 0; +} + +static av_always_inline int pthread_mutex_unlock(pthread_mutex_t *mutex) +{ + DosReleaseMutexSem(*(PHMTX)mutex); + + return 0; +} + +static av_always_inline int pthread_cond_init(pthread_cond_t *cond, + const pthread_condattr_t *attr) +{ + DosCreateEventSem(NULL, &cond->event_sem, DCE_POSTONE, FALSE); + DosCreateEventSem(NULL, &cond->ack_sem, DCE_POSTONE, FALSE); + + cond->wait_count = 0; + + return 0; +} + +static av_always_inline int pthread_cond_destroy(pthread_cond_t *cond) +{ + DosCloseEventSem(cond->event_sem); + DosCloseEventSem(cond->ack_sem); + + return 0; +} + +static av_always_inline int pthread_cond_signal(pthread_cond_t *cond) +{ + if (!__atomic_cmpxchg32(&cond->wait_count, 0, 0)) { + DosPostEventSem(cond->event_sem); + DosWaitEventSem(cond->ack_sem, SEM_INDEFINITE_WAIT); + } + + return 0; +} + +static av_always_inline int pthread_cond_broadcast(pthread_cond_t *cond) +{ + while (!__atomic_cmpxchg32(&cond->wait_count, 0, 0)) + pthread_cond_signal(cond); + + return 0; +} + +static av_always_inline int pthread_cond_wait(pthread_cond_t *cond, + pthread_mutex_t *mutex) +{ + __atomic_increment(&cond->wait_count); + + pthread_mutex_unlock(mutex); + + DosWaitEventSem(cond->event_sem, SEM_INDEFINITE_WAIT); + + __atomic_decrement(&cond->wait_count); + + DosPostEventSem(cond->ack_sem); + + pthread_mutex_lock(mutex); + + return 0; +} + +static av_always_inline int pthread_once(pthread_once_t *once_control, + void (*init_routine)(void)) +{ + if (!once_control->done) + { + _fmutex_request(&once_control->mtx, 0); + + if (!once_control->done) + { + init_routine(); + + once_control->done = 1; + } + + _fmutex_release(&once_control->mtx); + } + + return 0; +} +#endif /* COMPAT_OS2THREADS_H */ |