blob: 64b08a64791b7af16eaf05794889083afe1a3bee [file] [log] [blame]
// SPDX-License-Identifier: BSD-2-Clause
/*
* Copyright (c) 2017, Linaro Limited
*/
#include <assert.h>
#include <atomic.h>
#include <kernel/refcount.h>
bool refcount_inc(struct refcount *r)
{
unsigned int nval;
unsigned int oval = atomic_load_uint(&r->val);
while (true) {
nval = oval + 1;
/* r->val is 0, we can't do anything more. */
if (!oval)
return false;
if (atomic_cas_uint(&r->val, &oval, nval))
return true;
/*
* At this point atomic_cas_uint() has updated oval to the
* current r->val.
*/
}
}
bool refcount_dec(struct refcount *r)
{
unsigned int nval;
unsigned int oval = atomic_load_uint(&r->val);
while (true) {
assert(oval);
nval = oval - 1;
if (atomic_cas_uint(&r->val, &oval, nval)) {
/*
* Value has been updated, if value was set to 0
* return true to indicate that.
*/
return !nval;
}
/*
* At this point atomic_cas_uint() has updated oval to the
* current r->val.
*/
}
}