/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
 * vim: set ts=8 sts=4 et sw=4 tw=99:
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "vm/PosixNSPR.h"

#include "js/Utility.h"

#ifdef JS_POSIX_NSPR

#include <errno.h>
#include <sys/time.h>
#include <time.h>

#if defined(__DragonFly__) || defined(__FreeBSD__) || defined(__OpenBSD__)
#include <pthread_np.h>
#endif

class nspr::Thread
{
    pthread_t pthread_;
    void (*start)(void* arg);
    void* arg;
    bool joinable;

  public:
    Thread(void (*start)(void* arg), void* arg, bool joinable)
      : start(start), arg(arg), joinable(joinable) {}

    static void* ThreadRoutine(void* arg);

    pthread_t& pthread() { return pthread_; }
};

static pthread_key_t gSelfThreadIndex;
static nspr::Thread gMainThread(nullptr, nullptr, false);

void*
nspr::Thread::ThreadRoutine(void* arg)
{
    Thread* self = static_cast<Thread*>(arg);
    pthread_setspecific(gSelfThreadIndex, self);
    self->start(self->arg);
    if (!self->joinable)
        js_delete(self);
    return nullptr;
}

static bool gInitialized;

void
DummyDestructor(void*)
{
}

/* Should be called from the main thread. */
static void
Initialize()
{
    gInitialized = true;

    if (pthread_key_create(&gSelfThreadIndex, DummyDestructor)) {
        MOZ_CRASH();
        return;
    }

    pthread_setspecific(gSelfThreadIndex, &gMainThread);
}

PRThread*
PR_CreateThread(PRThreadType type,
                void (*start)(void* arg),
                void* arg,
                PRThreadPriority priority,
                PRThreadScope scope,
                PRThreadState state,
                uint32_t stackSize)
{
    MOZ_ASSERT(type == PR_USER_THREAD);
    MOZ_ASSERT(priority == PR_PRIORITY_NORMAL);

    if (!gInitialized) {
        /*
         * We assume that the first call to PR_CreateThread happens on the main
         * thread.
         */
        Initialize();
    }

    pthread_attr_t attr;
    if (pthread_attr_init(&attr))
        return nullptr;

    if (stackSize && pthread_attr_setstacksize(&attr, stackSize)) {
        pthread_attr_destroy(&attr);
        return nullptr;
    }

    nspr::Thread* t = js_new<nspr::Thread>(start, arg,
                                           state != PR_UNJOINABLE_THREAD);
    if (!t) {
        pthread_attr_destroy(&attr);
        return nullptr;
    }

    if (pthread_create(&t->pthread(), &attr, &nspr::Thread::ThreadRoutine, t)) {
        pthread_attr_destroy(&attr);
        js_delete(t);
        return nullptr;
    }

    if (state == PR_UNJOINABLE_THREAD) {
        if (pthread_detach(t->pthread())) {
            pthread_attr_destroy(&attr);
            js_delete(t);
            return nullptr;
        }
    }

    pthread_attr_destroy(&attr);

    return t;
}

PRStatus
PR_JoinThread(PRThread* thread)
{
    if (pthread_join(thread->pthread(), nullptr))
        return PR_FAILURE;

    js_delete(thread);

    return PR_SUCCESS;
}

PRThread*
PR_GetCurrentThread()
{
    if (!gInitialized)
        Initialize();

    PRThread* thread = reinterpret_cast<PRThread*>(pthread_getspecific(gSelfThreadIndex));
    if (!thread) {
        thread = js_new<PRThread>(nullptr, nullptr, false);
        if (!thread)
            MOZ_CRASH();
        pthread_setspecific(gSelfThreadIndex, thread);
    }
    return thread;
}

PRStatus
PR_SetCurrentThreadName(const char* name)
{
    int result;
#ifdef XP_DARWIN
    result = pthread_setname_np(name);
#elif defined(__DragonFly__) || defined(__FreeBSD__) || defined(__OpenBSD__)
    pthread_set_name_np(pthread_self(), name);
    result = 0;
#elif defined(__NetBSD__)
    result = pthread_setname_np(pthread_self(), "%s", (void*)name);
#else
    result = pthread_setname_np(pthread_self(), name);
#endif
    if (result)
        return PR_FAILURE;
    return PR_SUCCESS;
}

static const size_t MaxTLSKeyCount = 32;
static size_t gTLSKeyCount;
static pthread_key_t gTLSKeys[MaxTLSKeyCount];

PRStatus
PR_NewThreadPrivateIndex(unsigned* newIndex, PRThreadPrivateDTOR destructor)
{
    /*
     * We only call PR_NewThreadPrivateIndex from the main thread, so there's no
     * need to lock the table of TLS keys.
     */
    MOZ_ASSERT(PR_GetCurrentThread() == &gMainThread);

    pthread_key_t key;
    if (pthread_key_create(&key, destructor))
        return PR_FAILURE;

    MOZ_ASSERT(gTLSKeyCount + 1 < MaxTLSKeyCount);

    gTLSKeys[gTLSKeyCount] = key;
    *newIndex = gTLSKeyCount;
    gTLSKeyCount++;

    return PR_SUCCESS;
}

PRStatus
PR_SetThreadPrivate(unsigned index, void* priv)
{
    if (index >= gTLSKeyCount)
        return PR_FAILURE;
    if (pthread_setspecific(gTLSKeys[index], priv))
        return PR_FAILURE;
    return PR_SUCCESS;
}

void*
PR_GetThreadPrivate(unsigned index)
{
    if (index >= gTLSKeyCount)
        return nullptr;
    return pthread_getspecific(gTLSKeys[index]);
}

PRStatus
PR_CallOnce(PRCallOnceType* once, PRCallOnceFN func)
{
    MOZ_CRASH("PR_CallOnce unimplemented");
}

PRStatus
PR_CallOnceWithArg(PRCallOnceType* once, PRCallOnceWithArgFN func, void* arg)
{
    MOZ_CRASH("PR_CallOnceWithArg unimplemented");
}

class nspr::Lock
{
    pthread_mutex_t mutex_;

  public:
    Lock() {}
    pthread_mutex_t& mutex() { return mutex_; }
};

PRLock*
PR_NewLock()
{
    nspr::Lock* lock = js_new<nspr::Lock>();
    if (!lock)
        return nullptr;

    if (pthread_mutex_init(&lock->mutex(), nullptr)) {
        js_delete(lock);
        return nullptr;
    }

    return lock;
}

void
PR_DestroyLock(PRLock* lock)
{
    pthread_mutex_destroy(&lock->mutex());
    js_delete(lock);
}

void
PR_Lock(PRLock* lock)
{
    pthread_mutex_lock(&lock->mutex());
}

PRStatus
PR_Unlock(PRLock* lock)
{
    if (pthread_mutex_unlock(&lock->mutex()))
        return PR_FAILURE;
    return PR_SUCCESS;
}

class nspr::CondVar
{
    pthread_cond_t cond_;
    nspr::Lock* lock_;

  public:
    explicit CondVar(nspr::Lock* lock) : lock_(lock) {}
    pthread_cond_t& cond() { return cond_; }
    nspr::Lock* lock() { return lock_; }
};

PRCondVar*
PR_NewCondVar(PRLock* lock)
{
    nspr::CondVar* cvar = js_new<nspr::CondVar>(lock);
    if (!cvar)
        return nullptr;

    if (pthread_cond_init(&cvar->cond(), nullptr)) {
        js_delete(cvar);
        return nullptr;
    }

    return cvar;
}

void
PR_DestroyCondVar(PRCondVar* cvar)
{
    pthread_cond_destroy(&cvar->cond());
    js_delete(cvar);
}

PRStatus
PR_NotifyCondVar(PRCondVar* cvar)
{
    if (pthread_cond_signal(&cvar->cond()))
        return PR_FAILURE;
    return PR_SUCCESS;
}

PRStatus
PR_NotifyAllCondVar(PRCondVar* cvar)
{
    if (pthread_cond_broadcast(&cvar->cond()))
        return PR_FAILURE;
    return PR_SUCCESS;
}

uint32_t
PR_MillisecondsToInterval(uint32_t milli)
{
    return milli;
}

uint32_t
PR_MicrosecondsToInterval(uint32_t micro)
{
    return (micro + 999) / 1000;
}

static const uint64_t TicksPerSecond = 1000;
static const uint64_t NanoSecondsInSeconds = 1000000000;
static const uint64_t MicroSecondsInSeconds = 1000000;

uint32_t
PR_TicksPerSecond()
{
    return TicksPerSecond;
}

PRStatus
PR_WaitCondVar(PRCondVar* cvar, uint32_t timeout)
{
    if (timeout == PR_INTERVAL_NO_TIMEOUT) {
        if (pthread_cond_wait(&cvar->cond(), &cvar->lock()->mutex()))
            return PR_FAILURE;
        return PR_SUCCESS;
    } else {
        struct timespec ts;
        struct timeval tv;

        gettimeofday(&tv, nullptr);
        ts.tv_sec = tv.tv_sec;
        ts.tv_nsec = tv.tv_usec * (NanoSecondsInSeconds / MicroSecondsInSeconds);

        ts.tv_nsec += timeout * (NanoSecondsInSeconds / TicksPerSecond);
        while (uint64_t(ts.tv_nsec) >= NanoSecondsInSeconds) {
            ts.tv_nsec -= NanoSecondsInSeconds;
            ts.tv_sec++;
        }

        int result = pthread_cond_timedwait(&cvar->cond(), &cvar->lock()->mutex(), &ts);
        if (result == 0 || result == ETIMEDOUT)
            return PR_SUCCESS;
        return PR_FAILURE;
    }
}

#endif /* JS_POSIX_NSPR */
