/*
 * Win32 kernel functions
 *
 * Copyright 1995 Martin von Loewis
 * Copyright 1997 Onno Hovers
 */

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include "windows.h"
#include "winbase.h"
#include "winerror.h"
#include "stddebug.h"
#include "debug.h"


/*
 * FIXME: 
 * The c functions do not protect from non-interlocked accesses
 * This is no problem as long as we do not have multiple Win32 threads 
 * or processes. 
 * The assembly macro's do protect from non-interlocked access,
 * but they will only work for i386 systems with GCC.  
 */
 
/************************************************************************
*           InterlockedIncrement			[KERNEL32]	*
*									*
* InterlockedIncrement adds 1 to a long variable and returns		*
*  -  a negative number if the result < 0				*
*  -  zero if the result == 0						*
*  -  a positive number if the result > 0				*
*									*
* The returned number need not be equal to the result!!!!		*
************************************************************************/

LONG WINAPI InterlockedIncrement(LPLONG lpAddend)
{
#if defined(__i386__)&&defined(__GNUC__)
	long ret;
	__asm__
	(	  	 
	   "\tlock\n"	/* for SMP systems */
	   "\tincl	(%1)\n"
	   "\tje	2f\n"
	   "\tjl	1f\n"
	   "\tincl	%0\n"
	   "\tjmp	2f\n"
	   "1:\tdec	%0\n"    	  
	   "2:\n"
	   :"=r" (ret):"r" (lpAddend), "0" (0): "memory"
	);
	return ret;
#else      
	LONG ret;
	/* StopAllThreadsAndProcesses() */
	
	(*lpAddend)++;
	ret=*lpAddend;

	/* ResumeAllThreadsAndProcesses() */
	return ret;
#endif	 
}

/************************************************************************
*           InterlockedDecrement			[KERNEL32]	*
*									*
* InterlockedIncrement adds 1 to a long variable and returns		*
*  -  a negative number if the result < 0				*
*  -  zero if the result == 0						*
*  -  a positive number if the result > 0				*
*									*
* The returned number need not be equal to the result!!!!		*
************************************************************************/

LONG WINAPI InterlockedDecrement(LPLONG lpAddend)
{
#if defined(__i386__)&&defined(__GNUC__)	
	LONG ret;
	__asm__
	(	  	 
	   "\tlock\n"	/* for SMP systems */
	   "\tdecl	(%1)\n"
	   "\tje	2f\n"
	   "\tjl	1f\n"
	   "\tincl	%0\n"
	   "\tjmp	2f\n"
	   "1:\tdec	%0\n"    	  
	   "2:\n"
	   :"=r" (ret):"r" (lpAddend), "0" (0): "memory"          
	);
	return ret;
#else	
	LONG ret;
	/* StopAllThreadsAndProcesses() */

	(*lpAddend)--;
	ret=*lpAddend;

	/* ResumeAllThreadsAndProcesses() */
	return ret;
#endif	
}

/************************************************************************
*           InterlockedExchange				[KERNEL32]	*
************************************************************************/

LONG WINAPI InterlockedExchange(LPLONG target, LONG value)
{
#if defined(__i386__)&&defined(__GNUC__)	
	LONG ret;
	__asm__
	(	  	 

           "\tlock\n"	/* for SMP systems */
	   "\txchgl	%0,(%1)\n"	   	  
	   :"=r" (ret):"r" (target), "0" (value):"memory"
	);
	return ret;
#else
	LONG ret;
	/* StopAllThreadsAndProcesses() */	

	ret=*target;
	*target=value;

	/* ResumeAllThreadsAndProcesses() */
	return ret;
#endif	
}

/* AAARGHH some CriticalSection functions get called before we 
 * have a threadid
 */
 
#define GetCurrentThreadId()	(-1)

/************************************************************************
*           InitializeCriticalSection			[KERNEL32]	*
************************************************************************/

void WINAPI InitializeCriticalSection(CRITICAL_SECTION *pcritical)
{
   pcritical->LockCount=-1;
   pcritical->RecursionCount=0;
   pcritical->LockSemaphore=(HANDLE32) semget(IPC_PRIVATE,1,IPC_CREAT);
   pcritical->OwningThread=(HANDLE32) -1;
   pcritical->Reserved=0;
}

/************************************************************************
*           DeleteCriticalSection			[KERNEL32]	*
************************************************************************/

void WINAPI DeleteCriticalSection(CRITICAL_SECTION *pcritical)
{
   semctl((int) pcritical->LockSemaphore,0,IPC_RMID, (void *)0);
   pcritical->Reserved=-1;
}

/************************************************************************
*           EnterCriticalSection			[KERNEL32]	*
************************************************************************/

void WINAPI EnterCriticalSection (CRITICAL_SECTION *pcritical)
{
   if( InterlockedIncrement(&(pcritical->LockCount)))
   {   
      if( pcritical->OwningThread!= (HANDLE32) GetCurrentThreadId() )
      {                 
         struct sembuf sop;
                                             
         sop.sem_num=0;
         sop.sem_op=0;
         sop.sem_flg=0;            
         semop((int) pcritical->LockSemaphore,&sop,0);
            
         pcritical->OwningThread = (HANDLE32) GetCurrentThreadId();                
      }
   }
   else
   {      
      pcritical->OwningThread =(HANDLE32) GetCurrentThreadId();
   }
   pcritical->RecursionCount++;             
}

/************************************************************************
*           TryEnterCriticalSection			[KERNEL32]	*
************************************************************************/

BOOL32 WINAPI TryEnterCriticalSection (CRITICAL_SECTION *pcritical)
{
   if( InterlockedIncrement(&(pcritical->LockCount)))
   {
      if( pcritical->OwningThread!= (HANDLE32) GetCurrentThreadId() )
         return FALSE;
   }
   else
   {      
      pcritical->OwningThread =(HANDLE32) GetCurrentThreadId();
   }
   pcritical->RecursionCount++;             
   
   return TRUE;
}

/************************************************************************
*           LeaveCriticalSection			[KERNEL32]	*
************************************************************************/

void WINAPI LeaveCriticalSection(CRITICAL_SECTION *pcritical)
{
   /* do we actually own this critical section ??? */
   if( pcritical->OwningThread!= (HANDLE32) GetCurrentThreadId())
      return;
       
   pcritical->RecursionCount--;
   if( pcritical->RecursionCount==0)
   {
      pcritical->OwningThread=(HANDLE32)-1;
      if(InterlockedDecrement(&(pcritical->LockCount))>=0)
      {         
         struct sembuf sop;
         
         sop.sem_num=0;
         sop.sem_op=1;
         sop.sem_flg=0;
         semop((int) pcritical->LockSemaphore,&sop,0);
      }
   }
   else
   {
       InterlockedDecrement(&(pcritical->LockCount));
   }  
}

/************************************************************************
*           ReinitializeCriticalSection			[KERNEL32]	*
************************************************************************/

void WINAPI ReinitializeCriticalSection(CRITICAL_SECTION *lpCrit)
{
   /* hmm ?????? */	
}

/************************************************************************
*           MakeCriticalSectionGlobal			[KERNEL32]	*
************************************************************************/

void WINAPI MakeCriticalSectionGlobal(CRITICAL_SECTION *lpCrit)
{
   /* nothing (SysV Semaphores are already global) */
   return;	
}

