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