/*
 * 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"
#include "xmalloc.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 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 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 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 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 DeleteCriticalSection(CRITICAL_SECTION *pcritical)
{
   semctl((int) pcritical->LockSemaphore,0,IPC_RMID,NULL);
   pcritical->Reserved=-1;
}

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

void 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 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 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 ReinitializeCriticalSection(CRITICAL_SECTION *lpCrit)
{
   /* hmm ?????? */	
}

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

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

