/* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries * FILE: lib/kernel32/sync/intrlck.c * PURPOSE: Inter lock increments * UPDATE HISTORY: * Created 30/09/99 */ /* * Win32 kernel functions * * Copyright 1995 Martin von Loewis * Copyright 1997 Onno Hovers */ /************************************************************************ * InterlockedIncrement * * * * 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!!!! * * note: * * * ************************************************************************/ #include LONG STDCALL InterlockedIncrement(PLONG Addend) { long ret = 0; __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" (Addend), "0" (0): "memory" ); return ret; } /************************************************************************ * InterlockedDecrement * * * * 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 STDCALL InterlockedDecrement(LPLONG lpAddend) { 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; } /************************************************************************ * InterlockedExchange * * Atomically exchanges a pair of values. * * RETURNS * Prior value of value pointed to by Target */ LONG STDCALL InterlockedExchange(LPLONG target, LONG value ) { long ret; __asm__ ( /* lock for SMP systems */ "lock\n\txchgl %0,(%1)" :"=r" (ret):"r" (target), "0" (value):"memory" ); return ret; } /************************************************************************ * InterlockedCompareExchange * * Atomically compares Destination and Comperand, and if found equal exchanges * the value of Destination with Exchange * * RETURNS * Prior value of value pointed to by Destination */ PVOID STDCALL InterlockedCompareExchange( PVOID *Destination, PVOID Exchange, PVOID Comperand ) { PVOID ret; __asm__ ( /* lock for SMP systems */ "lock\n\t" "cmpxchgl %2,(%1)" :"=r" (ret) :"r" (Destination),"r" (Exchange), "0" (Comperand) :"memory" ); return ret; } /************************************************************************ * InterlockedExchangeAdd * * Atomically adds Increment to Addend and returns the previous value of * Addend * * RETURNS * Prior value of value pointed to by Addend */ LONG STDCALL InterlockedExchangeAdd( PLONG Addend, LONG Increment ) { LONG ret; __asm__ ( /* lock for SMP systems */ "lock\n\t" "xaddl %0,(%1)" :"=r" (ret) :"r" (Addend), "0" (Increment) :"memory" ); return ret; }