Merge "Refactor prop_area into a class"

am: 2a7f1b335d

* commit '2a7f1b335dcd08a480c4acc948ba202bae1a0a1f':
  Refactor prop_area into a class
This commit is contained in:
Tom Cherry 2015-11-10 21:58:23 +00:00 committed by android-build-merger
commit 8e86f33690

View File

@ -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<prop_area*>(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<prop_bt*>(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<prop_info*>(to_prop_obj(off));
}
static inline prop_bt *root_node()
inline prop_bt *prop_area::root_node()
{
return reinterpret_cast<prop_bt*>(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;
}