Merge "Refactor prop_area into a class"
am: 2a7f1b335d * commit '2a7f1b335dcd08a480c4acc948ba202bae1a0a1f': Refactor prop_area into a class
This commit is contained in:
commit
8e86f33690
@ -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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user