/*
 * 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 */
