/*
 * Win32 'syslevel' routines
 *
 * Copyright 1998 Ulrich Weigand
 */

#include <unistd.h>
#include <sys/types.h>
#include "ntddk.h"
#include "syslevel.h"
#include "heap.h"
#include "stackframe.h"
#include "debugtools.h"

DEFAULT_DEBUG_CHANNEL(win32);

static SYSLEVEL Win16Mutex = { CRITICAL_SECTION_INIT, 1 };

/* Global variable to save current TEB while in 16-bit code */
WORD SYSLEVEL_Win16CurrentTeb = 0;


/************************************************************************
 *           GetpWin16Lock    (KERNEL32.93)
 */
VOID WINAPI GetpWin16Lock(SYSLEVEL **lock)
{
    *lock = &Win16Mutex;
}

/************************************************************************
 *           GetpWin16Lock    (KERNEL.449)
 */
SEGPTR WINAPI GetpWin16Lock16(void)
{
    static SEGPTR segpWin16Mutex;
    if (!segpWin16Mutex)
    {
        SYSLEVEL **w16Mutex = SEGPTR_ALLOC(sizeof(SYSLEVEL *));
        *w16Mutex = &Win16Mutex;
        segpWin16Mutex = SEGPTR_GET(w16Mutex);
    }
    return segpWin16Mutex;
}

/************************************************************************
 *           _CreateSysLevel    (KERNEL.438)
 */
VOID WINAPI _CreateSysLevel(SYSLEVEL *lock, INT level)
{
    InitializeCriticalSection( &lock->crst );
    lock->level = level;

    TRACE("(%p, %d): handle is %d\n", 
                  lock, level, lock->crst.LockSemaphore );
}

/************************************************************************
 *           _EnterSysLevel    (KERNEL32.97)
 *           _EnterSysLevel    (KERNEL.439)
 */
VOID WINAPI _EnterSysLevel(SYSLEVEL *lock)
{
    TEB *teb = NtCurrentTeb();
    int i;

    TRACE("(%p, level %d): thread %p (fs %04x, pid %ld) count before %ld\n", 
                  lock, lock->level, teb->tid, teb->teb_sel, (long) getpid(),
                  teb->sys_count[lock->level] );

    for ( i = 3; i > lock->level; i-- )
        if ( teb->sys_count[i] > 0 )
        {
            ERR("(%p, level %d): Holding %p, level %d. Expect deadlock!\n", 
                        lock, lock->level, teb->sys_mutex[i], i );
        }

    EnterCriticalSection( &lock->crst );

    teb->sys_count[lock->level]++;
    teb->sys_mutex[lock->level] = lock;

    TRACE("(%p, level %d): thread %p (fs %04x, pid %ld) count after  %ld\n",
                  lock, lock->level, teb->tid, teb->teb_sel, (long) getpid(), 
                  teb->sys_count[lock->level] );

    if (lock == &Win16Mutex)
        SYSLEVEL_Win16CurrentTeb = __get_fs();
}

/************************************************************************
 *           _LeaveSysLevel    (KERNEL32.98)
 *           _LeaveSysLevel    (KERNEL.440)
 */
VOID WINAPI _LeaveSysLevel(SYSLEVEL *lock)
{
    TEB *teb = NtCurrentTeb();

    TRACE("(%p, level %d): thread %p (fs %04x, pid %ld) count before %ld\n", 
                  lock, lock->level, teb->tid, teb->teb_sel, (long) getpid(),
                  teb->sys_count[lock->level] );

    if ( teb->sys_count[lock->level] <= 0 || teb->sys_mutex[lock->level] != lock )
    {
        ERR("(%p, level %d): Invalid state: count %ld mutex %p.\n",
                    lock, lock->level, teb->sys_count[lock->level], 
                    teb->sys_mutex[lock->level] );
    }
    else
    {
        if ( --teb->sys_count[lock->level] == 0 )
            teb->sys_mutex[lock->level] = NULL;
    }

    LeaveCriticalSection( &lock->crst );

    TRACE("(%p, level %d): thread %p (fs %04x, pid %ld) count after  %ld\n",
                  lock, lock->level, teb->tid, teb->teb_sel, (long) getpid(), 
                  teb->sys_count[lock->level] );
}

/************************************************************************
 *		@ (KERNEL32.86)
 */
VOID WINAPI _KERNEL32_86(SYSLEVEL *lock)
{
    _LeaveSysLevel(lock);
}

/************************************************************************
 *           _ConfirmSysLevel    (KERNEL32.95)
 *           _ConfirmSysLevel    (KERNEL.436)
 */
DWORD WINAPI _ConfirmSysLevel(SYSLEVEL *lock)
{
    if ( lock && lock->crst.OwningThread == GetCurrentThreadId() )
        return lock->crst.RecursionCount;
    else
        return 0L;
}

/************************************************************************
 *           _CheckNotSysLevel    (KERNEL32.94)
 *           _CheckNotSysLevel    (KERNEL.437)
 */
VOID WINAPI _CheckNotSysLevel(SYSLEVEL *lock)
{
    FIXME("(%p)\n", lock);
}


/************************************************************************
 *           _EnterWin16Lock			[KERNEL.480]
 */
VOID WINAPI _EnterWin16Lock(void)
{
    _EnterSysLevel(&Win16Mutex);
}

/************************************************************************
 *           _LeaveWin16Lock		[KERNEL.481]
 */
VOID WINAPI _LeaveWin16Lock(void)
{
    _LeaveSysLevel(&Win16Mutex);
}

/************************************************************************
 *           _ConfirmWin16Lock    (KERNEL32.96)
 */
DWORD WINAPI _ConfirmWin16Lock(void)
{
    return _ConfirmSysLevel(&Win16Mutex);
}

/************************************************************************
 *           ReleaseThunkLock    (KERNEL32.48)
 */
VOID WINAPI ReleaseThunkLock(DWORD *mutex_count)
{
    DWORD count = _ConfirmSysLevel(&Win16Mutex);
    *mutex_count = count;

    while (count-- > 0)
        _LeaveSysLevel(&Win16Mutex);
}

/************************************************************************
 *           RestoreThunkLock    (KERNEL32.49)
 */
VOID WINAPI RestoreThunkLock(DWORD mutex_count)
{
    while (mutex_count-- > 0)
        _EnterSysLevel(&Win16Mutex);
}

/************************************************************************
 *           SYSLEVEL_CheckNotLevel
 */
VOID SYSLEVEL_CheckNotLevel( INT level )
{
    INT i;

    for ( i = 3; i >= level; i-- )
        if ( NtCurrentTeb()->sys_count[i] > 0 )
        {
            ERR("(%d): Holding lock of level %d!\n", 
                       level, i );
            DbgBreakPoint();
            break;
        }
}
