aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2014-05-14 02:47:07 -0700
committerChris Robinson <[email protected]>2014-05-14 02:47:07 -0700
commit1d2504d12e996a4c1e8fe9785901db9a9e3b4d7c (patch)
tree51895ba97192cee1fccab44a838e4fa43d81a984
parent4454ae25c753388c529b937ae2ce0f47f06d16c4 (diff)
Make RefCount a non-integer type
It should only be accessed through the appropriate functions to ensure proper atomicity.
-rw-r--r--Alc/ALc.c16
-rw-r--r--Alc/backends/winmm.c8
-rw-r--r--OpenAL32/Include/alMain.h6
-rw-r--r--OpenAL32/Include/alMidi.h6
-rw-r--r--OpenAL32/alAuxEffectSlot.c4
-rw-r--r--OpenAL32/alBuffer.c6
-rw-r--r--OpenAL32/alFontsound.c12
-rw-r--r--OpenAL32/alPreset.c10
-rw-r--r--OpenAL32/alSoundfont.c14
-rw-r--r--OpenAL32/alSource.c6
-rw-r--r--common/atomic.c6
-rw-r--r--common/rwlock.c4
-rw-r--r--include/atomic.h54
-rw-r--r--include/rwlock.h6
14 files changed, 88 insertions, 70 deletions
diff --git a/Alc/ALc.c b/Alc/ALc.c
index 5114942c..974ba6fa 100644
--- a/Alc/ALc.c
+++ b/Alc/ALc.c
@@ -2024,14 +2024,14 @@ static ALCvoid FreeDevice(ALCdevice *device)
void ALCdevice_IncRef(ALCdevice *device)
{
- RefCount ref;
+ uint ref;
ref = IncrementRef(&device->ref);
TRACEREF("%p increasing refcount to %u\n", device, ref);
}
void ALCdevice_DecRef(ALCdevice *device)
{
- RefCount ref;
+ uint ref;
ref = DecrementRef(&device->ref);
TRACEREF("%p decreasing refcount to %u\n", device, ref);
if(ref == 0) FreeDevice(device);
@@ -2189,14 +2189,14 @@ static void ReleaseContext(ALCcontext *context, ALCdevice *device)
void ALCcontext_IncRef(ALCcontext *context)
{
- RefCount ref;
+ uint ref;
ref = IncrementRef(&context->ref);
TRACEREF("%p increasing refcount to %u\n", context, ref);
}
void ALCcontext_DecRef(ALCcontext *context)
{
- RefCount ref;
+ uint ref;
ref = DecrementRef(&context->ref);
TRACEREF("%p decreasing refcount to %u\n", context, ref);
if(ref == 0) FreeContext(context);
@@ -2855,7 +2855,7 @@ ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCin
ALContext = calloc(1, sizeof(ALCcontext)+sizeof(ALlistener));
if(ALContext)
{
- ALContext->ref = 1;
+ InitRef(&ALContext->ref, 1);
ALContext->Listener = (ALlistener*)ALContext->_listener_mem;
VECTOR_INIT(ALContext->ActiveAuxSlots);
@@ -3052,7 +3052,7 @@ ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName)
}
//Validate device
- device->ref = 1;
+ InitRef(&device->ref, 1);
device->Connected = ALC_TRUE;
device->Type = Playback;
device->LastError = ALC_NO_ERROR;
@@ -3352,7 +3352,7 @@ ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *deviceName,
}
//Validate device
- device->ref = 1;
+ InitRef(&device->ref, 1);
device->Connected = ALC_TRUE;
device->Type = Capture;
@@ -3518,7 +3518,7 @@ ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceN
}
//Validate device
- device->ref = 1;
+ InitRef(&device->ref, 1);
device->Connected = ALC_TRUE;
device->Type = Loopback;
device->LastError = ALC_NO_ERROR;
diff --git a/Alc/backends/winmm.c b/Alc/backends/winmm.c
index 2f01ffdf..624af37a 100644
--- a/Alc/backends/winmm.c
+++ b/Alc/backends/winmm.c
@@ -41,7 +41,7 @@ typedef struct {
volatile ALboolean killNow;
althrd_t thread;
- volatile RefCount WaveBuffersCommitted;
+ RefCount WaveBuffersCommitted;
WAVEHDR WaveBuffer[4];
union {
@@ -194,7 +194,7 @@ FORCE_ALIGN static int PlaybackThreadProc(void *arg)
if(data->killNow)
{
- if(data->WaveBuffersCommitted == 0)
+ if(ReadRef(&data->WaveBuffersCommitted) == 0)
break;
continue;
}
@@ -412,7 +412,7 @@ static ALCboolean WinMMStartPlayback(ALCdevice *device)
if(althrd_create(&data->thread, PlaybackThreadProc, device) != althrd_success)
return ALC_FALSE;
- data->WaveBuffersCommitted = 0;
+ InitRef(&data->WaveBuffersCommitted, 0);
// Create 4 Buffers
BufferSize = device->UpdateSize*device->NumUpdates / 4;
@@ -549,7 +549,7 @@ static ALCenum WinMMOpenCapture(ALCdevice *Device, const ALCchar *deviceName)
if(!data->Ring)
goto failure;
- data->WaveBuffersCommitted = 0;
+ InitRef(&data->WaveBuffersCommitted, 0);
// Create 4 Buffers of 50ms each
BufferSize = data->Format.nAvgBytesPerSec / 20;
diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h
index a95abd44..2f1eb850 100644
--- a/OpenAL32/Include/alMain.h
+++ b/OpenAL32/Include/alMain.h
@@ -610,7 +610,7 @@ enum DeviceType {
struct ALCdevice_struct
{
- volatile RefCount ref;
+ RefCount ref;
ALCboolean Connected;
enum DeviceType Type;
@@ -689,7 +689,7 @@ struct ALCdevice_struct
* the end, so the bottom bit indicates if the device is currently mixing
* and the upper bits indicates how many mixes have been done.
*/
- volatile RefCount MixCount;
+ RefCount MixCount;
/* Default effect slot */
struct ALeffectslot *DefaultSlot;
@@ -744,7 +744,7 @@ DECL_VECTOR(ALeffectslotPtr)
struct ALCcontext_struct
{
- volatile RefCount ref;
+ RefCount ref;
struct ALlistener *Listener;
diff --git a/OpenAL32/Include/alMidi.h b/OpenAL32/Include/alMidi.h
index 24e6675f..d18c165e 100644
--- a/OpenAL32/Include/alMidi.h
+++ b/OpenAL32/Include/alMidi.h
@@ -32,7 +32,7 @@ typedef struct ALenvelope {
typedef struct ALfontsound {
- volatile RefCount ref;
+ RefCount ref;
ALint MinKey, MaxKey;
ALint MinVelocity, MaxVelocity;
@@ -110,7 +110,7 @@ void ReleaseALFontsounds(ALCdevice *device);
typedef struct ALsfpreset {
- volatile RefCount ref;
+ RefCount ref;
ALint Preset; /* a.k.a. MIDI program number */
ALint Bank; /* MIDI bank 0...127, or percussion (bank 128) */
@@ -133,7 +133,7 @@ void ReleaseALPresets(ALCdevice *device);
typedef struct ALsoundfont {
- volatile RefCount ref;
+ RefCount ref;
ALsfpreset **Presets;
ALsizei NumPresets;
diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c
index d4dabe0e..9f554cb0 100644
--- a/OpenAL32/alAuxEffectSlot.c
+++ b/OpenAL32/alAuxEffectSlot.c
@@ -122,7 +122,7 @@ AL_API ALvoid AL_APIENTRY alDeleteAuxiliaryEffectSlots(ALsizei n, const ALuint *
{
if((slot=LookupEffectSlot(context, effectslots[i])) == NULL)
SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
- if(slot->ref != 0)
+ if(ReadRef(&slot->ref) != 0)
SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done);
}
@@ -533,7 +533,7 @@ ALenum InitEffectSlot(ALeffectslot *slot)
for(i = 0;i < BUFFERSIZE;i++)
slot->WetBuffer[c][i] = 0.0f;
}
- slot->ref = 0;
+ InitRef(&slot->ref, 0);
return AL_NO_ERROR;
}
diff --git a/OpenAL32/alBuffer.c b/OpenAL32/alBuffer.c
index 2d368987..12d57d61 100644
--- a/OpenAL32/alBuffer.c
+++ b/OpenAL32/alBuffer.c
@@ -115,7 +115,7 @@ AL_API ALvoid AL_APIENTRY alDeleteBuffers(ALsizei n, const ALuint *buffers)
/* Check for valid Buffer ID */
if((ALBuf=LookupBuffer(device, buffers[i])) == NULL)
SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
- if(ALBuf->ref != 0)
+ if(ReadRef(&ALBuf->ref) != 0)
SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done);
}
@@ -695,7 +695,7 @@ AL_API void AL_APIENTRY alBufferiv(ALuint buffer, ALenum param, const ALint *val
{
case AL_LOOP_POINTS_SOFT:
WriteLock(&albuf->lock);
- if(albuf->ref != 0)
+ if(ReadRef(&albuf->ref) != 0)
{
WriteUnlock(&albuf->lock);
SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done);
@@ -980,7 +980,7 @@ static ALenum LoadData(ALbuffer *ALBuf, ALuint freq, ALenum NewFormat, ALsizei f
return AL_OUT_OF_MEMORY;
WriteLock(&ALBuf->lock);
- if(ALBuf->ref != 0)
+ if(ReadRef(&ALBuf->ref) != 0)
{
WriteUnlock(&ALBuf->lock);
return AL_INVALID_OPERATION;
diff --git a/OpenAL32/alFontsound.c b/OpenAL32/alFontsound.c
index 94cf3064..c4d49e92 100644
--- a/OpenAL32/alFontsound.c
+++ b/OpenAL32/alFontsound.c
@@ -69,7 +69,7 @@ AL_API ALvoid AL_APIENTRY alDeleteFontsoundsSOFT(ALsizei n, const ALuint *ids)
/* Check for valid ID */
if((inst=LookupFontsound(device, ids[i])) == NULL)
SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
- if(inst->ref != 0)
+ if(ReadRef(&inst->ref) != 0)
SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done);
}
@@ -115,7 +115,7 @@ AL_API void AL_APIENTRY alFontsoundiSOFT(ALuint id, ALenum param, ALint value)
device = context->Device;
if(!(sound=LookupFontsound(device, id)))
SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
- if(sound->ref != 0)
+ if(ReadRef(&sound->ref) != 0)
SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done);
ALfontsound_setPropi(sound, context, param, value);
@@ -136,7 +136,7 @@ AL_API void AL_APIENTRY alFontsound2iSOFT(ALuint id, ALenum param, ALint value1,
device = context->Device;
if(!(sound=LookupFontsound(device, id)))
SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
- if(sound->ref != 0)
+ if(ReadRef(&sound->ref) != 0)
SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done);
switch(param)
{
@@ -231,7 +231,7 @@ AL_API void AL_APIENTRY alFontsoundivSOFT(ALuint id, ALenum param, const ALint *
device = context->Device;
if(!(sound=LookupFontsound(device, id)))
SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
- if(sound->ref != 0)
+ if(ReadRef(&sound->ref) != 0)
SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done);
switch(param)
{
@@ -508,7 +508,7 @@ ALfontsound *NewFontsound(ALCcontext *context)
static void ALfontsound_Construct(ALfontsound *self)
{
- self->ref = 0;
+ InitRef(&self->ref, 0);
self->MinKey = 0;
self->MaxKey = 127;
@@ -829,7 +829,7 @@ void ALfontsound_setModStagei(ALfontsound *self, ALCcontext *context, ALsizei st
{
ALint srcidx = 0;
- if(self->ref != 0)
+ if(ReadRef(&self->ref) != 0)
SET_ERROR_AND_RETURN(context, AL_INVALID_OPERATION);
switch(param)
{
diff --git a/OpenAL32/alPreset.c b/OpenAL32/alPreset.c
index d34772a4..c7167d6b 100644
--- a/OpenAL32/alPreset.c
+++ b/OpenAL32/alPreset.c
@@ -65,7 +65,7 @@ AL_API ALvoid AL_APIENTRY alDeletePresetsSOFT(ALsizei n, const ALuint *ids)
/* Check for valid ID */
if((preset=LookupPreset(device, ids[i])) == NULL)
SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
- if(preset->ref != 0)
+ if(ReadRef(&preset->ref) != 0)
SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done);
}
@@ -107,7 +107,7 @@ AL_API void AL_APIENTRY alPresetiSOFT(ALuint id, ALenum param, ALint value)
device = context->Device;
if((preset=LookupPreset(device, id)) == NULL)
SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
- if(preset->ref != 0)
+ if(ReadRef(&preset->ref) != 0)
SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done);
switch(param)
{
@@ -151,7 +151,7 @@ AL_API void AL_APIENTRY alPresetivSOFT(ALuint id, ALenum param, const ALint *val
device = context->Device;
if((preset=LookupPreset(device, id)) == NULL)
SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
- if(preset->ref != 0)
+ if(ReadRef(&preset->ref) != 0)
SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done);
switch(param)
{
@@ -220,7 +220,7 @@ AL_API void AL_APIENTRY alPresetFontsoundsSOFT(ALuint id, ALsizei count, const A
if(count < 0)
SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
- if(preset->ref != 0)
+ if(ReadRef(&preset->ref) != 0)
SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done);
if(count == 0)
@@ -294,7 +294,7 @@ void DeletePreset(ALsfpreset *preset, ALCdevice *device)
static void ALsfpreset_Construct(ALsfpreset *self)
{
- self->ref = 0;
+ InitRef(&self->ref, 0);
self->Preset = 0;
self->Bank = 0;
diff --git a/OpenAL32/alSoundfont.c b/OpenAL32/alSoundfont.c
index 0952c412..357e13e7 100644
--- a/OpenAL32/alSoundfont.c
+++ b/OpenAL32/alSoundfont.c
@@ -91,7 +91,7 @@ AL_API ALvoid AL_APIENTRY alDeleteSoundfontsSOFT(ALsizei n, const ALuint *ids)
}
else if((sfont=LookupSfont(device, ids[i])) == NULL)
SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
- if(sfont->Mapped != AL_FALSE || sfont->ref != 0)
+ if(sfont->Mapped != AL_FALSE || ReadRef(&sfont->ref) != 0)
SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done);
}
@@ -157,7 +157,7 @@ AL_API ALvoid AL_APIENTRY alSoundfontSamplesSOFT(ALuint id, ALenum type, ALsizei
SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
WriteLock(&sfont->Lock);
- if(sfont->ref != 0)
+ if(ReadRef(&sfont->ref) != 0)
alSetError(context, AL_INVALID_OPERATION);
else if(sfont->Mapped)
alSetError(context, AL_INVALID_OPERATION);
@@ -232,7 +232,7 @@ AL_API ALvoid* AL_APIENTRY alSoundfontMapSamplesSOFT(ALuint id, ALsizei offset,
SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
ReadLock(&sfont->Lock);
- if(sfont->ref != 0)
+ if(ReadRef(&sfont->ref) != 0)
alSetError(context, AL_INVALID_OPERATION);
else if(ExchangeInt(&sfont->Mapped, AL_TRUE) == AL_TRUE)
alSetError(context, AL_INVALID_OPERATION);
@@ -329,7 +329,7 @@ AL_API void AL_APIENTRY alSoundfontPresetsSOFT(ALuint id, ALsizei count, const A
SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
WriteLock(&sfont->Lock);
- if(sfont->ref != 0)
+ if(ReadRef(&sfont->ref) != 0)
{
WriteUnlock(&sfont->Lock);
SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done);
@@ -390,7 +390,7 @@ AL_API void AL_APIENTRY alLoadSoundfontSOFT(ALuint id, size_t(*cb)(ALvoid*,size_
SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
WriteLock(&sfont->Lock);
- if(sfont->ref != 0)
+ if(ReadRef(&sfont->ref) != 0)
{
WriteUnlock(&sfont->Lock);
SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done);
@@ -419,7 +419,7 @@ done:
void ALsoundfont_Construct(ALsoundfont *self)
{
- self->ref = 0;
+ InitRef(&self->ref, 0);
self->Presets = NULL;
self->NumPresets = 0;
@@ -520,7 +520,7 @@ void ALsoundfont_deleteSoundfont(ALsoundfont *self, ALCdevice *device)
deleting = AL_FALSE;
for(j = 0;j < num_sounds;j++)
{
- if(sounds[j] && sounds[j]->ref == 0)
+ if(sounds[j] && ReadRef(&sounds[j]->ref) == 0)
{
deleting = AL_TRUE;
RemoveFontsound(device, sounds[j]->id);
diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c
index 167208e5..78ccef9a 100644
--- a/OpenAL32/alSource.c
+++ b/OpenAL32/alSource.c
@@ -2230,16 +2230,16 @@ AL_API ALvoid AL_APIENTRY alSourceUnqueueBuffers(ALuint src, ALsizei nb, ALuint
if(BufferList)
{
ALCdevice *device = context->Device;
- RefCount count;
+ uint count;
/* Cut the new head's link back to the old body. The mixer is robust
* enough to handle the link back going away. Once the active mix (if
* any) is complete, it's safe to finish cutting the old tail from the
* new head. */
BufferList = ExchangePtr((XchgPtr*)&BufferList->prev, NULL);
- if(((count=device->MixCount)&1) != 0)
+ if(((count=ReadRef(&device->MixCount))&1) != 0)
{
- while(count == device->MixCount)
+ while(count == ReadRef(&device->MixCount))
althrd_yield();
}
BufferList->next = NULL;
diff --git a/common/atomic.c b/common/atomic.c
index 02bbf066..95b8f835 100644
--- a/common/atomic.c
+++ b/common/atomic.c
@@ -4,8 +4,10 @@
#include "atomic.h"
-extern inline RefCount IncrementRef(volatile RefCount *ptr);
-extern inline RefCount DecrementRef(volatile RefCount *ptr);
+extern inline void InitRef(volatile RefCount *ptr, uint value);
+extern inline uint ReadRef(volatile RefCount *ptr);
+extern inline uint IncrementRef(volatile RefCount *ptr);
+extern inline uint DecrementRef(volatile RefCount *ptr);
extern inline int ExchangeInt(volatile int *ptr, int newval);
extern inline void *ExchangePtr(XchgPtr *ptr, void *newval);
extern inline int CompExchangeInt(volatile int *ptr, int oldval, int newval);
diff --git a/common/rwlock.c b/common/rwlock.c
index b967db0a..ff7aa418 100644
--- a/common/rwlock.c
+++ b/common/rwlock.c
@@ -24,8 +24,8 @@ static void Unlock(volatile int *l)
void RWLockInit(RWLock *lock)
{
- lock->read_count = 0;
- lock->write_count = 0;
+ InitRef(&lock->read_count, 0);
+ InitRef(&lock->write_count, 0);
lock->read_lock = false;
lock->read_entry_lock = false;
lock->write_lock = false;
diff --git a/include/atomic.h b/include/atomic.h
index 2fc6ee18..e8a9d3f4 100644
--- a/include/atomic.h
+++ b/include/atomic.h
@@ -5,14 +5,24 @@
typedef void *volatile XchgPtr;
-typedef unsigned int RefCount;
+
+typedef unsigned int uint;
+typedef union {
+ uint value;
+} RefCount;
+
+#define STATIC_REFCOUNT_INIT(V) {(V)}
#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)) && !defined(__QNXNTO__)
-inline RefCount IncrementRef(volatile RefCount *ptr)
-{ return __sync_add_and_fetch(ptr, 1); }
-inline RefCount DecrementRef(volatile RefCount *ptr)
-{ return __sync_sub_and_fetch(ptr, 1); }
+inline void InitRef(volatile RefCount *ptr, uint value)
+{ ptr->value = value; }
+inline uint ReadRef(volatile RefCount *ptr)
+{ __sync_synchronize(); return ptr->value; }
+inline uint IncrementRef(volatile RefCount *ptr)
+{ return __sync_add_and_fetch(&ptr->value, 1); }
+inline uint DecrementRef(volatile RefCount *ptr)
+{ return __sync_sub_and_fetch(&ptr->value, 1); }
inline int ExchangeInt(volatile int *ptr, int newval)
{ return __sync_lock_test_and_set(ptr, newval); }
@@ -25,7 +35,7 @@ inline void *CompExchangePtr(XchgPtr *ptr, void *oldval, void *newval)
#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
-inline unsigned int xaddl(volatile unsigned int *dest, int incr)
+inline uint xaddl(volatile uint *dest, int incr)
{
unsigned int ret;
__asm__ __volatile__("lock; xaddl %0,(%1)"
@@ -35,10 +45,14 @@ inline unsigned int xaddl(volatile unsigned int *dest, int incr)
return ret;
}
-inline RefCount IncrementRef(volatile RefCount *ptr)
-{ return xaddl(ptr, 1)+1; }
-inline RefCount DecrementRef(volatile RefCount *ptr)
-{ return xaddl(ptr, -1)-1; }
+inline void InitRef(volatile RefCount *ptr, uint value)
+{ ptr->value = value; }
+inline uint ReadRef(volatile RefCount *ptr)
+{ __asm__ __volatile__("" ::: "memory"); return ptr->value; }
+inline uint IncrementRef(volatile RefCount *ptr)
+{ return xaddl(&ptr->value, 1)+1; }
+inline uint DecrementRef(volatile RefCount *ptr)
+{ return xaddl(&ptr->value, -1)-1; }
inline int ExchangeInt(volatile int *dest, int newval)
{
@@ -94,27 +108,29 @@ inline void *CompExchangePtr(XchgPtr *dest, void *oldval, void *newval)
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
-static_assert(sizeof(LONG)==sizeof(RefCount), "sizeof LONG does not match sizeof RefCount");
+static_assert(sizeof(LONG)==sizeof(uint), "sizeof LONG does not match sizeof uint");
-inline RefCount IncrementRef(volatile RefCount *ptr)
+inline void InitRef(volatile RefCount *ptr, uint value)
+{ ptr->value = value; }
+inline uint ReadRef(volatile RefCount *ptr)
+{ _ReadBarrier(); return ptr->value; }
+inline uint IncrementRef(volatile RefCount *ptr)
{
union {
- volatile RefCount *u;
+ volatile uint *u;
volatile LONG *l;
- } u = { ptr };
+ } u = { &ptr->value };
return InterlockedIncrement(u.l);
}
-inline RefCount DecrementRef(volatile RefCount *ptr)
+inline uint DecrementRef(volatile RefCount *ptr)
{
union {
- volatile RefCount *u;
+ volatile uint *u;
volatile LONG *l;
- } u = { ptr };
+ } u = { &ptr->value };
return InterlockedDecrement(u.l);
}
-static_assert(sizeof(LONG)==sizeof(int), "sizeof LONG does not match sizeof int");
-
inline int ExchangeInt(volatile int *ptr, int newval)
{
union {
diff --git a/include/rwlock.h b/include/rwlock.h
index 764940fa..c3a275e6 100644
--- a/include/rwlock.h
+++ b/include/rwlock.h
@@ -5,13 +5,13 @@
#include "atomic.h"
typedef struct {
- volatile RefCount read_count;
- volatile RefCount write_count;
+ RefCount read_count;
+ RefCount write_count;
volatile int read_lock;
volatile int read_entry_lock;
volatile int write_lock;
} RWLock;
-#define RWLOCK_STATIC_INITIALIZE { 0, 0, false, false, false }
+#define RWLOCK_STATIC_INITIALIZE { STATIC_REFCOUNT_INIT(0), STATIC_REFCOUNT_INIT(0), false, false, false }
void RWLockInit(RWLock *lock);
void ReadLock(RWLock *lock);