[-]
[+]
|
Changed |
_service:tar_git:libhybris.changes
|
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris.spec
^
|
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.14.tar.bz2/libhybris/hybris/configure.ac
^
|
@@ -73,6 +73,13 @@
[wayland_serverside_buffers=yes])
AM_CONDITIONAL( [WANT_WL_SERVERSIDE_BUFFERS], [test x"$wayland_serverside_buffers" = x"yes"])
+AC_ARG_ENABLE(property_cache,
+ [ --enable-property-cache Enable runtime android property cache (default=disabled)],
+ [property_cache=$enableval],
+ [property_cache=no])
+AM_CONDITIONAL( [WANT_RUNTIME_PROPERTY_CACHE], [test x"$property_cache" = x"yes"])
+
+
AC_ARG_ENABLE(arch,
[ --enable-arch[=arch] Compile specific CPU target(default=arm)
arm: compile for ARM
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.14.tar.bz2/libhybris/hybris/properties/Makefile.am
^
|
@@ -3,6 +3,12 @@
libandroid_properties_la_SOURCES = properties.c cache.c
libandroid_properties_la_CFLAGS = -I$(top_srcdir)/include $(ANDROID_HEADERS_CFLAGS)
+if WANT_RUNTIME_PROPERTY_CACHE
+libandroid_properties_la_SOURCES += runtime_cache.c
+else
+libandroid_properties_la_CFLAGS += -DNO_RUNTIME_PROPERTY_CACHE
+endif
+
if WANT_DEBUG
libandroid_properties_la_CFLAGS += -ggdb -O0
endif
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.14.tar.bz2/libhybris/hybris/properties/properties.c
^
|
@@ -167,8 +167,23 @@
if ((key) && (strlen(key) >= PROP_NAME_MAX -1)) return -1;
if (value == NULL) return -1;
- if (property_get_socket(key, value, default_value) == 0)
- return strlen(value);
+
+ // Runtime cache will serialize property lookups within the process.
+ // This will increase latency if multiple threads are doing many
+ // parallel lookups to new properties, but the overhead should
+ // be offset with the caching eventually.
+ runtime_cache_lock();
+ if (runtime_cache_get(key, value) == 0) {
+ ret = value;
+ } else if (property_get_socket(key, value, default_value) == 0) {
+ runtime_cache_insert(key, value);
+ ret = value;
+ }
+ runtime_cache_unlock();
+
+ if (ret)
+ return strlen(ret);
+
/* In case the socket is not available, search the property file cache by hand */
ret = hybris_propcache_find(key);
@@ -196,6 +211,10 @@
if (strlen(key) >= PROP_NAME_MAX -1) return -1;
if (strlen(value) >= PROP_VALUE_MAX -1) return -1;
+ runtime_cache_lock();
+ runtime_cache_remove(key);
+ runtime_cache_unlock();
+
memset(&msg, 0, sizeof(msg));
msg.cmd = PROP_MSG_SETPROP;
strncpy(msg.name, key, sizeof(msg.name));
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.14.tar.bz2/libhybris/hybris/properties/properties_p.h
^
|
@@ -23,4 +23,18 @@
void hybris_propcache_list(hybris_propcache_list_cb cb, void *cookie);
char *hybris_propcache_find(const char *key);
+#ifndef NO_RUNTIME_PROPERTY_CACHE
+void runtime_cache_lock();
+void runtime_cache_unlock();
+int runtime_cache_get(const char *key, char *value);
+void runtime_cache_insert(const char *key, char *value);
+void runtime_cache_remove(const char *key);
+#else
+#define runtime_cache_lock()
+#define runtime_cache_unlock()
+#define runtime_cache_get(K,V) (-1)
+#define runtime_cache_insert(K,V)
+#define runtime_cache_remove(K)
+#endif
+
#endif
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.14.tar.bz2/libhybris/hybris/properties/runtime_cache.c
^
|
@@ -0,0 +1,180 @@
+/*
+ * Copyright (c) 2012 Carsten Munk <carsten.munk@gmail.com>
+ * Copyright (c) 2008 The Android Open Source Project
+ * Copyright (c) 2013 Simon Busch <morphis@gravedo.de>
+ * Copyright (c) 2013 Canonical Ltd
+ * Copyright (c) 2013 Jolla Ltd. <robin.burchell@jollamobile.com>
+ * Copyright (c) 2015 Jolla Ltd. <mikko.harju@jollamobile.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <stdlib.h>
+#include <assert.h>
+#include <errno.h>
+#include <string.h>
+#include <time.h>
+#include <pthread.h>
+
+
+#define HYBRIS_PROPERTY_CACHE_DEFAULT_TIMEOUT_SECS 10
+
+/** Maximum allowed time to return stale data from the cache. Override
+ with HYBRIS_PROPERTY_CACHE_TIMEOUT_SECS environment variable.
+*/
+static time_t runtime_cache_timeout_secs = HYBRIS_PROPERTY_CACHE_DEFAULT_TIMEOUT_SECS;
+
+
+/** Key, value pair and the time of previous update (in seconds) */
+struct hybris_prop_value
+{
+ char *key;
+ char *value;
+ time_t last_update;
+};
+
+static struct hybris_prop_value * prop_array = 0;
+static int num_prop = 0;
+static int num_alloc = 0;
+
+/** Protect access to statics */
+static pthread_mutex_t array_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+/* private:
+ * compares two hybris_prop_value by key, so as to maintain a qsorted array of
+ * props, and search the array.
+ */
+static int prop_qcmp(const void *a, const void *b)
+{
+ struct hybris_prop_value *aa = (struct hybris_prop_value *)a;
+ struct hybris_prop_value *bb = (struct hybris_prop_value *)b;
+
+ return strcmp(aa->key, bb->key);
+}
+
+static struct hybris_prop_value *cache_find_internal(const char *key)
+{
+ struct hybris_prop_value prop_key;
+ prop_key.key = (char*)key;
+
+ return bsearch(&prop_key, prop_array, num_prop, sizeof(struct hybris_prop_value), prop_qcmp);
+}
+
+static void runtime_cache_init()
+{
+ num_alloc = 8;
+ prop_array = malloc(num_alloc * sizeof(struct hybris_prop_value));
+
+ const char *timeout_str = getenv("HYBRIS_PROPERTY_CACHE_TIMEOUT_SECS");
+ if (timeout_str) {
+ runtime_cache_timeout_secs = atoi(timeout_str);
+ }
+}
+
+static void runtime_cache_ensure_initialized()
+{
+ if (!prop_array) {
+ runtime_cache_init();
+ }
+}
+
+/** Invalidate an entry in the cache
+ *
+ * Cache will never shrink. Instead, assume that the same key
+ * will be queried soon after invalidation and reuse the entry.
+ */
+static void runtime_cache_invalidate_entry(struct hybris_prop_value *entry)
+{
+ free(entry->value);
+ entry->value = NULL;
+}
+
+static int runtime_cache_get_impl(const char *key, char *value)
+{
+ int ret = -ENOENT;
+
+ struct hybris_prop_value *entry = cache_find_internal(key);
+ if (entry != NULL && entry->value != NULL) {
+ struct timespec now;
+ clock_gettime(CLOCK_MONOTONIC_COARSE, &now);
+ time_t delta_secs = now.tv_sec - entry->last_update;
+ if (delta_secs > runtime_cache_timeout_secs) {
+ // assume the data in cache is stale, and force refresh
+ runtime_cache_invalidate_entry(entry);
+ } else {
+ // success, return value from cache
+ strcpy(value, entry->value);
+ ret = 0;
+ }
+ }
+
+ return ret;
+}
+
+static void runtime_cache_insert_impl(const char *key, char *value)
+{
+ struct timespec now;
+ clock_gettime(CLOCK_MONOTONIC_COARSE, &now);
+
+ struct hybris_prop_value *entry = cache_find_internal(key);
+ if (entry) {
+ assert(entry->value == NULL);
+ // key,value pair was invalidated earlier,
+ // reuse entry in the property array
+ entry->value = strdup(value);
+ entry->last_update = now.tv_sec;
+ } else {
+ if (num_alloc == num_prop) {
+ num_alloc = 3 * num_alloc / 2;
+ prop_array = realloc(prop_array, num_alloc * sizeof(struct hybris_prop_value));
+ }
+
+ struct hybris_prop_value new_entry = { strdup(key), strdup(value), now.tv_sec };
+ prop_array[num_prop++] = new_entry;
+
+ qsort(prop_array, num_prop, sizeof(struct hybris_prop_value), prop_qcmp);
+ }
+}
+
+
+void runtime_cache_lock()
+{
+ pthread_mutex_lock(&array_mutex);
+}
+
+void runtime_cache_unlock()
+{
+ pthread_mutex_unlock(&array_mutex);
+}
+
+void runtime_cache_remove(const char *key)
+{
+ runtime_cache_ensure_initialized();
+ struct hybris_prop_value *entry = cache_find_internal(key);
+ if (entry) {
+ runtime_cache_invalidate_entry(entry);
+ }
+}
+
+int runtime_cache_get(const char *key, char *value)
+{
+ runtime_cache_ensure_initialized();
+ return runtime_cache_get_impl(key, value);
+}
+
+void runtime_cache_insert(const char *key, char *value)
+{
+ runtime_cache_ensure_initialized();
+ runtime_cache_insert_impl(key, value);
+}
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.14.tar.bz2/upstream/hybris/configure.ac
^
|
@@ -73,6 +73,13 @@
[wayland_serverside_buffers=yes])
AM_CONDITIONAL( [WANT_WL_SERVERSIDE_BUFFERS], [test x"$wayland_serverside_buffers" = x"yes"])
+AC_ARG_ENABLE(property_cache,
+ [ --enable-property-cache Enable runtime android property cache (default=disabled)],
+ [property_cache=$enableval],
+ [property_cache=no])
+AM_CONDITIONAL( [WANT_RUNTIME_PROPERTY_CACHE], [test x"$property_cache" = x"yes"])
+
+
AC_ARG_ENABLE(arch,
[ --enable-arch[=arch] Compile specific CPU target(default=arm)
arm: compile for ARM
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.14.tar.bz2/upstream/hybris/properties/Makefile.am
^
|
@@ -3,6 +3,12 @@
libandroid_properties_la_SOURCES = properties.c cache.c
libandroid_properties_la_CFLAGS = -I$(top_srcdir)/include $(ANDROID_HEADERS_CFLAGS)
+if WANT_RUNTIME_PROPERTY_CACHE
+libandroid_properties_la_SOURCES += runtime_cache.c
+else
+libandroid_properties_la_CFLAGS += -DNO_RUNTIME_PROPERTY_CACHE
+endif
+
if WANT_DEBUG
libandroid_properties_la_CFLAGS += -ggdb -O0
endif
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.14.tar.bz2/upstream/hybris/properties/properties.c
^
|
@@ -167,8 +167,23 @@
if ((key) && (strlen(key) >= PROP_NAME_MAX -1)) return -1;
if (value == NULL) return -1;
- if (property_get_socket(key, value, default_value) == 0)
- return strlen(value);
+
+ // Runtime cache will serialize property lookups within the process.
+ // This will increase latency if multiple threads are doing many
+ // parallel lookups to new properties, but the overhead should
+ // be offset with the caching eventually.
+ runtime_cache_lock();
+ if (runtime_cache_get(key, value) == 0) {
+ ret = value;
+ } else if (property_get_socket(key, value, default_value) == 0) {
+ runtime_cache_insert(key, value);
+ ret = value;
+ }
+ runtime_cache_unlock();
+
+ if (ret)
+ return strlen(ret);
+
/* In case the socket is not available, search the property file cache by hand */
ret = hybris_propcache_find(key);
@@ -196,6 +211,10 @@
if (strlen(key) >= PROP_NAME_MAX -1) return -1;
if (strlen(value) >= PROP_VALUE_MAX -1) return -1;
+ runtime_cache_lock();
+ runtime_cache_remove(key);
+ runtime_cache_unlock();
+
memset(&msg, 0, sizeof(msg));
msg.cmd = PROP_MSG_SETPROP;
strncpy(msg.name, key, sizeof(msg.name));
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.14.tar.bz2/upstream/hybris/properties/properties_p.h
^
|
@@ -23,4 +23,18 @@
void hybris_propcache_list(hybris_propcache_list_cb cb, void *cookie);
char *hybris_propcache_find(const char *key);
+#ifndef NO_RUNTIME_PROPERTY_CACHE
+void runtime_cache_lock();
+void runtime_cache_unlock();
+int runtime_cache_get(const char *key, char *value);
+void runtime_cache_insert(const char *key, char *value);
+void runtime_cache_remove(const char *key);
+#else
+#define runtime_cache_lock()
+#define runtime_cache_unlock()
+#define runtime_cache_get(K,V) (-1)
+#define runtime_cache_insert(K,V)
+#define runtime_cache_remove(K)
+#endif
+
#endif
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.14.tar.bz2/upstream/hybris/properties/runtime_cache.c
^
|
@@ -0,0 +1,180 @@
+/*
+ * Copyright (c) 2012 Carsten Munk <carsten.munk@gmail.com>
+ * Copyright (c) 2008 The Android Open Source Project
+ * Copyright (c) 2013 Simon Busch <morphis@gravedo.de>
+ * Copyright (c) 2013 Canonical Ltd
+ * Copyright (c) 2013 Jolla Ltd. <robin.burchell@jollamobile.com>
+ * Copyright (c) 2015 Jolla Ltd. <mikko.harju@jollamobile.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <stdlib.h>
+#include <assert.h>
+#include <errno.h>
+#include <string.h>
+#include <time.h>
+#include <pthread.h>
+
+
+#define HYBRIS_PROPERTY_CACHE_DEFAULT_TIMEOUT_SECS 10
+
+/** Maximum allowed time to return stale data from the cache. Override
+ with HYBRIS_PROPERTY_CACHE_TIMEOUT_SECS environment variable.
+*/
+static time_t runtime_cache_timeout_secs = HYBRIS_PROPERTY_CACHE_DEFAULT_TIMEOUT_SECS;
+
+
+/** Key, value pair and the time of previous update (in seconds) */
+struct hybris_prop_value
+{
+ char *key;
+ char *value;
+ time_t last_update;
+};
+
+static struct hybris_prop_value * prop_array = 0;
+static int num_prop = 0;
+static int num_alloc = 0;
+
+/** Protect access to statics */
+static pthread_mutex_t array_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+/* private:
+ * compares two hybris_prop_value by key, so as to maintain a qsorted array of
+ * props, and search the array.
+ */
+static int prop_qcmp(const void *a, const void *b)
+{
+ struct hybris_prop_value *aa = (struct hybris_prop_value *)a;
+ struct hybris_prop_value *bb = (struct hybris_prop_value *)b;
+
+ return strcmp(aa->key, bb->key);
+}
+
+static struct hybris_prop_value *cache_find_internal(const char *key)
+{
+ struct hybris_prop_value prop_key;
+ prop_key.key = (char*)key;
+
+ return bsearch(&prop_key, prop_array, num_prop, sizeof(struct hybris_prop_value), prop_qcmp);
+}
+
+static void runtime_cache_init()
+{
+ num_alloc = 8;
+ prop_array = malloc(num_alloc * sizeof(struct hybris_prop_value));
+
+ const char *timeout_str = getenv("HYBRIS_PROPERTY_CACHE_TIMEOUT_SECS");
+ if (timeout_str) {
+ runtime_cache_timeout_secs = atoi(timeout_str);
+ }
+}
+
+static void runtime_cache_ensure_initialized()
+{
+ if (!prop_array) {
+ runtime_cache_init();
+ }
+}
+
+/** Invalidate an entry in the cache
+ *
+ * Cache will never shrink. Instead, assume that the same key
+ * will be queried soon after invalidation and reuse the entry.
+ */
+static void runtime_cache_invalidate_entry(struct hybris_prop_value *entry)
+{
+ free(entry->value);
+ entry->value = NULL;
+}
+
+static int runtime_cache_get_impl(const char *key, char *value)
+{
+ int ret = -ENOENT;
+
+ struct hybris_prop_value *entry = cache_find_internal(key);
+ if (entry != NULL && entry->value != NULL) {
+ struct timespec now;
+ clock_gettime(CLOCK_MONOTONIC_COARSE, &now);
+ time_t delta_secs = now.tv_sec - entry->last_update;
+ if (delta_secs > runtime_cache_timeout_secs) {
+ // assume the data in cache is stale, and force refresh
+ runtime_cache_invalidate_entry(entry);
+ } else {
+ // success, return value from cache
+ strcpy(value, entry->value);
+ ret = 0;
+ }
+ }
+
+ return ret;
+}
+
+static void runtime_cache_insert_impl(const char *key, char *value)
+{
+ struct timespec now;
+ clock_gettime(CLOCK_MONOTONIC_COARSE, &now);
+
+ struct hybris_prop_value *entry = cache_find_internal(key);
+ if (entry) {
+ assert(entry->value == NULL);
+ // key,value pair was invalidated earlier,
+ // reuse entry in the property array
+ entry->value = strdup(value);
+ entry->last_update = now.tv_sec;
+ } else {
+ if (num_alloc == num_prop) {
+ num_alloc = 3 * num_alloc / 2;
+ prop_array = realloc(prop_array, num_alloc * sizeof(struct hybris_prop_value));
+ }
+
+ struct hybris_prop_value new_entry = { strdup(key), strdup(value), now.tv_sec };
+ prop_array[num_prop++] = new_entry;
+
+ qsort(prop_array, num_prop, sizeof(struct hybris_prop_value), prop_qcmp);
+ }
+}
+
+
+void runtime_cache_lock()
+{
+ pthread_mutex_lock(&array_mutex);
+}
+
+void runtime_cache_unlock()
+{
+ pthread_mutex_unlock(&array_mutex);
+}
+
+void runtime_cache_remove(const char *key)
+{
+ runtime_cache_ensure_initialized();
+ struct hybris_prop_value *entry = cache_find_internal(key);
+ if (entry) {
+ runtime_cache_invalidate_entry(entry);
+ }
+}
+
+int runtime_cache_get(const char *key, char *value)
+{
+ runtime_cache_ensure_initialized();
+ return runtime_cache_get_impl(key, value);
+}
+
+void runtime_cache_insert(const char *key, char *value)
+{
+ runtime_cache_ensure_initialized();
+ runtime_cache_insert_impl(key, value);
+}
|