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