From patchwork Tue Sep 12 09:36:10 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mattijs Korpershoek X-Patchwork-Id: 18985 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 9FE87C3260 for ; Tue, 12 Sep 2023 09:36:23 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id E8D7E628FA; Tue, 12 Sep 2023 11:36:21 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1694511382; bh=V8H6oWQC035fz59EKF4waa9Kvjxmd+PEIjSMxtRGSmg=; h=Date:References:In-Reply-To:To:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=RiY73JBGtVYCjnwTjQJLGEsQy75EmQiRxLQpyWgN7AyO5AlyuhKQcQ5uVLjC27goT wTQwoK50y/+guHKe1EwXjUopsWAndJ+/5phAlJTK/SKJD+WEB3vPkaWJUMzzdHGKG7 4MVulIA91XB4Zbhgx9jazFw4TLMS/yCDTiOcnEVZ1kq993MrQFcmMdjQbo4EvBuzSh C558XyFGytZEbibehiwX87vX54alnx+hvj3CYer4SUemwucE8SsuHh/gM0+SDtMTqs u2fCQ7nCNJ5eLH7YotWMk0UrHbFetWWgeHIwIi0gcn0Tqbn29rxtZhThYQWJq86vRn cZg034ZnJaTBw== Received: from mail-wm1-x335.google.com (mail-wm1-x335.google.com [IPv6:2a00:1450:4864:20::335]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 9DC0F628E9 for ; Tue, 12 Sep 2023 11:36:19 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b="jhm9TmdO"; dkim-atps=neutral Received: by mail-wm1-x335.google.com with SMTP id 5b1f17b1804b1-401bdff4cb4so57772685e9.3 for ; Tue, 12 Sep 2023 02:36:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1694511379; x=1695116179; darn=lists.libcamera.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=InTK3cpHjAowfn+YPF+0J0VMRNJykgYZo8jT8zXv8lo=; b=jhm9TmdOxFYbUqbwSgkzN/3drxohVEUrgaht2eqoP7bcdQKdrMshhtoHnMj/YzftjY /4VAeMNUVs0PRseB09bd3xRYelwWKrpmQGsrJJ+rXfzYTbjQi6f/DA1dFwj0lF2GehP8 CE4b9/IgzUvEjunz2G9boitMIq5eUiNw0Jo35rTL/ShkV70fwO3+fJtP3Z4pDLMZXxnF OgoQ8ux+rffUzkH2zKfaSISiYPAW3l4/nIXIw6L1KaZ2P3OFsjnuFkdXhPwLlk7dC8aW m9ng1aBIDmfXIZNQOYqRY0AOoOXmm9O8CnYMSpoDx894dR4ZUe+rDRO8OLWsfd2cRutT 1tgw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1694511379; x=1695116179; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=InTK3cpHjAowfn+YPF+0J0VMRNJykgYZo8jT8zXv8lo=; b=KiX7/UjMgJguwWcghhlgGkxKHV7Agl35/SXnsOZVH7UNFvVs1kCy2X0Xa0O6a2GSlX y6iVZW+92ak2flyYsS2hXbqvdRi+ne5H/z2iMpV1dWaTKREFR9hucglha9bTzfYkrunC lpxDRZF+uYK7W1cgGZFHQhVHcS7YGU/g6ixB9hTaUMpGnpTVUZh6fezVHzgwJfBPINaN Jp+9bX67Pt0xON+0TWEXr1lONAPnhcWksNvN7zoIVx/9TyHy90LIKdPnAoeCebd4hJry iC2uy7S3Ukv0MGqWsvzzUDNVb6MdJLOojzwyUWSvlDMOz2kA0AsBHx/zf0+trogWx0+i Lp1A== X-Gm-Message-State: AOJu0YyEArX/YpVJU066t41xZOLWe7XILqUkQO45gecEdDWgaFqfeUU8 hy1fOmWVsTrx2gdiN/0ecO2MEbHaNTHyytr8RJg= X-Google-Smtp-Source: AGHT+IFI6E9LXncwpyejsGYjLwL9ipb8H8wODoXT1hilBZkADpoGmmPqw86hW53B5pyPvwqt/S3YdQ== X-Received: by 2002:a05:600c:215:b0:401:b53e:6c56 with SMTP id 21-20020a05600c021500b00401b53e6c56mr10320307wmi.3.1694511379085; Tue, 12 Sep 2023 02:36:19 -0700 (PDT) Received: from [192.168.2.39] ([82.66.159.240]) by smtp.gmail.com with ESMTPSA id y10-20020a05600c364a00b00401b242e2e6sm15578253wmq.47.2023.09.12.02.36.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 Sep 2023 02:36:18 -0700 (PDT) Date: Tue, 12 Sep 2023 11:36:10 +0200 MIME-Version: 1.0 Message-Id: <20230912-gralloc-api-v4-v1-1-0f80402d8e7a@baylibre.com> References: <20230912-gralloc-api-v4-v1-0-0f80402d8e7a@baylibre.com> In-Reply-To: <20230912-gralloc-api-v4-v1-0-0f80402d8e7a@baylibre.com> To: libcamera-devel@lists.libcamera.org X-Mailer: b4 0.12.3 Subject: [libcamera-devel] [PATCH 1/4] android: Import libutils/libui headers from vndk v33 X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Mattijs Korpershoek via libcamera-devel From: Mattijs Korpershoek Reply-To: Mattijs Korpershoek Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" In order to switch to the more modern GraphicBufferAllocator class, we need additional compile-time dependencies. Import all the needed headers from the Android Vendor Native Development Kit (vndk) and add them to the android_includes. These have been imported from: URL: https://android.googlesource.com/platform/prebuilts/vndk/v33/ rev: 390028a9da88 ("Update VNDK snapshot v33 to build 9948968. am: 3042508aee am: 7092391a46") No changes have been made to the files, besides adding the SPDX comment. Signed-off-by: Mattijs Korpershoek --- .../native/libs/ui/include/ui/PixelFormat.h | 75 +++++++ include/android/meson.build | 2 + .../system/core/libutils/include/utils/Compat.h | 94 +++++++++ .../system/core/libutils/include/utils/Errors.h | 78 ++++++++ .../system/core/libutils/include/utils/Mutex.h | 219 +++++++++++++++++++++ .../system/core/libutils/include/utils/Singleton.h | 102 ++++++++++ .../system/core/libutils/include/utils/Timers.h | 103 ++++++++++ 7 files changed, 673 insertions(+) diff --git a/include/android/frameworks/native/libs/ui/include/ui/PixelFormat.h b/include/android/frameworks/native/libs/ui/include/ui/PixelFormat.h new file mode 100644 index 000000000000..2add09462218 --- /dev/null +++ b/include/android/frameworks/native/libs/ui/include/ui/PixelFormat.h @@ -0,0 +1,75 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * Copyright (C) 2005 The Android Open Source Project + * + * 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. + */ + +// + +// Pixel formats used across the system. +// These formats might not all be supported by all renderers, for instance +// skia or SurfaceFlinger are not required to support all of these formats +// (either as source or destination) + + +#ifndef UI_PIXELFORMAT_H +#define UI_PIXELFORMAT_H + +#include + +namespace android { + +enum { + // + // these constants need to match those + // in graphics/PixelFormat.java & pixelflinger/format.h + // + PIXEL_FORMAT_UNKNOWN = 0, + PIXEL_FORMAT_NONE = 0, + + // logical pixel formats used by the SurfaceFlinger ----------------------- + PIXEL_FORMAT_CUSTOM = -4, + // Custom pixel-format described by a PixelFormatInfo structure + + PIXEL_FORMAT_TRANSLUCENT = -3, + // System chooses a format that supports translucency (many alpha bits) + + PIXEL_FORMAT_TRANSPARENT = -2, + // System chooses a format that supports transparency + // (at least 1 alpha bit) + + PIXEL_FORMAT_OPAQUE = -1, + // System chooses an opaque format (no alpha bits required) + + // real pixel formats supported for rendering ----------------------------- + + PIXEL_FORMAT_RGBA_8888 = HAL_PIXEL_FORMAT_RGBA_8888, // 4x8-bit RGBA + PIXEL_FORMAT_RGBX_8888 = HAL_PIXEL_FORMAT_RGBX_8888, // 4x8-bit RGB0 + PIXEL_FORMAT_RGB_888 = HAL_PIXEL_FORMAT_RGB_888, // 3x8-bit RGB + PIXEL_FORMAT_RGB_565 = HAL_PIXEL_FORMAT_RGB_565, // 16-bit RGB + PIXEL_FORMAT_BGRA_8888 = HAL_PIXEL_FORMAT_BGRA_8888, // 4x8-bit BGRA + PIXEL_FORMAT_RGBA_5551 = 6, // 16-bit ARGB + PIXEL_FORMAT_RGBA_4444 = 7, // 16-bit ARGB + PIXEL_FORMAT_RGBA_FP16 = HAL_PIXEL_FORMAT_RGBA_FP16, // 64-bit RGBA + PIXEL_FORMAT_RGBA_1010102 = HAL_PIXEL_FORMAT_RGBA_1010102, // 32-bit RGBA + PIXEL_FORMAT_R_8 = 0x38, +}; + +typedef int32_t PixelFormat; + +uint32_t bytesPerPixel(PixelFormat format); + +}; // namespace android + +#endif // UI_PIXELFORMAT_H diff --git a/include/android/meson.build b/include/android/meson.build index da2504f2e493..59a4f36b523b 100644 --- a/include/android/meson.build +++ b/include/android/meson.build @@ -1,7 +1,9 @@ # SPDX-License-Identifier: CC0-1.0 android_includes = ([ + include_directories('frameworks/native/libs/ui/include/'), include_directories('hardware/libhardware/include/'), include_directories('metadata/'), include_directories('system/core/include'), + include_directories('system/core/libutils/include/'), ]) diff --git a/include/android/system/core/libutils/include/utils/Compat.h b/include/android/system/core/libutils/include/utils/Compat.h new file mode 100644 index 000000000000..bba568bd3226 --- /dev/null +++ b/include/android/system/core/libutils/include/utils/Compat.h @@ -0,0 +1,94 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * 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. + */ + +#ifndef __LIB_UTILS_COMPAT_H +#define __LIB_UTILS_COMPAT_H + +#include + +#if !defined(__MINGW32__) +#include +#endif + +#if defined(__APPLE__) + +/* Mac OS has always had a 64-bit off_t, so it doesn't have off64_t. */ +static_assert(sizeof(off_t) >= 8, "This code requires that Mac OS have at least a 64-bit off_t."); +typedef off_t off64_t; + +static inline void* mmap64(void* addr, size_t length, int prot, int flags, int fd, off64_t offset) { + return mmap(addr, length, prot, flags, fd, offset); +} + +static inline off64_t lseek64(int fd, off64_t offset, int whence) { + return lseek(fd, offset, whence); +} + +static inline ssize_t pread64(int fd, void* buf, size_t nbytes, off64_t offset) { + return pread(fd, buf, nbytes, offset); +} + +static inline ssize_t pwrite64(int fd, const void* buf, size_t nbytes, off64_t offset) { + return pwrite(fd, buf, nbytes, offset); +} + +static inline int ftruncate64(int fd, off64_t length) { + return ftruncate(fd, length); +} + +#endif /* __APPLE__ */ + +#if defined(_WIN32) +#define O_CLOEXEC O_NOINHERIT +#define O_NOFOLLOW 0 +#define DEFFILEMODE 0666 +#endif /* _WIN32 */ + +#define ZD "%zd" +#define ZD_TYPE ssize_t + +/* + * Needed for cases where something should be constexpr if possible, but not + * being constexpr is fine if in pre-C++11 code (such as a const static float + * member variable). + */ +#if __cplusplus >= 201103L +#define CONSTEXPR constexpr +#else +#define CONSTEXPR +#endif + +/* TEMP_FAILURE_RETRY is not available on macOS, but still useful there. */ +#ifndef TEMP_FAILURE_RETRY +/* Used to retry syscalls that can return EINTR. */ +#define TEMP_FAILURE_RETRY(exp) \ + ({ \ + __typeof__(exp) _rc; \ + do { \ + _rc = (exp); \ + } while (_rc == -1 && errno == EINTR); \ + _rc; \ + }) +#endif + +#if defined(_WIN32) +#define OS_PATH_SEPARATOR '\\' +#else +#define OS_PATH_SEPARATOR '/' +#endif + +#endif /* __LIB_UTILS_COMPAT_H */ diff --git a/include/android/system/core/libutils/include/utils/Errors.h b/include/android/system/core/libutils/include/utils/Errors.h new file mode 100644 index 000000000000..f812844eacc4 --- /dev/null +++ b/include/android/system/core/libutils/include/utils/Errors.h @@ -0,0 +1,78 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * 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. + */ + +#pragma once + +#include +#include +#include +#include + +namespace android { + +/** + * The type used to return success/failure from frameworks APIs. + * See the anonymous enum below for valid values. + */ +typedef int32_t status_t; + +/* + * Error codes. + * All error codes are negative values. + */ + +enum { + OK = 0, // Preferred constant for checking success. +#ifndef NO_ERROR + // Win32 #defines NO_ERROR as well. It has the same value, so there's no + // real conflict, though it's a bit awkward. + NO_ERROR = OK, // Deprecated synonym for `OK`. Prefer `OK` because it doesn't conflict with Windows. +#endif + + UNKNOWN_ERROR = (-2147483647-1), // INT32_MIN value + + NO_MEMORY = -ENOMEM, + INVALID_OPERATION = -ENOSYS, + BAD_VALUE = -EINVAL, + BAD_TYPE = (UNKNOWN_ERROR + 1), + NAME_NOT_FOUND = -ENOENT, + PERMISSION_DENIED = -EPERM, + NO_INIT = -ENODEV, + ALREADY_EXISTS = -EEXIST, + DEAD_OBJECT = -EPIPE, + FAILED_TRANSACTION = (UNKNOWN_ERROR + 2), +#if !defined(_WIN32) + BAD_INDEX = -EOVERFLOW, + NOT_ENOUGH_DATA = -ENODATA, + WOULD_BLOCK = -EWOULDBLOCK, + TIMED_OUT = -ETIMEDOUT, + UNKNOWN_TRANSACTION = -EBADMSG, +#else + BAD_INDEX = -E2BIG, + NOT_ENOUGH_DATA = (UNKNOWN_ERROR + 3), + WOULD_BLOCK = (UNKNOWN_ERROR + 4), + TIMED_OUT = (UNKNOWN_ERROR + 5), + UNKNOWN_TRANSACTION = (UNKNOWN_ERROR + 6), +#endif + FDS_NOT_ALLOWED = (UNKNOWN_ERROR + 7), + UNEXPECTED_NULL = (UNKNOWN_ERROR + 8), +}; + +// Human readable name of error +std::string statusToString(status_t status); + +} // namespace android diff --git a/include/android/system/core/libutils/include/utils/Mutex.h b/include/android/system/core/libutils/include/utils/Mutex.h new file mode 100644 index 000000000000..72d20bdca888 --- /dev/null +++ b/include/android/system/core/libutils/include/utils/Mutex.h @@ -0,0 +1,219 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * 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. + */ + +#ifndef _LIBS_UTILS_MUTEX_H +#define _LIBS_UTILS_MUTEX_H + +#include +#include +#include + +#if !defined(_WIN32) +# include +#endif + +#include +#include + +// Enable thread safety attributes only with clang. +// The attributes can be safely erased when compiling with other compilers. +#if defined(__clang__) && (!defined(SWIG)) +#define THREAD_ANNOTATION_ATTRIBUTE__(x) __attribute__((x)) +#else +#define THREAD_ANNOTATION_ATTRIBUTE__(x) // no-op +#endif + +#define CAPABILITY(x) THREAD_ANNOTATION_ATTRIBUTE__(capability(x)) + +#define SCOPED_CAPABILITY THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable) + +#define GUARDED_BY(x) THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x)) + +#define PT_GUARDED_BY(x) THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded_by(x)) + +#define ACQUIRED_BEFORE(...) THREAD_ANNOTATION_ATTRIBUTE__(acquired_before(__VA_ARGS__)) + +#define ACQUIRED_AFTER(...) THREAD_ANNOTATION_ATTRIBUTE__(acquired_after(__VA_ARGS__)) + +#define REQUIRES(...) THREAD_ANNOTATION_ATTRIBUTE__(requires_capability(__VA_ARGS__)) + +#define REQUIRES_SHARED(...) THREAD_ANNOTATION_ATTRIBUTE__(requires_shared_capability(__VA_ARGS__)) + +#define ACQUIRE(...) THREAD_ANNOTATION_ATTRIBUTE__(acquire_capability(__VA_ARGS__)) + +#define ACQUIRE_SHARED(...) THREAD_ANNOTATION_ATTRIBUTE__(acquire_shared_capability(__VA_ARGS__)) + +#define RELEASE(...) THREAD_ANNOTATION_ATTRIBUTE__(release_capability(__VA_ARGS__)) + +#define RELEASE_SHARED(...) THREAD_ANNOTATION_ATTRIBUTE__(release_shared_capability(__VA_ARGS__)) + +#define TRY_ACQUIRE(...) THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_capability(__VA_ARGS__)) + +#define TRY_ACQUIRE_SHARED(...) \ + THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_shared_capability(__VA_ARGS__)) + +#define EXCLUDES(...) THREAD_ANNOTATION_ATTRIBUTE__(locks_excluded(__VA_ARGS__)) + +#define ASSERT_CAPABILITY(x) THREAD_ANNOTATION_ATTRIBUTE__(assert_capability(x)) + +#define ASSERT_SHARED_CAPABILITY(x) THREAD_ANNOTATION_ATTRIBUTE__(assert_shared_capability(x)) + +#define RETURN_CAPABILITY(x) THREAD_ANNOTATION_ATTRIBUTE__(lock_returned(x)) + +#define NO_THREAD_SAFETY_ANALYSIS THREAD_ANNOTATION_ATTRIBUTE__(no_thread_safety_analysis) + +// --------------------------------------------------------------------------- +namespace android { +// --------------------------------------------------------------------------- + +class Condition; + +/* + * NOTE: This class is for code that builds on Win32. Its usage is + * deprecated for code which doesn't build for Win32. New code which + * doesn't build for Win32 should use std::mutex and std::lock_guard instead. + * + * Simple mutex class. The implementation is system-dependent. + * + * The mutex must be unlocked by the thread that locked it. They are not + * recursive, i.e. the same thread can't lock it multiple times. + */ +class CAPABILITY("mutex") Mutex { + public: + enum { + PRIVATE = 0, + SHARED = 1 + }; + + Mutex(); + explicit Mutex(const char* name); + explicit Mutex(int type, const char* name = nullptr); + ~Mutex(); + + // lock or unlock the mutex + status_t lock() ACQUIRE(); + void unlock() RELEASE(); + + // lock if possible; returns 0 on success, error otherwise + status_t tryLock() TRY_ACQUIRE(0); + +#if defined(__ANDROID__) + // Lock the mutex, but don't wait longer than timeoutNs (relative time). + // Returns 0 on success, TIMED_OUT for failure due to timeout expiration. + // + // OSX doesn't have pthread_mutex_timedlock() or equivalent. To keep + // capabilities consistent across host OSes, this method is only available + // when building Android binaries. + // + // FIXME?: pthread_mutex_timedlock is based on CLOCK_REALTIME, + // which is subject to NTP adjustments, and includes time during suspend, + // so a timeout may occur even though no processes could run. + // Not holding a partial wakelock may lead to a system suspend. + status_t timedLock(nsecs_t timeoutNs) TRY_ACQUIRE(0); +#endif + + // Manages the mutex automatically. It'll be locked when Autolock is + // constructed and released when Autolock goes out of scope. + class SCOPED_CAPABILITY Autolock { + public: + inline explicit Autolock(Mutex& mutex) ACQUIRE(mutex) : mLock(mutex) { mLock.lock(); } + inline explicit Autolock(Mutex* mutex) ACQUIRE(mutex) : mLock(*mutex) { mLock.lock(); } + inline ~Autolock() RELEASE() { mLock.unlock(); } + + private: + Mutex& mLock; + // Cannot be copied or moved - declarations only + Autolock(const Autolock&); + Autolock& operator=(const Autolock&); + }; + + private: + friend class Condition; + + // A mutex cannot be copied + Mutex(const Mutex&); + Mutex& operator=(const Mutex&); + +#if !defined(_WIN32) + pthread_mutex_t mMutex; +#else + void _init(); + void* mState; +#endif +}; + +// --------------------------------------------------------------------------- + +#if !defined(_WIN32) + +inline Mutex::Mutex() { + pthread_mutex_init(&mMutex, nullptr); +} +inline Mutex::Mutex(__attribute__((unused)) const char* name) { + pthread_mutex_init(&mMutex, nullptr); +} +inline Mutex::Mutex(int type, __attribute__((unused)) const char* name) { + if (type == SHARED) { + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED); + pthread_mutex_init(&mMutex, &attr); + pthread_mutexattr_destroy(&attr); + } else { + pthread_mutex_init(&mMutex, nullptr); + } +} +inline Mutex::~Mutex() { + pthread_mutex_destroy(&mMutex); +} +inline status_t Mutex::lock() { + return -pthread_mutex_lock(&mMutex); +} +inline void Mutex::unlock() { + pthread_mutex_unlock(&mMutex); +} +inline status_t Mutex::tryLock() { + return -pthread_mutex_trylock(&mMutex); +} +#if defined(__ANDROID__) +inline status_t Mutex::timedLock(nsecs_t timeoutNs) { + timeoutNs += systemTime(SYSTEM_TIME_REALTIME); + const struct timespec ts = { + /* .tv_sec = */ static_cast(timeoutNs / 1000000000), + /* .tv_nsec = */ static_cast(timeoutNs % 1000000000), + }; + return -pthread_mutex_timedlock(&mMutex, &ts); +} +#endif + +#endif // !defined(_WIN32) + +// --------------------------------------------------------------------------- + +/* + * Automatic mutex. Declare one of these at the top of a function. + * When the function returns, it will go out of scope, and release the + * mutex. + */ + +typedef Mutex::Autolock AutoMutex; + +// --------------------------------------------------------------------------- +} // namespace android +// --------------------------------------------------------------------------- + +#endif // _LIBS_UTILS_MUTEX_H diff --git a/include/android/system/core/libutils/include/utils/Singleton.h b/include/android/system/core/libutils/include/utils/Singleton.h new file mode 100644 index 000000000000..154aed8f28e5 --- /dev/null +++ b/include/android/system/core/libutils/include/utils/Singleton.h @@ -0,0 +1,102 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * 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. + */ + +#ifndef ANDROID_UTILS_SINGLETON_H +#define ANDROID_UTILS_SINGLETON_H + +#include + +// some vendor code assumes they have atoi() after including this file. +#include + +#include +#include +#include + +namespace android { +// --------------------------------------------------------------------------- + +// Singleton may be used in multiple libraries, only one of which should +// define the static member variables using ANDROID_SINGLETON_STATIC_INSTANCE. +// Turn off -Wundefined-var-template so other users don't get: +// instantiation of variable 'android::Singleton::sLock' required here, +// but no definition is available +#if defined(__clang__) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wundefined-var-template" +#endif + +// DO NOT USE: Please use scoped static initialization. For instance: +// MyClass& getInstance() { +// static MyClass gInstance(...); +// return gInstance; +// } +template +class ANDROID_API Singleton +{ +public: + static TYPE& getInstance() { + Mutex::Autolock _l(sLock); + TYPE* instance = sInstance; + if (instance == nullptr) { + instance = new TYPE(); + sInstance = instance; + } + return *instance; + } + + static bool hasInstance() { + Mutex::Autolock _l(sLock); + return sInstance != nullptr; + } + +protected: + ~Singleton() { } + Singleton() { } + +private: + Singleton(const Singleton&); + Singleton& operator = (const Singleton&); + static Mutex sLock; + static TYPE* sInstance; +}; + +#if defined(__clang__) +#pragma clang diagnostic pop +#endif + +/* + * use ANDROID_SINGLETON_STATIC_INSTANCE(TYPE) in your implementation file + * (eg: .cpp) to create the static instance of Singleton<>'s attributes, + * and avoid to have a copy of them in each compilation units Singleton + * is used. + * NOTE: we use a version of Mutex ctor that takes a parameter, because + * for some unknown reason using the default ctor doesn't emit the variable! + */ + +#define ANDROID_SINGLETON_STATIC_INSTANCE(TYPE) \ + template<> ::android::Mutex \ + (::android::Singleton< TYPE >::sLock)(::android::Mutex::PRIVATE); \ + template<> TYPE* ::android::Singleton< TYPE >::sInstance(nullptr); /* NOLINT */ \ + template class ::android::Singleton< TYPE >; + + +// --------------------------------------------------------------------------- +} // namespace android + +#endif // ANDROID_UTILS_SINGLETON_H + diff --git a/include/android/system/core/libutils/include/utils/Timers.h b/include/android/system/core/libutils/include/utils/Timers.h new file mode 100644 index 000000000000..40acafabc099 --- /dev/null +++ b/include/android/system/core/libutils/include/utils/Timers.h @@ -0,0 +1,103 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * Copyright (C) 2005 The Android Open Source Project + * + * 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. + */ + +#pragma once + +#include +#include +#include + +#include + +// ------------------------------------------------------------------ +// C API + +#ifdef __cplusplus +extern "C" { +#endif + +typedef int64_t nsecs_t; // nano-seconds + +static CONSTEXPR inline nsecs_t seconds_to_nanoseconds(nsecs_t secs) +{ + return secs*1000000000; +} + +static CONSTEXPR inline nsecs_t milliseconds_to_nanoseconds(nsecs_t secs) +{ + return secs*1000000; +} + +static CONSTEXPR inline nsecs_t microseconds_to_nanoseconds(nsecs_t secs) +{ + return secs*1000; +} + +static CONSTEXPR inline nsecs_t nanoseconds_to_seconds(nsecs_t secs) +{ + return secs/1000000000; +} + +static CONSTEXPR inline nsecs_t nanoseconds_to_milliseconds(nsecs_t secs) +{ + return secs/1000000; +} + +static CONSTEXPR inline nsecs_t nanoseconds_to_microseconds(nsecs_t secs) +{ + return secs/1000; +} + +static CONSTEXPR inline nsecs_t s2ns(nsecs_t v) {return seconds_to_nanoseconds(v);} +static CONSTEXPR inline nsecs_t ms2ns(nsecs_t v) {return milliseconds_to_nanoseconds(v);} +static CONSTEXPR inline nsecs_t us2ns(nsecs_t v) {return microseconds_to_nanoseconds(v);} +static CONSTEXPR inline nsecs_t ns2s(nsecs_t v) {return nanoseconds_to_seconds(v);} +static CONSTEXPR inline nsecs_t ns2ms(nsecs_t v) {return nanoseconds_to_milliseconds(v);} +static CONSTEXPR inline nsecs_t ns2us(nsecs_t v) {return nanoseconds_to_microseconds(v);} + +static CONSTEXPR inline nsecs_t seconds(nsecs_t v) { return s2ns(v); } +static CONSTEXPR inline nsecs_t milliseconds(nsecs_t v) { return ms2ns(v); } +static CONSTEXPR inline nsecs_t microseconds(nsecs_t v) { return us2ns(v); } + +enum { + SYSTEM_TIME_REALTIME = 0, // system-wide realtime clock + SYSTEM_TIME_MONOTONIC = 1, // monotonic time since unspecified starting point + SYSTEM_TIME_PROCESS = 2, // high-resolution per-process clock + SYSTEM_TIME_THREAD = 3, // high-resolution per-thread clock + SYSTEM_TIME_BOOTTIME = 4, // same as SYSTEM_TIME_MONOTONIC, but including CPU suspend time +}; + +// return the system-time according to the specified clock +#ifdef __cplusplus +nsecs_t systemTime(int clock = SYSTEM_TIME_MONOTONIC); +#else +nsecs_t systemTime(int clock); +#endif // def __cplusplus + +/** + * Returns the number of milliseconds to wait between the reference time and the timeout time. + * If the timeout is in the past relative to the reference time, returns 0. + * If the timeout is more than INT_MAX milliseconds in the future relative to the reference time, + * such as when timeoutTime == LLONG_MAX, returns -1 to indicate an infinite timeout delay. + * Otherwise, returns the difference between the reference time and timeout time + * rounded up to the next millisecond. + */ +int toMillisecondTimeoutDelay(nsecs_t referenceTime, nsecs_t timeoutTime); + +#ifdef __cplusplus +} // extern "C" +#endif