Example #1
0
static VALUE ir_compare_and_set(volatile VALUE self, VALUE expect_value, VALUE new_value) {
#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1050
    if (OSAtomicCompareAndSwap64(expect_value, new_value, &DATA_PTR(self))) {
	return Qtrue;
    }
#elif defined(__sun)
/*  Assuming VALUE is uintptr_t */
/*  Based on the definition of uintptr_t from /usr/include/sys/int_types.h */
#if defined(_LP64) || defined(_I32LPx)
    /*  64-bit: uintptr_t === unsigned long */
    if (atomic_cas_ulong((uintptr_t *) &DATA_PTR(self), expect_value, new_value)) {
        return Qtrue;
    }
#else
    /*  32-bit: uintptr_t === unsigned int */
    if (atomic_cas_uint((uintptr_t *) &DATA_PTR(self), expect_value, new_value)) {
        return Qtrue;
    }
#endif
#elif defined _MSC_VER && defined _M_AMD64
    if (InterlockedCompareExchange64((LONGLONG*)&DATA_PTR(self), new_value, expect_value)) {
	return Qtrue;
    }
#elif defined _MSC_VER && defined _M_IX86
    if (InterlockedCompareExchange((LONG*)&DATA_PTR(self), new_value, expect_value)) {
	return Qtrue;
    }
#else
    if (__sync_bool_compare_and_swap(&DATA_PTR(self), expect_value, new_value)) {
	return Qtrue;
    }
#endif
    return Qfalse;
}
EFIAPI
InterlockedCompareExchangePointer (
  IN OUT  VOID                      **Value,
  IN      VOID                      *CompareValue,
  IN      VOID                      *ExchangeValue
  )
{
  UINT8  SizeOfValue;

  SizeOfValue = sizeof (*Value);

  switch (SizeOfValue) {
    case sizeof (UINT32):
      return (VOID*)(UINTN)InterlockedCompareExchange32 (
                             (UINT32*)Value,
                             (UINT32)(UINTN)CompareValue,
                             (UINT32)(UINTN)ExchangeValue
                             );
    case sizeof (UINT64):
      return (VOID*)(UINTN)InterlockedCompareExchange64 (
                             (UINT64*)Value,
                             (UINT64)(UINTN)CompareValue,
                             (UINT64)(UINTN)ExchangeValue
                             );
    default:
      ASSERT (FALSE);
      return NULL;
  }
}
Example #3
0
__int64 _InterlockedOr64 (__int64 volatile *Destination,__int64 Value)
{
  __int64 Old;
  do {
    Old = *Destination;
  } while(InterlockedCompareExchange64(Destination,Old | Value,Old)!=Old);
  return Old;
}
void baked_light_baker_add_64i(int64_t *dst,int64_t value) {

	while(true) {
		int64_t from = *dst;
		int64_t to = from+value;
		int64_t result = InterlockedCompareExchange64(dst,to,from);
		if (result==from)
			break;
	}
}
Example #5
0
INLINE void *compare_exchange_ptr(void * volatile *ptr, void *compare, void *exchange)
{
#ifdef PTR64
	INT64 result = InterlockedCompareExchange64((LONGLONG *)ptr, (LONGLONG)exchange, (LONGLONG)compare);
	return (void *)result;
#else
	INT32 result = InterlockedCompareExchange((LPLONG)ptr, (LONG)exchange, (LONG)compare);
	return (void *)result;
#endif
}
RU64
    rInterlocked_get64
    (
        volatile RU64* pRu64
    )
{
#ifdef RPAL_PLATFORM_WINDOWS
    return InterlockedCompareExchange64( (LONG64*)pRu64, *pRu64, *pRu64 );
#elif defined( RPAL_PLATFORM_LINUX ) || defined( RPAL_PLATFORM_MACOSX )
    return __sync_fetch_and_or( pRu64, 0 );
#endif
}
Example #7
0
// static
void CycleTimer::InterlockedAddU64(unsigned __int64* loc, unsigned __int64 amount)
{
    volatile __int64* vloc = (volatile __int64*)loc;
    unsigned __int64 prev = *vloc;
    for (;;)
    {
        unsigned __int64 next = prev + amount;
        __int64 snext = (__int64)next;
        __int64 sprev = (__int64)prev;
        __int64 res = InterlockedCompareExchange64(vloc, snext, sprev);
        if (res == sprev) return;
        else prev = (unsigned __int64)res;
    }
}
    int64 SequenceNumber::GetNext()
    {
        int64 value = DateTime::Now().Ticks;
        int64 oldValue;

        do
        {
            oldValue = LastTimeStamp;
            if (value <= oldValue)
            {
                value = oldValue + 1;
            }
        } while (InterlockedCompareExchange64(&LastTimeStamp, value, oldValue) != oldValue);

        return value;
    }
Example #9
0
/* Wait for spin lock */
static int slwait (LOCKLONG *sl)
{

    LOCKLONG Destination = *sl;
    LONG Exchange = 1;
    LONG Comparand = 0;
#if _WIN64
    while (InterlockedCompareExchange64(&Destination, Exchange, Comparand))

#else
    while (InterlockedCompareExchange (&Destination, Exchange, Comparand))
#endif
    {
        Sleep (0);
    }
    *sl = Destination;
    return 0;
}
void baked_light_baker_add_64f(double *dst,double value) {

	union {
		int64_t i;
		double f;
	} swapy;


	while(true) {
		swapy.f=*dst;
		int64_t from = swapy.i;
		swapy.f+=value;
		int64_t to=swapy.i;
		int64_t result = InterlockedCompareExchange64((int64_t*)dst,to,from);
		if (result==from)
			break;
	}

}
Example #11
0
int64 ThreadInterlockedCompareExchange64( int64 volatile *pDest, int64 value, int64 comperand )
{
	Assert( (size_t)pDest % 8 == 0 );

#if defined(_WIN64) || defined (_X360)
	return InterlockedCompareExchange64( pDest, value, comperand );
#else
	__asm 
	{
		lea esi,comperand;
		lea edi,value;

		mov eax,[esi];
		mov edx,4[esi];
		mov ebx,[edi];
		mov ecx,4[edi];
		mov esi,pDest;
		lock CMPXCHG8B [esi];			
	}
#endif
}
 static inline bool compare_exchange(volatile Type& storage, Type& expected, Type desired) {
   Type temp_expected = expected;
   Type previous = static_cast<Type>(InterlockedCompareExchange64((__int64*)&storage, (__int64)desired, (__int64)temp_expected));
   expected = previous;
   return (previous == temp_expected);
 }
Example #13
0
		bool compareAndExchange64(int64_t volatile* dest, int64_t exchange, int64_t comperand)
		{
			return InterlockedCompareExchange64(dest, exchange, comperand) == comperand;
		}
Example #14
0
//---------------------------------------------------------------------------
int64_t interlockedCompareExchange(volatile int64_t & v,int64_t exValue,int64_t cmpValue)
{
  return InterlockedCompareExchange64((LONGLONG *) &v,exValue,cmpValue);
}
Example #15
0
 inline ::LONGLONG compare_exchange
     ( ::LONGLONG z, volatile ::LONGLONG& x, ::LONGLONG y )
 {
     return InterlockedCompareExchange64(&x, y, z);
 }
Example #16
0
int __cdecl main(int argc, char *argv[]) {
  
    LONGLONG BaseVariableToManipulate = START_VALUE;
    LONGLONG ValueToExchange = SECOND_VALUE;
    LONGLONG TempValue;
    LONGLONG TheReturn;

    /*
     * Initialize the PAL and return FAILURE if this fails
     */

    if(0 != (PAL_Initialize(argc, argv)))
    {
        return FAIL;
    }

/*
**  Run only on 64 bit platforms
*/
#if defined(BIT64) && defined(PLATFORM_UNIX)
    /* Compare START_VALUE with BaseVariableToManipulate, they're equal, 
       so exchange 
    */
  
    TheReturn = InterlockedCompareExchange64(
        &BaseVariableToManipulate, /* Destination */
        ValueToExchange,           /* Exchange value */
        START_VALUE);              /* Compare value */
  
    /* Exchanged, these should be equal now */
    if(BaseVariableToManipulate != ValueToExchange) 
    {
#ifdef PLATFORM_UNIX
        Fail("ERROR: A successful compare and exchange should have occurred, "
             "making the variable have the value of %ll, as opposed to the "
             "current value of %ll.",
             ValueToExchange,BaseVariableToManipulate);  
#else
        Fail("ERROR: A successful compare and exchange should have occurred, "
             "making the variable have the value of %I64, as opposed to the "
             "current value of %d.",
             ValueToExchange,BaseVariableToManipulate);  

#endif
    }
  
    /* Check to make sure it returns the original number which 
       'BaseVariableToManipulate' was set to.  
    */
    if(TheReturn != START_VALUE) 
    {
#ifdef PLATFORM_UNIX
        Fail("ERROR: The return value after the first exchange should be the "
             "former value of the variable, which was %ll, but it is now %ll.",
             START_VALUE,TheReturn);
#else
        Fail("ERROR: The return value after the first exchange should be the "
             "former value of the variable, which was %I64, but it is now %I64.",
             START_VALUE,TheReturn);
#endif

    }


  
    ValueToExchange = THIRD_VALUE;         /* Give this a new value */
    TempValue = BaseVariableToManipulate;  /* Note value of Base */
  
    /* 
       Do an exchange where 'BaseVariableToManipulate' doesn't 
       match -- therefore the exchange shouldn't happen.  
       So, it should end up the same as the 'TempValue' we saved.
    */ 
  
    InterlockedCompareExchange64(&BaseVariableToManipulate,
                               ValueToExchange,
                               START_VALUE);
  
    if(BaseVariableToManipulate != TempValue) 
    {
#ifdef PLATFORM_UNIX
        Fail("ERROR:  An attempted exchange should have failed due to "
             "the compare failing.  But, it seems to have succeeded.  The "
             "value should be %ll but is %ll in this case.",
             TempValue,BaseVariableToManipulate);  
#else
        Fail("ERROR:  An attempted exchange should have failed due to "
             "the compare failing.  But, it seems to have succeeded.  The "
             "value should be %I64 but is %I64 in this case.",
             TempValue,BaseVariableToManipulate);  
#endif
    }

#endif  //if defined(BIT64) && defined(PLATFORM_UNIX)
    PAL_Terminate();
    return PASS; 
}
Example #17
0
BOOLEAN
ExRemoveHeadNBQueue (
    IN PVOID Header,
    OUT PULONG64 Value
    )

/*++

Routine Description:

    This function removes a queue entry from the head of the specified
    non-blocking queue and returns the associated data value.

Arguments:

    Header - Supplies an opaque pointer to a non-blocking queue header.

    Value - Supplies a pointer to a variable that receives the queue
        element value.

Return Value:

    If an entry is removed from the specified non-blocking queue, then
    TRUE is returned as the function value. Otherwise, FALSE is returned.

--*/

{

    NBQUEUE_POINTER Head;
    PNBQUEUE_NODE HeadNode;
    NBQUEUE_POINTER Insert;
    NBQUEUE_POINTER Next;
    PNBQUEUE_NODE NextNode;
    PNBQUEUE_HEADER QueueHead;
    NBQUEUE_POINTER Tail;
    PNBQUEUE_NODE TailNode;

    //
    // The following loop is executed until an entry can be removed from
    // the specified non-blocking queue or until it can be determined that
    // the queue is empty.
    //

    QueueHead = (PNBQUEUE_HEADER)Header;
    do {

        //
        // Read the head queue pointer, the tail queue pointer, and the
        // next queue pointer of the head queue pointer making sure the
        // three pointers are coherent.
        //

        Head.Data = ReadForWriteAccess((volatile LONG64 *)(&QueueHead->Head.Data));
        Tail.Data = *((volatile LONG64 *)(&QueueHead->Tail.Data));
        HeadNode = UnpackNBQPointer(&Head);
        Next.Data = *((volatile LONG64 *)(&HeadNode->Next.Data));
        if (Head.Data == *((volatile LONG64 *)(&QueueHead->Head.Data))) {

            //
            // If the queue header node is equal to the queue tail node,
            // then either the queue is empty or the tail pointer is falling
            // behind. Otherwise, there is an entry in the queue that can
            // be removed.
            //

            NextNode = UnpackNBQPointer(&Next);
            TailNode = UnpackNBQPointer(&Tail);
            if (HeadNode == TailNode) {

                //
                // If the next node of head pointer is NULL, then the queue
                // is empty. Otherwise, attempt to move the tail forward.
                //

                if (NextNode == NULL) {
                    return FALSE;

                } else {
                    PackNBQPointer(&Insert, NextNode);
                    Insert.Count = Tail.Count + 1;
                    InterlockedCompareExchange64(&QueueHead->Tail.Data,
                                                 Insert.Data,
                                                 Tail.Data);
                }

            } else {

                //
                // There is an entry in the queue that can be removed.
                //

                *Value = NextNode->Value;
                PackNBQPointer(&Insert, NextNode);
                Insert.Count = Head.Count + 1;
                if (InterlockedCompareExchange64(&QueueHead->Head.Data,
                                                 Insert.Data,
                                                 Head.Data) == Head.Data) {

                    break;
                }
            }
        }

    } while (TRUE);

    //
    // Free the node that was removed for the list by inserting the node
    // in the associated SLIST.
    //

    InterlockedPushEntrySList(QueueHead->SlistHead,
                              (PSLIST_ENTRY)HeadNode);

    return TRUE;
}
Example #18
0
int TestInterlockedAccess(int argc, char* argv[])
{
	int index;
	LONG* Addend;
	LONG* Target;
	LONG oldValue;
	LONG* Destination;
	LONGLONG oldValue64;
	LONGLONG* Destination64;

	/* InterlockedIncrement */

	Addend = _aligned_malloc(sizeof(LONG), sizeof(LONG));
	if (!Addend)
	{
		printf("Failed to allocate memory\n");
		return -1;
	}

	*Addend = 0;

	for (index = 0; index < 10; index ++)
		InterlockedIncrement(Addend);

	if (*Addend != 10)
	{
		printf("InterlockedIncrement failure: Actual: %"PRId32", Expected: 10\n", *Addend);
		return -1;
	}

	/* InterlockedDecrement */

	for (index = 0; index < 10; index ++)
		InterlockedDecrement(Addend);

	if (*Addend != 0)
	{
		printf("InterlockedDecrement failure: Actual: %"PRId32", Expected: 0\n", *Addend);
		return -1;
	}

	/* InterlockedExchange */

	Target = _aligned_malloc(sizeof(LONG), sizeof(LONG));

	if (!Target)
	{
		printf("Failed to allocate memory\n");
		return -1;
	}

	*Target = 0xAA;

	oldValue = InterlockedExchange(Target, 0xFF);

	if (oldValue != 0xAA)
	{
		printf("InterlockedExchange failure: Actual: 0x%08"PRIX32", Expected: 0xAA\n", oldValue);
		return -1;
	}

	if (*Target != 0xFF)
	{
		printf("InterlockedExchange failure: Actual: 0x%08"PRIX32", Expected: 0xFF\n", *Target);
		return -1;
	}

	/* InterlockedExchangeAdd */

	*Addend = 25;

	oldValue = InterlockedExchangeAdd(Addend, 100);

	if (oldValue != 25)
	{
		printf("InterlockedExchangeAdd failure: Actual: %"PRId32", Expected: 25\n", oldValue);
		return -1;
	}

	if (*Addend != 125)
	{
		printf("InterlockedExchangeAdd failure: Actual: %"PRId32", Expected: 125\n", *Addend);
		return -1;
	}

	/* InterlockedCompareExchange (*Destination == Comparand) */

	Destination = _aligned_malloc(sizeof(LONG), sizeof(LONG));
	if (!Destination)
	{
		printf("Failed to allocate memory\n");
		return -1;
	}

	*Destination = 0xAABBCCDD;

	oldValue = InterlockedCompareExchange(Destination, 0xCCDDEEFF, 0xAABBCCDD);

	if (oldValue != 0xAABBCCDD)
	{
		printf("InterlockedCompareExchange failure: Actual: 0x%08"PRIX32", Expected: 0xAABBCCDD\n", oldValue);
		return -1;
	}

	if (*Destination != 0xCCDDEEFF)
	{
		printf("InterlockedCompareExchange failure: Actual: 0x%08"PRIX32", Expected: 0xCCDDEEFF\n", *Destination);
		return -1;
	}

	/* InterlockedCompareExchange (*Destination != Comparand) */

	*Destination = 0xAABBCCDD;

	oldValue = InterlockedCompareExchange(Destination, 0xCCDDEEFF, 0x66778899);

	if (oldValue != 0xAABBCCDD)
	{
		printf("InterlockedCompareExchange failure: Actual: 0x%08"PRIX32", Expected: 0xAABBCCDD\n", oldValue);
		return -1;
	}

	if (*Destination != 0xAABBCCDD)
	{
		printf("InterlockedCompareExchange failure: Actual: 0x%08"PRIX32", Expected: 0xAABBCCDD\n", *Destination);
		return -1;
	}

	/* InterlockedCompareExchange64 (*Destination == Comparand) */

	Destination64 = _aligned_malloc(sizeof(LONGLONG), sizeof(LONGLONG));
	if (!Destination64)
	{
		printf("Failed to allocate memory\n");
		return -1;
	}

	*Destination64 = 0x66778899AABBCCDD;

	oldValue64 = InterlockedCompareExchange64(Destination64, 0x8899AABBCCDDEEFF, 0x66778899AABBCCDD);

	if (oldValue64 != 0x66778899AABBCCDD)
	{
		printf("InterlockedCompareExchange failure: Actual: 0x%016"PRIX64", Expected: 0x66778899AABBCCDD\n", oldValue64);
		return -1;
	}

	if (*Destination64 != 0x8899AABBCCDDEEFF)
	{
		printf("InterlockedCompareExchange failure: Actual: 0x%016"PRIX64", Expected: 0x8899AABBCCDDEEFF\n", *Destination64);
		return -1;
	}

	/* InterlockedCompareExchange64 (*Destination != Comparand) */

	*Destination64 = 0x66778899AABBCCDD;

	oldValue64 = InterlockedCompareExchange64(Destination64, 0x8899AABBCCDDEEFF, 12345);

	if (oldValue64 != 0x66778899AABBCCDD)
	{
		printf("InterlockedCompareExchange failure: Actual: 0x%016"PRIX64", Expected: 0x66778899AABBCCDD\n", oldValue64);
		return -1;
	}

	if (*Destination64 != 0x66778899AABBCCDD)
	{
		printf("InterlockedCompareExchange failure: Actual: 0x%016"PRIX64", Expected: 0x66778899AABBCCDD\n", *Destination64);
		return -1;
	}

	_aligned_free(Addend);
	_aligned_free(Target);
	_aligned_free(Destination);
	_aligned_free(Destination64);

	return 0;
}
Example #19
0
BOOLEAN
ExInsertTailNBQueue (
    IN PVOID Header,
    IN ULONG64 Value
    )

/*++

Routine Description:

    This function inserts the specific data value at the tail of the
    specified non-blocking queue.

Arguments:

    Header - Supplies an opaque pointer to a non-blocking queue header.

    Value - Supplies a pointer to an opaque data value.

Return Value:

    If the specified opaque data value is successfully inserted at the tail
    of the specified non-blocking queue, then a value of TRUE is returned as
    the function value. Otherwise, a value of FALSE is returned.

    N.B. FALSE is returned if a queue node cannot be allocated from the
         associated SLIST.

--*/

{

    NBQUEUE_POINTER Insert;
    NBQUEUE_POINTER Next;
    PNBQUEUE_NODE NextNode;
    PNBQUEUE_HEADER QueueHead;
    PNBQUEUE_NODE QueueNode;
    NBQUEUE_POINTER Tail;
    PNBQUEUE_NODE TailNode;

    //
    // Attempt to allocate a queue node from the SLIST associated with
    // the specified non-blocking queue. If a node can be allocated, then
    // the node is inserted at the tail of the specified non-blocking
    // queue, and TRUE is returned as the function value. Otherwise, FALSE
    // is returned.
    //

    QueueHead = (PNBQUEUE_HEADER)Header;
    QueueNode = (PNBQUEUE_NODE)InterlockedPopEntrySList(QueueHead->SlistHead);
    if (QueueNode != NULL) {

        //
        //  Initialize the queue node next pointer and value.
        //

        QueueNode->Next.Data = 0;
        QueueNode->Value = Value;

        //
        // The following loop is executed until the specified entry can
        // be safely inserted at the tail of the specified non-blocking
        // queue.
        //

        do {

            //
            // Read the tail queue pointer and the next queue pointer of
            // the tail queue pointer making sure the two pointers are
            // coherent.
            //

            Tail.Data = ReadForWriteAccess((volatile LONG64 *)(&QueueHead->Tail.Data));
            TailNode = UnpackNBQPointer(&Tail);
            Next.Data = *((volatile LONG64 *)(&TailNode->Next.Data));
            QueueNode->Next.Count = Tail.Count + 1;
            if (Tail.Data == *((volatile LONG64 *)(&QueueHead->Tail.Data))) {

                //
                // If the tail is pointing to the last node in the list,
                // then attempt to insert the new node at the end of the
                // list. Otherwise, the tail is not pointing to the last
                // node in the list and an attempt is made to move the
                // tail pointer to the next node.
                //

                NextNode = UnpackNBQPointer(&Next);
                if (NextNode == NULL) {
                    PackNBQPointer(&Insert, QueueNode);
                    Insert.Count = Next.Count + 1;
                    if (InterlockedCompareExchange64(&TailNode->Next.Data,
                                                     Insert.Data,
                                                     Next.Data) == Next.Data) {
                        break;
                    }

                } else {
                    PackNBQPointer(&Insert, NextNode);
                    Insert.Count = Tail.Count + 1;
                    InterlockedCompareExchange64(&QueueHead->Tail.Data,
                                                 Insert.Data,
                                                 Tail.Data);
                }
            }

        } while (TRUE);

        //
        // Attempt to move the tail to the new tail node.
        //

        PackNBQPointer(&Insert, QueueNode);
        Insert.Count = Tail.Count + 1;
        InterlockedCompareExchange64(&QueueHead->Tail.Data,
                                     Insert.Data,
                                     Tail.Data);

        return TRUE;

    } else {
        return FALSE;
    }
}
Example #20
0
bool TRI_CompareIntegerUInt64 (volatile uint64_t* theValue, uint64_t oldValue) {
  return ( (uint64_t)(InterlockedCompareExchange64((volatile LONGLONG*)(theValue), (LONGLONG)(oldValue), (LONGLONG)(oldValue) ) ) == oldValue );
}
Example #21
0
bool TRI_CompareAndSwapIntegerInt64 (volatile int64_t* theValue, int64_t oldValue, int64_t newValue) {
  return ( (int64_t)(InterlockedCompareExchange64((volatile LONGLONG*)(theValue), (LONGLONG)(newValue), (LONGLONG)(oldValue) ) ) == oldValue );
}
Example #22
0
INT64 win_compare_exchange64(INT64 volatile *ptr, INT64 compare, INT64 exchange)
{
	return InterlockedCompareExchange64((LONGLONG*)ptr, (LONGLONG)exchange, (LONGLONG)compare);
}
Example #23
0
intptr_t CompareAndSwap(volatile intptr_t *ptr, intptr_t old_value, intptr_t new_value)
{
	return InterlockedCompareExchange64((LONGLONG *)ptr, new_value, old_value);
}