/*
 * Copyright (c) 1994, 2008, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code 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 General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

/*
 * Win32 implementation of Java threads
 */

#include "hpi_impl.h"

#include <windows.h>
#include <process.h>              /* for _beginthreadex(), _endthreadex() */
#include <stdlib.h>

#include "threads_md.h"
#include "monitor_md.h"


/*
 * Queue of active Java threads
 */
static sys_thread_t *ThreadQueue;
sys_mon_t *_sys_queue_lock;

static int ActiveThreadCount = 0;               /* All threads */

/*
 * Set to TRUE once threads have been bootstrapped
 */
bool_t ThreadsInitialized = FALSE;

/*
 * Are we running under Window NT
 */
static bool_t windowsNT = FALSE;

/*
 * Thread local storage index used for looking up sys_thread_t struct
 * (tid) associated with the current thread.
 */
#define TLS_INVALID_INDEX 0xffffffffUL
static unsigned long tls_index = TLS_INVALID_INDEX;

static void RecordNTTIB(sys_thread_t *tid)
{
#ifndef _WIN64
    PNT_TIB nt_tib;
    __asm {
        mov eax, dword ptr fs:[18h];
        mov nt_tib, eax;
    }
    tid->nt_tib = nt_tib;
#else
    tid->nt_tib = 0;
#endif
}

/*
 * Add thread to queue of active threads.
 */
static void
queueInsert(sys_thread_t *tid)
{
    if (ThreadsInitialized)
        SYS_QUEUE_LOCK(sysThreadSelf());
    ActiveThreadCount++;
    tid->next = ThreadQueue;
    ThreadQueue = tid;
    if (ThreadsInitialized)
        SYS_QUEUE_UNLOCK(sysThreadSelf());
    else
        ThreadsInitialized = TRUE;
}

/*
 * Remove thread from queue of active threads.
 */
static void
removefromActiveQ(sys_thread_t *tid)
{
    sysAssert(SYS_QUEUE_LOCKED(sysThreadSelf()));
    --ActiveThreadCount;

    if (ThreadQueue == tid) {
        ThreadQueue = tid->next;
    } else {
        sys_thread_t *p;
        for (p = ThreadQueue; p->next != 0; p = p->next) {
            if (p->next == tid) {
                p->next = tid->next;
                break;
            }
        }
    }
}

/*
 * Allocate and initialize the sys_thread_t structure for an arbitary
 * native thread.
 */
int
sysThreadAlloc(sys_thread_t **tidP)
{
    HANDLE hnd = GetCurrentProcess();
    sys_thread_t *tid = allocThreadBlock();
    if (tid == NULL) {
        return SYS_NOMEM;
    }

    tid->state = RUNNABLE;
    tid->interrupted = FALSE;
    tid->interrupt_event = CreateEvent(NULL, TRUE, FALSE, NULL);
    tid->id = GetCurrentThreadId();
    DuplicateHandle(hnd, GetCurrentThread(), hnd, &tid->handle, 0, FALSE,
                    DUPLICATE_SAME_ACCESS);

    RecordNTTIB(tid);
    /* For the Invocation API:
       We update the thread-specific storage before locking the
       queue because sysMonitorEnter will access sysThreadSelf.
     */
    TlsSetValue(tls_index, tid);

    queueInsert(tid);
    tid->stack_ptr = &tid;
    *tidP = tid;
    return SYS_OK;
}

/*
 * Bootstrap the Java thread system by making the current thread the
 * "primordial" thread.
 */
int threadBootstrapMD(sys_thread_t **tidP, sys_mon_t **lockP, int nb)
{
    OSVERSIONINFO windowsVersion;
    HANDLE hnd = GetCurrentProcess();

    nReservedBytes = (nb + 7) & (~7);
    /*
     * Allocate TLS index for thread-specific data.
     */
    tls_index = TlsAlloc();
    if (tls_index == TLS_INVALID_INDEX) {
        VM_CALL(jio_fprintf)(stderr, "TlsAlloc failed (errcode = %x)\n",
                    GetLastError());
        return SYS_NOMEM;
    }

    /* OS properties */
    windowsVersion.dwOSVersionInfoSize = sizeof(windowsVersion);
    GetVersionEx(&windowsVersion);
    windowsNT = windowsVersion.dwPlatformId == VER_PLATFORM_WIN32_NT;

   /* Initialize the queue lock monitor */
    _sys_queue_lock = (sys_mon_t *)sysMalloc(sysMonitorSizeof());
    if (_sys_queue_lock == NULL) {
        return SYS_ERR;
    }
    VM_CALL(monitorRegister)(_sys_queue_lock, "Thread queue lock");
    *lockP = _sys_queue_lock;

    return sysThreadAlloc(tidP);
}

/*
 * Return current stack pointer of specified thread.
 */
void *
sysThreadStackPointer(sys_thread_t *tid)
{
#ifndef _WIN64
    CONTEXT context;
    WORD __current_SS;

    /* REMIND: Need to fix this for Win95 */
    context.ContextFlags = CONTEXT_CONTROL;
    if (!GetThreadContext(tid->handle, &context)) {
        VM_CALL(jio_fprintf)(stderr, "GetThreadContext failed (errcode = %x)\n",
                GetLastError());
        return 0;
    }

    /* With the NT TIB stuff that Hong came up with, I don't think we
     * need any of the complicated VirtualQuery calls anymore. If
     * context.Esp is within the stack limit and base, we return
     * context.Esp, otherwise, we can simply return nt_tib->StackLimit.
     * To minimize code changes, though, I'm keeping the code the way
     * it was.
     */
    if (tid->nt_tib == NULL) {
        /* thread hasn't started yet. */
        return 0;
    }

    __asm {
        mov ax, ss;
        mov __current_SS, ax;
    }

    if (context.SegSs == __current_SS &&
        context.Esp >= (uintptr_t)(tid->nt_tib->StackLimit) &&
        context.Esp < (uintptr_t)(tid->nt_tib->StackBase)) {
        MEMORY_BASIC_INFORMATION mbi;

        VirtualQuery((PBYTE) context.Esp, &mbi, sizeof(mbi));

        if (!(mbi.Protect & PAGE_GUARD)) {
            return (void *) context.Esp;
        } else {
            SYSTEM_INFO si;
            char *Esp = (char*) context.Esp;
            DWORD dwPageSize;

            GetSystemInfo(&si);
            dwPageSize = si.dwPageSize;
            Esp -= (((DWORD) Esp) % dwPageSize);
            do {
                Esp += dwPageSize;
                VirtualQuery((PBYTE) Esp, &mbi, sizeof(mbi));
            } while (mbi.Protect & PAGE_GUARD);
            return Esp;
        }
    } else {
        /* segment selectors don't match - thread is in some weird context */
        MEMORY_BASIC_INFORMATION mbi;
        PBYTE pbStackHwm, pbStackBase;
        SYSTEM_INFO si;
        DWORD dwPageSize;
        stackp_t stack_ptr = tid->stack_ptr;

        if (stack_ptr == 0) {
            return 0;
        }
        GetSystemInfo(&si);
        dwPageSize = si.dwPageSize;
        VirtualQuery((PBYTE)stack_ptr - 1, &mbi, sizeof(mbi));
        pbStackBase = (PBYTE)mbi.AllocationBase;
        /* step backwards till beginning of segment, non-RW page, or guard
           page (guard pages only on WinNT) */
        do {
            pbStackHwm = (PBYTE)mbi.BaseAddress;
            if (pbStackHwm <= pbStackBase) {
                break;
            }
            VirtualQuery(pbStackHwm - dwPageSize, &mbi, sizeof(mbi));
        }
        while ((mbi.Protect & PAGE_READWRITE) &&
              !(mbi.Protect & PAGE_GUARD));
        /* the best we can do for now is the first page of stack
           storage - it should be a stack high-water mark, anyway */
        return (void *)pbStackHwm;
    }
#else
    return 0;
#endif
}

/*
 * Get the end of stack (if you step beyond (above or below depending
 * on your architecture) you can die.  We refer to the logical top of
 * stack.
 *
 * NOTE!  There are restrictions about when you can call this method.  If
 * you did a sysThreadAlloc, then you can call this method as soon as
 * sysThreadAlloc returns.  If you called sysThreadCreate(start_function),
 * then you must call sysThreadStackTop only inside start_function and not
 * as soon as sysThreadCreate returns.
 */
void *
sysThreadStackTop(sys_thread_t *tid)
{
  return 0; /* FIXME: Unimplemented. */
}

long *
sysThreadRegs(sys_thread_t *tid, int *nregs)
{
    *nregs = N_TRACED_REGS;
    return tid->regs;
}

/*
 * Thread start routine for new Java threads
 */
static unsigned __stdcall
_start(sys_thread_t *tid)
{
    /* Should thread suspend itself at this point? */

    tid->state = RUNNABLE;
    RecordNTTIB(tid);
    TlsSetValue(tls_index, tid);
    tid->stack_ptr = &tid;
    tid->start_proc(tid->start_parm);
    sysThreadFree();
    _endthreadex(0);
    /* not reached */
    return 0;
}

/*
 * Create a new Java thread. The thread is initially suspended.
 */
int
sysThreadCreate(sys_thread_t **tidP, long stack_size,
                void (*proc)(void *), void *arg)
{
    sys_thread_t *tid = allocThreadBlock();
    if (tid == NULL) {
        return SYS_NOMEM;
    }
    tid->state = SUSPENDED;
    tid->start_proc = proc;
    tid->start_parm = arg;

    tid->interrupt_event = CreateEvent(NULL, TRUE, FALSE, NULL);

    /*
     * Start the new thread.
     */
    tid->handle = (HANDLE)_beginthreadex(NULL, stack_size, _start, tid,
                                         CREATE_SUSPENDED, &tid->id);
    if (tid->handle == 0) {
        return SYS_NORESOURCE;  /* Will be treated as though SYS_NOMEM */
    }

    queueInsert(tid);
    *tidP = tid;
    return SYS_OK;
}

/*
 * Free a system thread block.
 * Remove from the thread queue.
 */
int
sysThreadFree()
{
    sys_thread_t *tid = sysThreadSelf();

    /*
     * remove ourselves from the thread queue.  This must be done after
     * the notify above since monitor operations aren't really safe if
     * your thread isn't on the thread queue.  (This isn't true of
     * the sysMonitor* functions, only monitor*)
     */
    SYS_QUEUE_LOCK(tid);
    removefromActiveQ(tid);
    SYS_QUEUE_UNLOCK(tid);

    /* For invocation API: later sysThreadSelf() calls will return 0 */
    TlsSetValue(tls_index, 0);

    /*
     * Close the thread and interrupt event handles, and free the
     * sys_thread_t structure.
     */
    CloseHandle(tid->handle);
    CloseHandle(tid->interrupt_event);
    freeThreadBlock(tid);
    return SYS_OK;
}

/*
 * Yield control to another thread.
 */
void
sysThreadYield(void)
{
    Sleep(0);
}

/*
 * Suspend execution of the specified thread.
 */
int
sysThreadSuspend(sys_thread_t *tid)
{
    /* REMIND: Fix for Win95 */
    /* Set state first so state is reflected before this thread */
    /* returns.  Fix suggested by ARB of SAS  */
    thread_state_t oldstate = tid->state;
    sys_thread_t *self = sysThreadSelf();

    if (tid == self) {
        self->state = SUSPENDED;
    } else {
        switch(tid->state) {
            case RUNNABLE:
                tid->state = SUSPENDED;
                break;
            case MONITOR_WAIT:
                tid->state = SUSPENDED;
                tid->suspend_flags |= MONITOR_WAIT_SUSPENDED;
                break;
            case CONDVAR_WAIT:
                tid->state = SUSPENDED;
                tid->suspend_flags |= CONDVAR_WAIT_SUSPENDED;
                break;
            case SUSPENDED:
            case MONITOR_SUSPENDED:
            default:
                return SYS_ERR;
        }
    }
    if (SuspendThread(tid->handle) == 0xffffffffUL) {
        tid->state = oldstate;
        tid->suspend_flags = 0;
        return SYS_ERR;
    }
    return SYS_OK;
}

/*
 * Continue execution of the specified thread.
 */
int
sysThreadResume(sys_thread_t *tid)
{
    unsigned long n;

    if (tid->suspend_flags & MONITOR_WAIT_SUSPENDED) {
        tid->suspend_flags = 0;
        tid->state = MONITOR_WAIT;
    } else if (tid->suspend_flags & CONDVAR_WAIT_SUSPENDED) {
        tid->suspend_flags = 0;
        tid->state = CONDVAR_WAIT;
    } else {
        switch(tid->state) {
            case SUSPENDED:
                tid->state = RUNNABLE;
                break;
            case MONITOR_SUSPENDED:
                tid->state = MONITOR_WAIT;
                break;
            case RUNNABLE:
            case MONITOR_WAIT:
            case CONDVAR_WAIT:
            default:
                return SYS_ERR;
                break;
        }
    }

    /* Decrement thread's suspend count until no longer suspended */
    while ((n = ResumeThread(tid->handle)) > 1) {
        if (n == 0xffffffffUL) {
            return SYS_ERR;
        }
    }
    return SYS_OK;
}

/*
 * Return priority of specified thread.
 */
int
sysThreadGetPriority(sys_thread_t *tid, int *pp)
{
    switch (GetThreadPriority(tid->handle)) {
    case THREAD_PRIORITY_IDLE:
        *pp = 0; break;
    case THREAD_PRIORITY_LOWEST:
        *pp = 2; break;
    case THREAD_PRIORITY_BELOW_NORMAL:
        *pp = 4; break;
    case THREAD_PRIORITY_NORMAL:
        *pp = 5; break;
    case THREAD_PRIORITY_ABOVE_NORMAL:
        *pp = 6; break;
    case THREAD_PRIORITY_HIGHEST:
        *pp = 8; break;
    case THREAD_PRIORITY_TIME_CRITICAL:
        *pp = 10; break;
    case THREAD_PRIORITY_ERROR_RETURN:
        return SYS_ERR;
    }
    return SYS_OK;
}

/*
 * Set priority of specified thread.
 */
int
sysThreadSetPriority(sys_thread_t *tid, int p)
{
    int priority;

    switch (p) {
    case 0:
        priority = THREAD_PRIORITY_IDLE;
        break;
    case 1: case 2:
        priority = THREAD_PRIORITY_LOWEST;
        break;
    case 3: case 4:
        priority = THREAD_PRIORITY_BELOW_NORMAL;
        break;
    case 5:
        priority = THREAD_PRIORITY_NORMAL;
        break;
    case 6: case 7:
        priority = THREAD_PRIORITY_ABOVE_NORMAL;
        break;
    case 8: case 9:
        priority = THREAD_PRIORITY_HIGHEST;
        break;
    case 10:
        priority = THREAD_PRIORITY_TIME_CRITICAL;
        break;
    default:
        return SYS_ERR;
    }
    return SetThreadPriority(tid->handle, priority) ? SYS_OK : SYS_ERR;
}

/*
 * Return the thread information block of the calling thread.
 */
sys_thread_t *
sysThreadSelf(void)
{
    return tls_index == 0xffffffffUL ? 0 : TlsGetValue(tls_index);
}

/*
 * Enumerate over all threads in active queue calling a function for
 * each one.  Expects the caller to lock _queue_lock
 */
int
sysThreadEnumerateOver(int (*func)(sys_thread_t *, void *), void *arg)
{
    sys_thread_t *tid;
    int ret = SYS_OK;
    sys_thread_t *self = sysThreadSelf();

    sysAssert(SYS_QUEUE_LOCKED(sysThreadSelf()));

    for (tid = ThreadQueue; tid != 0; tid = tid->next) {
        if ((ret = (*func)(tid, arg)) != SYS_OK) {
            break;
        }
    }
    return ret;
}

/*
 * Helper function for sysThreadSingle()
 */
static int
threadSingleHelper(sys_thread_t *tid, void *self)
{
    if (tid == self) {
        return SYS_OK;
    }
    if (SuspendThread(tid->handle) == 0xffffffffUL) {
        return SYS_ERR;
    }
    {
        CONTEXT context;
        DWORD *esp = (DWORD *)tid->regs;

        context.ContextFlags = CONTEXT_INTEGER | CONTEXT_CONTROL;
        if (!GetThreadContext(tid->handle, &context)) {
            VM_CALL(jio_fprintf)
                (stderr, "GetThreadContext failed (errcode = %x)\n",
                 GetLastError());
            return SYS_ERR;
        }
#ifdef _M_AMD64
        *esp++ = context.Rax;
        *esp++ = context.Rbx;
        *esp++ = context.Rcx;
        *esp++ = context.Rdx;
        *esp++ = context.Rsi;
        *esp++ = context.Rdi;
        *esp   = context.Rbp;
#else
        *esp++ = context.Eax;
        *esp++ = context.Ebx;
        *esp++ = context.Ecx;
        *esp++ = context.Edx;
        *esp++ = context.Esi;
        *esp++ = context.Edi;
        *esp   = context.Ebp;
#endif
    }
    return SYS_OK;
}

/*
 * Puts each thread in the active thread queue to sleep except for the
 * calling thread. The threads must be later woken up with a corresponding
 * call to 'sysThreadMulti'. Returns SYS_OK on success, or SYS_ERR if any
 * of the threads could not be suspended.
 */
int
sysThreadSingle(void)
{
    return sysThreadEnumerateOver(threadSingleHelper, sysThreadSelf());
}

/*
 * Helper function for sysThreadMulti(): Only ResumeThread once, unlike
 * sysThreadResume(), which will repeatedly call ResumeThread until the
 * thread is really resumed.  That is, Thread.resume will unwind any
 * number of Thread.suspend invocations, but sysThreadMulti() calls must
 * be strictly matched with sysThreadSingle() calls.  Doing this keeps
 * the garbage collector, which uses thread suspension to stop threads
 * while it operates, from waking up threads that were already suspended
 * when GC was invoked.
 */
static int
threadMultiHelper(sys_thread_t *tid, void *self)
{
    if (tid == self || ResumeThread(tid->handle) != 0xffffffffUL) {
        return SYS_OK;
    } else {
        return SYS_ERR;
    }
}

/*
 * Wakes up each thread in active thread queue except for the calling
 * thread.  The mechanism uses thread suspension, and will not wake a
 * thread that was already suspended.  Must be matched 1-1 with calls
 * to sysThreadSingle().  Returns SYS_ERR if not all threads could be
 * woken up.
 */
void
sysThreadMulti(void)
{
    sysThreadEnumerateOver(threadMultiHelper, sysThreadSelf());
}

/*
 * Dump system-specific information about threads.
 */
void *
sysThreadNativeID(sys_thread_t *tid)
{
    return (void *)(uintptr_t)tid->id;
}

int
sysThreadCheckStack(void)
{
    return 1;
}

/*
 * The mechanics of actually signalling an exception (in the future,
 * and Alarm or Interrupt) depend upon what thread implementation you
 * are using.
 */
void
sysThreadPostException(sys_thread_t *tid, void *exc)
{
    /* Interrupt the thread if it's waiting; REMIND: race??? */
    SetEvent(tid->interrupt_event);
}

/*
 * Support for (Java-level) interrupts.
 */
void
sysThreadInterrupt(sys_thread_t *tid)
{
    if (tid->interrupted == FALSE) {
        tid->interrupted = TRUE;
        SetEvent(tid->interrupt_event);
    }
}

int
sysThreadIsInterrupted(sys_thread_t *tid, int ClearInterrupted)
{
    bool_t interrupted = tid->interrupted;
    if (interrupted && ClearInterrupted) {
        tid->interrupted = FALSE;
        ResetEvent(tid->interrupt_event);
    }
    return interrupted;
}

HPI_SysInfo *
sysGetSysInfo()
{
    static HPI_SysInfo info = {0, 0};

    if (info.name == NULL) {
        SYSTEM_INFO sysinfo;
        GetSystemInfo(&sysinfo);
        info.isMP = sysinfo.dwNumberOfProcessors > 1;
        info.name = "native threads";
    }
    return &info;
}

#define FT2INT64(ft) \
        ((jlong)(ft).dwHighDateTime << 32 | (jlong)(ft).dwLowDateTime)

jlong
sysThreadCPUTime()
{
    if (windowsNT) {
        FILETIME CreationTime;
        FILETIME ExitTime;
        FILETIME KernelTime;
        FILETIME UserTime;

        GetThreadTimes(GetCurrentThread(),
                       &CreationTime, &ExitTime, &KernelTime, &UserTime);
        return FT2INT64(UserTime) * 100;
    } else {
        return (jlong)sysGetMilliTicks() * 1000000;
    }
}

int
sysThreadGetStatus(sys_thread_t *tid, sys_mon_t **monitorPtr)
{
    int status;
    switch (tid->state) {
      case RUNNABLE:
          if (tid->enter_monitor)
              status = SYS_THREAD_MONITOR_WAIT;
          else
              status = SYS_THREAD_RUNNABLE;
          break;
      case SUSPENDED:
          if (tid->enter_monitor)
              status = SYS_THREAD_SUSPENDED | SYS_THREAD_MONITOR_WAIT;
          else if (tid->suspend_flags & CONDVAR_WAIT_SUSPENDED)
              status = SYS_THREAD_SUSPENDED | SYS_THREAD_CONDVAR_WAIT;
          else
              status = SYS_THREAD_SUSPENDED;
          break;
      case MONITOR_SUSPENDED:
          status = SYS_THREAD_SUSPENDED | SYS_THREAD_MONITOR_WAIT;
          break;
      case CONDVAR_WAIT:
          status = SYS_THREAD_CONDVAR_WAIT;
          break;
      case MONITOR_WAIT:
          /*
           * this flag should never be in used on win32 since the
           * state is actually signalled by setting self->enter_monitor
           * to point at the monitor the thread is waiting to enter
           */
          sysAssert(FALSE);
      default:
          return SYS_ERR;
    }
    if (monitorPtr) {
        if (status & SYS_THREAD_MONITOR_WAIT) {
            *monitorPtr = tid->enter_monitor;
        } else if (status & SYS_THREAD_CONDVAR_WAIT) {
            *monitorPtr = tid->wait_monitor;
        } else {
            *monitorPtr = NULL;
        }
    }
    return status;
}

int sysAdjustTimeSlice(int i)
{
    return JNI_ERR;
}

void sysThreadProfSuspend(sys_thread_t *tid)
{
    SuspendThread(tid->handle);
}

void sysThreadProfResume(sys_thread_t *tid)
{
    ResumeThread(tid->handle);
}

bool_t sysThreadIsRunning(sys_thread_t *tid)
{
#ifndef _M_AMD64
    unsigned int sum = 0;
    unsigned int *p;
    CONTEXT context;

    context.ContextFlags = CONTEXT_FULL;
    GetThreadContext(tid->handle, &context);
    p = &context.SegGs;
    while (p <= &context.SegSs) {
        sum += *p;
        p++;
    }

    if (sum == tid->last_sum) {
        return FALSE;
    }
    tid->last_sum = sum;
#endif
    return TRUE;
}

void *
sysThreadInterruptEvent()
{
    return sysThreadSelf()->interrupt_event;
}
