1*b97e9666SJens Wiklander /* 2*b97e9666SJens Wiklander * Copyright (c) 2017, Linaro Limited 3*b97e9666SJens Wiklander * 4*b97e9666SJens Wiklander * SPDX-License-Identifier: BSD-2-Clause 5*b97e9666SJens Wiklander */ 6*b97e9666SJens Wiklander 7*b97e9666SJens Wiklander #include <assert.h> 8*b97e9666SJens Wiklander #include <atomic.h> 9*b97e9666SJens Wiklander #include <kernel/refcount.h> 10*b97e9666SJens Wiklander 11*b97e9666SJens Wiklander bool refcount_inc(struct refcount *r) 12*b97e9666SJens Wiklander { 13*b97e9666SJens Wiklander unsigned int nval; 14*b97e9666SJens Wiklander unsigned int oval = atomic_load_uint(&r->val); 15*b97e9666SJens Wiklander 16*b97e9666SJens Wiklander while (true) { 17*b97e9666SJens Wiklander nval = oval + 1; 18*b97e9666SJens Wiklander 19*b97e9666SJens Wiklander /* r->val is 0, we can't do anything more. */ 20*b97e9666SJens Wiklander if (!oval) 21*b97e9666SJens Wiklander return false; 22*b97e9666SJens Wiklander 23*b97e9666SJens Wiklander if (atomic_cas_uint(&r->val, &oval, nval)) 24*b97e9666SJens Wiklander return true; 25*b97e9666SJens Wiklander /* 26*b97e9666SJens Wiklander * At this point atomic_cas_uint() has updated oval to the 27*b97e9666SJens Wiklander * current r->val. 28*b97e9666SJens Wiklander */ 29*b97e9666SJens Wiklander } 30*b97e9666SJens Wiklander } 31*b97e9666SJens Wiklander 32*b97e9666SJens Wiklander bool refcount_dec(struct refcount *r) 33*b97e9666SJens Wiklander { 34*b97e9666SJens Wiklander unsigned int nval; 35*b97e9666SJens Wiklander unsigned int oval = atomic_load_uint(&r->val); 36*b97e9666SJens Wiklander 37*b97e9666SJens Wiklander while (true) { 38*b97e9666SJens Wiklander assert(oval); 39*b97e9666SJens Wiklander nval = oval - 1; 40*b97e9666SJens Wiklander 41*b97e9666SJens Wiklander if (atomic_cas_uint(&r->val, &oval, nval)) { 42*b97e9666SJens Wiklander /* 43*b97e9666SJens Wiklander * Value has been updated, if value was set to 0 44*b97e9666SJens Wiklander * return true to indicate that. 45*b97e9666SJens Wiklander */ 46*b97e9666SJens Wiklander return !nval; 47*b97e9666SJens Wiklander } 48*b97e9666SJens Wiklander /* 49*b97e9666SJens Wiklander * At this point atomic_cas_uint() has updated oval to the 50*b97e9666SJens Wiklander * current r->val. 51*b97e9666SJens Wiklander */ 52*b97e9666SJens Wiklander } 53*b97e9666SJens Wiklander } 54