1 /** 2 * \file 3 * Linearizable property bag. 4 * 5 * Authors: 6 * Rodrigo Kumpera (kumpera@gmail.com) 7 * 8 * Licensed under the MIT license. See LICENSE file in the project root for full license information. 9 */ 10 #include <mono/metadata/property-bag.h> 11 #include <mono/utils/atomic.h> 12 #include <mono/utils/mono-membar.h> 13 14 /* 15 * mono_property_bag_get: 16 * 17 * Return the value of the property with TAG or NULL. 18 * This doesn't take any locks. 19 */ 20 void* mono_property_bag_get(MonoPropertyBag * bag,int tag)21mono_property_bag_get (MonoPropertyBag *bag, int tag) 22 { 23 MonoPropertyBagItem *item; 24 25 for (item = bag->head; item && item->tag <= tag; item = item->next) { 26 if (item->tag == tag) 27 return item; 28 } 29 return NULL; 30 } 31 32 /* 33 * mono_property_bag_add: 34 * 35 * Store VALUE in the property bag. Return the previous value 36 * with the same tag, or NULL. VALUE should point to a structure 37 * extending the MonoPropertyBagItem structure with the 'tag' 38 * field set. 39 * This doesn't take any locks. 40 */ 41 void* mono_property_bag_add(MonoPropertyBag * bag,void * value)42mono_property_bag_add (MonoPropertyBag *bag, void *value) 43 { 44 MonoPropertyBagItem *cur, **prev, *item = value; 45 int tag = item->tag; 46 mono_memory_barrier (); //publish the values in value 47 48 retry: 49 prev = &bag->head; 50 while (1) { 51 cur = *prev; 52 if (!cur || cur->tag > tag) { 53 item->next = cur; 54 if (mono_atomic_cas_ptr ((void*)prev, item, cur) == cur) 55 return item; 56 goto retry; 57 } else if (cur->tag == tag) { 58 return cur; 59 } else { 60 prev = &cur->next; 61 } 62 } 63 return value; 64 } 65