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