/*
 * 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,(union semun)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;	
}

