ITAAtomicOpsGCCBuiltinsImpl.cpp 2.95 KB
Newer Older
Fabian Schlieper's avatar
Fabian Schlieper committed
1 2 3 4
#include "ITAAtomicOps.h"

#include <stdint.h>

5 6
typedef union
{
Fabian Schlieper's avatar
Fabian Schlieper committed
7 8 9
	int32_t i32Value;
	float floatValue;
} ConvI32Float;
10 11

int atomic_read_int( volatile const int* src )
Fabian Schlieper's avatar
Fabian Schlieper committed
12 13
{
	/*
14 15 16 17 18
	*  Trick: Realisierung mittels CAS!
	*         Falls der Wert schon 0, dann wird er gegen 0 ausgetauscht...
	*         Also keine Änderung!
	*/
	return __sync_val_compare_and_swap( ( int* ) src, 0, 0 );
Fabian Schlieper's avatar
Fabian Schlieper committed
19 20
}

21 22 23 24 25 26 27 28 29 30 31 32
long atomic_read_long( volatile const long* src )
{
	/*
	*  Trick: Realisierung mittels CAS!
	*         Falls der Wert schon 0, dann wird er gegen 0 ausgetauscht...
	*         Also keine Änderung!
	*/
	return __sync_val_compare_and_swap( ( long* ) src, 0, 0 );
}

float atomic_read_float( volatile const float* src )
{
Fabian Schlieper's avatar
Fabian Schlieper committed
33 34 35 36 37 38 39 40 41 42
	/*
	 *  Trick: Realisierung mittels CAS!
	 *         Falls der Wert schon 0, dann wird er gegen 0 ausgetauscht...
	 *         Also keine �nderung!
	 *
	 *  Info:  Auf manchen Architekturen ist InterlockedAdd(src, 0) schneller.
	 *         Leider steht InterlockedAdd nur auf Itanium-Arch. zur Verf�gung.
	 */

	ConvI32Float c;
43
	c.i32Value = __sync_val_compare_and_swap( ( volatile int32_t* ) src, 0, 0 );
Fabian Schlieper's avatar
Fabian Schlieper committed
44 45 46
	return c.floatValue;
}

47 48
void* atomic_read_ptr( volatile const void** src )
{
Fabian Schlieper's avatar
Fabian Schlieper committed
49 50 51 52 53
	/*
	 *  Trick: Realisierung mittels CAS!
	 *         Falls der Wert schon 0, dann wird er gegen 0 ausgetauscht...
	 *         Also keine Änderung!
	 */
54
	return __sync_val_compare_and_swap( ( void** ) src, 0, 0 );
Fabian Schlieper's avatar
Fabian Schlieper committed
55 56
}

57 58 59
void atomic_write_int( volatile int* dest, int value )
{
	__sync_lock_test_and_set( dest, value );
Fabian Schlieper's avatar
Fabian Schlieper committed
60 61
}

62
void atomic_write_long( volatile long* dest, long value )
63 64 65 66 67 68
{
	__sync_lock_test_and_set( dest, value );
}

void atomic_write_float( volatile float* dest, float value )
{
Fabian Schlieper's avatar
Fabian Schlieper committed
69 70
	ConvI32Float c;
	c.floatValue = value;
71
	__sync_lock_test_and_set( ( volatile int32_t* ) dest, c.i32Value );
Fabian Schlieper's avatar
Fabian Schlieper committed
72 73
}

74 75 76
void atomic_write_ptr( volatile void** dest, void* value )
{
	__sync_lock_test_and_set( dest, value );
Fabian Schlieper's avatar
Fabian Schlieper committed
77 78
}

79 80 81
bool atomic_cas_int( volatile int* dest, int expected_value, int new_value )
{
	return __sync_bool_compare_and_swap( dest, expected_value, new_value );
Fabian Schlieper's avatar
Fabian Schlieper committed
82 83 84 85
}

/*
bool atomic_cas_double(volatile double* dest, double expected_value, double new_value) {
86
return __sync_bool_compare_and_swap(dest, expected_value, new_value);
Fabian Schlieper's avatar
Fabian Schlieper committed
87 88 89
}
*/

90 91 92
bool atomic_cas_ptr( volatile void** dest, void* expected_value, void* new_value )
{
	return __sync_bool_compare_and_swap( dest, expected_value, new_value );
Fabian Schlieper's avatar
Fabian Schlieper committed
93 94
}

95 96 97
void atomic_read32( volatile void* src, void* dest )
{
	*( ( int32_t* ) dest ) = __sync_val_compare_and_swap( ( volatile int32_t* ) src, 0, 0 );
Fabian Schlieper's avatar
Fabian Schlieper committed
98 99
}

100 101 102
bool atomic_cas32( volatile void* dest, void* expected_value, void* new_value )
{
	return __sync_bool_compare_and_swap( ( volatile int32_t* ) dest, *( int32_t* ) expected_value, *( int32_t* ) new_value );
Fabian Schlieper's avatar
Fabian Schlieper committed
103 104
}

105 106 107
int atomic_inc_int( volatile int* dest )
{
	return __sync_fetch_and_add( dest, 1 );
Fabian Schlieper's avatar
Fabian Schlieper committed
108 109
}

110 111 112
int atomic_dec_int( volatile int* dest )
{
	return __sync_fetch_and_sub( dest, 1 );
Fabian Schlieper's avatar
Fabian Schlieper committed
113
}