2015-10-25 03:30:15 +00:00
|
|
|
#include "mbed.h"
|
|
|
|
#include "MicroBit.h"
|
|
|
|
|
2015-10-25 15:30:05 +00:00
|
|
|
void RefCounted::init()
|
|
|
|
{
|
|
|
|
// Initialize to one reference (lowest bit set to 1)
|
|
|
|
refCount = 3;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline bool isReadOnlyInline(RefCounted *t)
|
|
|
|
{
|
|
|
|
uint32_t refCount = t->refCount;
|
|
|
|
|
|
|
|
if (refCount == 0xffff)
|
|
|
|
return true; // object in flash
|
|
|
|
|
|
|
|
// Do some sanity checking while we're here
|
|
|
|
if (refCount == 1)
|
2015-10-25 19:59:45 +00:00
|
|
|
uBit.panic(MICROBIT_USE_AFTER_FREE); // object should have been deleted
|
2015-10-25 15:30:05 +00:00
|
|
|
|
|
|
|
if ((refCount & 1) == 0)
|
2015-10-25 19:59:45 +00:00
|
|
|
uBit.panic(MICROBIT_REF_COUNT_CORRUPTION); // refCount doesn't look right
|
2015-10-25 15:30:05 +00:00
|
|
|
|
|
|
|
// Not read only
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool RefCounted::isReadOnly()
|
|
|
|
{
|
|
|
|
return isReadOnlyInline(this);
|
|
|
|
}
|
|
|
|
|
2015-10-25 03:30:15 +00:00
|
|
|
void RefCounted::incr()
|
|
|
|
{
|
2015-10-25 15:30:05 +00:00
|
|
|
if (!isReadOnlyInline(this))
|
|
|
|
refCount += 2;
|
2015-10-25 03:30:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void RefCounted::decr()
|
|
|
|
{
|
2015-10-25 15:30:05 +00:00
|
|
|
if (isReadOnlyInline(this))
|
2015-10-25 03:30:15 +00:00
|
|
|
return;
|
2015-10-25 15:30:05 +00:00
|
|
|
|
|
|
|
refCount -= 2;
|
|
|
|
if (refCount == 2) {
|
|
|
|
free(this);
|
2015-10-25 03:30:15 +00:00
|
|
|
}
|
|
|
|
}
|