diff options
| author | LuK1337 <priv.luk@gmail.com> | 2017-01-26 00:48:19 +0100 |
|---|---|---|
| committer | TheStrix <parthbhatia@lineageos.org> | 2017-03-21 16:06:20 +0530 |
| commit | 27583097b2da370eac965f7237a769ce496882db (patch) | |
| tree | 353809704bb7ddaa77f6a870264b0df051c1aca1 | |
| parent | d45dff9fd5f9aed588bf87db49ad9b154e443fcd (diff) | |
kenzo: Add libc hax for camera
* See : https://review.lineageos.org/#/c/1170/
Change-Id: I040c3023f81322140d153cb14be9578457777ac2
| -rw-r--r-- | device.mk | 1 | ||||
| -rw-r--r-- | libshims/Android.mk | 15 | ||||
| -rw-r--r-- | libshims/bionic/bionic_time_conversions.cpp | 17 | ||||
| -rw-r--r-- | libshims/bionic/pthread_cond.cpp | 79 | ||||
| -rw-r--r-- | libshims/private/bionic_futex.h | 14 | ||||
| -rw-r--r-- | libshims/private/bionic_time_conversions.h | 3 | ||||
| -rw-r--r-- | rootdir/etc/init.target.rc | 2 |
7 files changed, 130 insertions, 1 deletions
@@ -38,6 +38,7 @@ PRODUCT_COPY_FILES += \ # Libshims PRODUCT_PACKAGES += \ + libshims_camera \ libshims_ims # Ramdisk diff --git a/libshims/Android.mk b/libshims/Android.mk index 5f0aac4..bd4c3c4 100644 --- a/libshims/Android.mk +++ b/libshims/Android.mk @@ -25,3 +25,18 @@ LOCAL_MODULE := libshims_ims LOCAL_MODULE_TAGS := optional include $(BUILD_SHARED_LIBRARY) + +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := \ + bionic/bionic_time_conversions.cpp \ + bionic/pthread_cond.cpp + +LOCAL_SHARED_LIBRARIES := libc + +LOCAL_MODULE := libshims_camera +LOCAL_MODULE_TAGS := optional + +LOCAL_32_BIT_ONLY := true + +include $(BUILD_SHARED_LIBRARY) diff --git a/libshims/bionic/bionic_time_conversions.cpp b/libshims/bionic/bionic_time_conversions.cpp new file mode 100644 index 0000000..0fbf15c --- /dev/null +++ b/libshims/bionic/bionic_time_conversions.cpp @@ -0,0 +1,17 @@ +#include "private/bionic_time_conversions.h" + +#define NS_PER_S 1000000000 + +bool timespec_from_absolute_timespec(timespec& ts, const timespec& abs_ts, clockid_t clock) { + clock_gettime(clock, &ts); + ts.tv_sec = abs_ts.tv_sec - ts.tv_sec; + ts.tv_nsec = abs_ts.tv_nsec - ts.tv_nsec; + if (ts.tv_nsec < 0) { + ts.tv_sec--; + ts.tv_nsec += NS_PER_S; + } + if (ts.tv_nsec < 0 || ts.tv_sec < 0) { + return false; + } + return true; +} diff --git a/libshims/bionic/pthread_cond.cpp b/libshims/bionic/pthread_cond.cpp new file mode 100644 index 0000000..0bde504 --- /dev/null +++ b/libshims/bionic/pthread_cond.cpp @@ -0,0 +1,79 @@ +#include <pthread.h> + +#include <sys/syscall.h> +#include <sys/mman.h> +#include <linux/futex.h> +#include <errno.h> +#include <stdatomic.h> +#include <time.h> +#include <unistd.h> + +#include "private/bionic_futex.h" +#include "private/bionic_time_conversions.h" + +#define COND_SHARED_MASK 0x0001 +#define COND_CLOCK_MASK 0x0002 + +#define COND_IS_SHARED(c) (((c) & COND_SHARED_MASK) != 0) +#define COND_GET_CLOCK(c) (((c) & COND_CLOCK_MASK) >> 1) + +struct pthread_cond_internal_t { + atomic_uint state; + + bool process_shared() { + return COND_IS_SHARED(atomic_load_explicit(&state, memory_order_relaxed)); + } + + int get_clock() { + return COND_GET_CLOCK(atomic_load_explicit(&state, memory_order_relaxed)); + } + +#if defined(__LP64__) + char __reserved[44]; +#endif +}; + +static pthread_cond_internal_t* __get_internal_cond(pthread_cond_t* cond_interface) { + return reinterpret_cast<pthread_cond_internal_t*>(cond_interface); +} + +static int __pthread_cond_timedwait_relative(pthread_cond_internal_t* cond, pthread_mutex_t* mutex, + const timespec* rel_timeout_or_null) { + unsigned int old_state = atomic_load_explicit(&cond->state, memory_order_relaxed); + + pthread_mutex_unlock(mutex); + int status = __futex_wait_ex(&cond->state, cond->process_shared(), old_state, rel_timeout_or_null); + pthread_mutex_lock(mutex); + + if (status == -ETIMEDOUT) { + return ETIMEDOUT; + } + return 0; +} + +static int __pthread_cond_timedwait(pthread_cond_internal_t* cond, pthread_mutex_t* mutex, + const timespec* abs_timeout_or_null, clockid_t clock) { + timespec ts; + timespec* rel_timeout = NULL; + + if (abs_timeout_or_null != NULL) { + rel_timeout = &ts; + if (!timespec_from_absolute_timespec(*rel_timeout, *abs_timeout_or_null, clock)) { + return ETIMEDOUT; + } + } + + return __pthread_cond_timedwait_relative(cond, mutex, rel_timeout); +} + +int pthread_cond_timedwait(pthread_cond_t *cond_interface, pthread_mutex_t * mutex, + const timespec *abstime) { + + pthread_cond_internal_t* cond = __get_internal_cond(cond_interface); + return __pthread_cond_timedwait(cond, mutex, abstime, cond->get_clock()); +} + +int pthread_cond_wait(pthread_cond_t* cond_interface, pthread_mutex_t* mutex) { + pthread_cond_internal_t* cond = __get_internal_cond(cond_interface); + return __pthread_cond_timedwait(cond, mutex, NULL, cond->get_clock()); +} diff --git a/libshims/private/bionic_futex.h b/libshims/private/bionic_futex.h new file mode 100644 index 0000000..0a8f4b0 --- /dev/null +++ b/libshims/private/bionic_futex.h @@ -0,0 +1,14 @@ +static inline __always_inline int __futex(volatile void* ftx, int op, int value, const struct timespec* timeout) { + // Our generated syscall assembler sets errno, but our callers (pthread functions) don't want to. + int saved_errno = errno; + int result = syscall(__NR_futex, ftx, op, value, timeout); + if (__predict_false(result == -1)) { + result = -errno; + errno = saved_errno; + } + return result; +} + +static inline int __futex_wait_ex(volatile void* ftx, bool shared, int value, const struct timespec* timeout) { + return __futex(ftx, shared ? FUTEX_WAIT : FUTEX_WAIT_PRIVATE, value, timeout); +} diff --git a/libshims/private/bionic_time_conversions.h b/libshims/private/bionic_time_conversions.h new file mode 100644 index 0000000..3010e87 --- /dev/null +++ b/libshims/private/bionic_time_conversions.h @@ -0,0 +1,3 @@ +#include <time.h> + +bool timespec_from_absolute_timespec(timespec& ts, const timespec& abs_ts, clockid_t clock); diff --git a/rootdir/etc/init.target.rc b/rootdir/etc/init.target.rc index b1e8add..447c26a 100644 --- a/rootdir/etc/init.target.rc +++ b/rootdir/etc/init.target.rc @@ -28,4 +28,4 @@ # on early-init - export LD_SHIM_LIBS /system/vendor/lib64/lib-imsvt.so|libshims_ims.so + export LD_SHIM_LIBS "/system/vendor/lib64/lib-imsvt.so|libshims_ims.so:/system/bin/mm-qcamera-daemon|libshims_camera.so" |
