From 926ebe109424baa407b2cd938ba053b5c0b8ce7c Mon Sep 17 00:00:00 2001 From: Tom Cherry Date: Wed, 23 Sep 2015 15:34:40 -0700 Subject: [PATCH] Refactor prop_area into a class Bug 21852512 Change-Id: I432bf592f1a71a046c32616fc334ad77c220f0ca --- libc/bionic/system_properties.cpp | 163 +++++++++++++++++++++++++------------- 1 file changed, 110 insertions(+), 53 deletions(-) diff --git a/libc/bionic/system_properties.cpp b/libc/bionic/system_properties.cpp index c436a16c6..9fe982a84 100644 --- a/libc/bionic/system_properties.cpp +++ b/libc/bionic/system_properties.cpp @@ -112,23 +112,57 @@ private: DISALLOW_COPY_AND_ASSIGN(prop_bt); }; -struct prop_area { - uint32_t bytes_used; - atomic_uint_least32_t serial; - uint32_t magic; - uint32_t version; - uint32_t reserved[28]; - char data[0]; +class prop_area { +public: prop_area(const uint32_t magic, const uint32_t version) : - magic(magic), version(version) { - atomic_init(&serial, 0); - memset(reserved, 0, sizeof(reserved)); + magic_(magic), version_(version) { + atomic_init(&serial_, 0); + memset(reserved_, 0, sizeof(reserved_)); // Allocate enough space for the root node. - bytes_used = sizeof(prop_bt); + bytes_used_ = sizeof(prop_bt); } + const prop_info *find(const char *name); + bool add(const char *name, unsigned int namelen, + const char *value, unsigned int valuelen); + + bool foreach(void (*propfn)(const prop_info *pi, void *cookie), void *cookie); + + atomic_uint_least32_t *serial() { return &serial_; } + uint32_t magic() const { return magic_; } + uint32_t version() const { return version_; } + private: + void *allocate_obj(const size_t size, uint_least32_t *const off); + prop_bt *new_prop_bt(const char *name, uint8_t namelen, uint_least32_t *const off); + prop_info *new_prop_info(const char *name, uint8_t namelen, + const char *value, uint8_t valuelen, + uint_least32_t *const off); + void *to_prop_obj(uint_least32_t off); + prop_bt *to_prop_bt(atomic_uint_least32_t *off_p); + prop_info *to_prop_info(atomic_uint_least32_t *off_p); + + prop_bt *root_node(); + + prop_bt *find_prop_bt(prop_bt *const bt, const char *name, + uint8_t namelen, bool alloc_if_needed); + + const prop_info *find_property(prop_bt *const trie, const char *name, + uint8_t namelen, const char *value, + uint8_t valuelen, bool alloc_if_needed); + + bool foreach_property(prop_bt *const trie, + void (*propfn)(const prop_info *pi, void *cookie), + void *cookie); + + uint32_t bytes_used_; + atomic_uint_least32_t serial_; + uint32_t magic_; + uint32_t version_; + uint32_t reserved_[28]; + char data_[0]; + DISALLOW_COPY_AND_ASSIGN(prop_area); }; @@ -246,13 +280,14 @@ static int map_fd_ro(const int fd) { } prop_area* pa = reinterpret_cast(map_result); - if ((pa->magic != PROP_AREA_MAGIC) || (pa->version != PROP_AREA_VERSION && - pa->version != PROP_AREA_VERSION_COMPAT)) { + if ((pa->magic() != PROP_AREA_MAGIC) || + (pa->version() != PROP_AREA_VERSION && + pa->version() != PROP_AREA_VERSION_COMPAT)) { munmap(pa, pa_size); return -1; } - if (pa->version == PROP_AREA_VERSION_COMPAT) { + if (pa->version() == PROP_AREA_VERSION_COMPAT) { compat_mode = true; } @@ -290,20 +325,19 @@ static int map_prop_area() return map_result; } -static void *allocate_obj(const size_t size, uint_least32_t *const off) +void *prop_area::allocate_obj(const size_t size, uint_least32_t *const off) { - prop_area *pa = __system_property_area__; const size_t aligned = BIONIC_ALIGN(size, sizeof(uint_least32_t)); - if (pa->bytes_used + aligned > pa_data_size) { + if (bytes_used_ + aligned > pa_data_size) { return NULL; } - *off = pa->bytes_used; - pa->bytes_used += aligned; - return pa->data + *off; + *off = bytes_used_; + bytes_used_ += aligned; + return data_ + *off; } -static prop_bt *new_prop_bt(const char *name, uint8_t namelen, uint_least32_t *const off) +prop_bt *prop_area::new_prop_bt(const char *name, uint8_t namelen, uint_least32_t *const off) { uint_least32_t new_offset; void *const p = allocate_obj(sizeof(prop_bt) + namelen + 1, &new_offset); @@ -316,7 +350,7 @@ static prop_bt *new_prop_bt(const char *name, uint8_t namelen, uint_least32_t *c return NULL; } -static prop_info *new_prop_info(const char *name, uint8_t namelen, +prop_info *prop_area::new_prop_info(const char *name, uint8_t namelen, const char *value, uint8_t valuelen, uint_least32_t *const off) { uint_least32_t new_offset; @@ -330,27 +364,25 @@ static prop_info *new_prop_info(const char *name, uint8_t namelen, return NULL; } -static void *to_prop_obj(uint_least32_t off) +void *prop_area::to_prop_obj(uint_least32_t off) { if (off > pa_data_size) return NULL; - if (!__system_property_area__) - return NULL; - return (__system_property_area__->data + off); + return (data_ + off); } -static inline prop_bt *to_prop_bt(atomic_uint_least32_t* off_p) { +inline prop_bt *prop_area::to_prop_bt(atomic_uint_least32_t* off_p) { uint_least32_t off = atomic_load_explicit(off_p, memory_order_consume); return reinterpret_cast(to_prop_obj(off)); } -static inline prop_info *to_prop_info(atomic_uint_least32_t* off_p) { +inline prop_info *prop_area::to_prop_info(atomic_uint_least32_t* off_p) { uint_least32_t off = atomic_load_explicit(off_p, memory_order_consume); return reinterpret_cast(to_prop_obj(off)); } -static inline prop_bt *root_node() +inline prop_bt *prop_area::root_node() { return reinterpret_cast(to_prop_obj(0)); } @@ -366,8 +398,8 @@ static int cmp_prop_name(const char *one, uint8_t one_len, const char *two, return strncmp(one, two, one_len); } -static prop_bt *find_prop_bt(prop_bt *const bt, const char *name, - uint8_t namelen, bool alloc_if_needed) +prop_bt *prop_area::find_prop_bt(prop_bt *const bt, const char *name, + uint8_t namelen, bool alloc_if_needed) { prop_bt* current = bt; @@ -417,7 +449,7 @@ static prop_bt *find_prop_bt(prop_bt *const bt, const char *name, } } -static const prop_info *find_property(prop_bt *const trie, const char *name, +const prop_info *prop_area::find_property(prop_bt *const trie, const char *name, uint8_t namelen, const char *value, uint8_t valuelen, bool alloc_if_needed) { @@ -543,39 +575,52 @@ static void find_nth_fn(const prop_info *pi, void *ptr) cookie->count++; } -static int foreach_property(prop_bt *const trie, +bool prop_area::foreach_property(prop_bt *const trie, void (*propfn)(const prop_info *pi, void *cookie), void *cookie) { if (!trie) - return -1; + return false; uint_least32_t left_offset = atomic_load_explicit(&trie->left, memory_order_relaxed); if (left_offset != 0) { const int err = foreach_property(to_prop_bt(&trie->left), propfn, cookie); if (err < 0) - return -1; + return false; } uint_least32_t prop_offset = atomic_load_explicit(&trie->prop, memory_order_relaxed); if (prop_offset != 0) { prop_info *info = to_prop_info(&trie->prop); if (!info) - return -1; + return false; propfn(info, cookie); } uint_least32_t children_offset = atomic_load_explicit(&trie->children, memory_order_relaxed); if (children_offset != 0) { const int err = foreach_property(to_prop_bt(&trie->children), propfn, cookie); if (err < 0) - return -1; + return false; } uint_least32_t right_offset = atomic_load_explicit(&trie->right, memory_order_relaxed); if (right_offset != 0) { const int err = foreach_property(to_prop_bt(&trie->right), propfn, cookie); if (err < 0) - return -1; + return false; } - return 0; + return true; +} + +const prop_info *prop_area::find(const char *name) { + return find_property(root_node(), name, strlen(name), nullptr, 0, false); +} + +bool prop_area::add(const char *name, unsigned int namelen, + const char *value, unsigned int valuelen) { + return find_property(root_node(), name, namelen, value, valuelen, true); +} + +bool prop_area::foreach(void (*propfn)(const prop_info* pi, void* cookie), void* cookie) { + return foreach_property(root_node(), propfn, cookie); } int __system_properties_init() @@ -605,7 +650,7 @@ unsigned int __system_property_area_serial() return -1; } // Make sure this read fulfilled before __system_property_serial - return atomic_load_explicit(&(pa->serial), memory_order_acquire); + return atomic_load_explicit(pa->serial(), memory_order_acquire); } const prop_info *__system_property_find(const char *name) @@ -613,7 +658,12 @@ const prop_info *__system_property_find(const char *name) if (__predict_false(compat_mode)) { return __system_property_find_compat(name); } - return find_property(root_node(), name, strlen(name), NULL, 0, false); + + if (!__system_property_area__) { + return nullptr; + } + + return __system_property_area__->find(name); } // The C11 standard doesn't allow atomic loads from const fields, @@ -708,10 +758,10 @@ int __system_property_update(prop_info *pi, const char *value, unsigned int len) __futex_wake(&pi->serial, INT32_MAX); atomic_store_explicit( - &pa->serial, - atomic_load_explicit(&pa->serial, memory_order_relaxed) + 1, + pa->serial(), + atomic_load_explicit(pa->serial(), memory_order_relaxed) + 1, memory_order_release); - __futex_wake(&pa->serial, INT32_MAX); + __futex_wake(pa->serial(), INT32_MAX); return 0; } @@ -720,7 +770,6 @@ int __system_property_add(const char *name, unsigned int namelen, const char *value, unsigned int valuelen) { prop_area *pa = __system_property_area__; - const prop_info *pi; if (namelen >= PROP_NAME_MAX) return -1; @@ -729,17 +778,21 @@ int __system_property_add(const char *name, unsigned int namelen, if (namelen < 1) return -1; - pi = find_property(root_node(), name, namelen, value, valuelen, true); - if (!pi) + if (!__system_property_area__) { + return -1; + } + + bool ret = __system_property_area__->add(name, namelen, value, valuelen); + if (!ret) return -1; // There is only a single mutator, but we want to make sure that // updates are visible to a reader waiting for the update. atomic_store_explicit( - &pa->serial, - atomic_load_explicit(&pa->serial, memory_order_relaxed) + 1, + pa->serial(), + atomic_load_explicit(pa->serial(), memory_order_relaxed) + 1, memory_order_release); - __futex_wake(&pa->serial, INT32_MAX); + __futex_wake(pa->serial(), INT32_MAX); return 0; } @@ -762,8 +815,8 @@ unsigned int __system_property_wait_any(unsigned int serial) uint32_t my_serial; do { - __futex_wait(&pa->serial, serial, NULL); - my_serial = atomic_load_explicit(&pa->serial, memory_order_acquire); + __futex_wait(pa->serial(), serial, NULL); + my_serial = atomic_load_explicit(pa->serial(), memory_order_acquire); } while (my_serial == serial); return my_serial; @@ -788,5 +841,9 @@ int __system_property_foreach(void (*propfn)(const prop_info *pi, void *cookie), return __system_property_foreach_compat(propfn, cookie); } - return foreach_property(root_node(), propfn, cookie); + if (!__system_property_area__) { + return -1; + } + + return __system_property_area__->foreach(propfn, cookie) ? 0 : -1; } -- 2.11.0