1e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie/* 2e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * Copyright (C) 2016 The Android Open Source Project 3e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * 4e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * Licensed under the Apache License, Version 2.0 (the "License"); 5e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * you may not use this file except in compliance with the License. 6e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * You may obtain a copy of the License at 7e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * 8e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * http://www.apache.org/licenses/LICENSE-2.0 9e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * 10e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * Unless required by applicable law or agreed to in writing, software 11e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * distributed under the License is distributed on an "AS IS" BASIS, 12e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * See the License for the specific language governing permissions and 14e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * limitations under the License. 15e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie */ 16e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 17e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie#ifndef CHRE_CORE_EVENT_LOOP_H_ 18e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie#define CHRE_CORE_EVENT_LOOP_H_ 19e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 20e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie#include "chre/core/event.h" 21e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie#include "chre/core/nanoapp.h" 22fbb213b072fec0a14f437ad55685c4d95eec829eAndrew Rossignol#include "chre/core/timer_pool.h" 23977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie#include "chre/platform/mutex.h" 242de17c9c5c541d72248f8371dfb4d7e402dc93e8Andrew Rossignol#include "chre/platform/platform_nanoapp.h" 25ff1c1a2ab3ff2614bb6cea1f1d6f6e9c44a87464Arthur Ishiguro#include "chre/platform/power_control_manager.h" 26c03d7df169f13195652de29f4452830130a0c53fAndrew Rossignol#include "chre/util/dynamic_vector.h" 27022cc6c770c299bb364e35377a2661791475bbceAndrew Rossignol#include "chre/util/fixed_size_blocking_queue.h" 28e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie#include "chre/util/non_copyable.h" 29a1d5686c7513f6b8a436efd9f554d8c2227a2291Brian Duddie#include "chre/util/synchronized_memory_pool.h" 302de17c9c5c541d72248f8371dfb4d7e402dc93e8Andrew Rossignol#include "chre/util/unique_ptr.h" 3162f187d9d736346275492e916f6001576b68bb00Brian Duddie#include "chre_api/chre/event.h" 32e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 33cbf0967e920840e21bcd6aeda67d88b70d30a558Meng-hsuan Chung// These default values can be overridden in the variant-specific makefile. 34cbf0967e920840e21bcd6aeda67d88b70d30a558Meng-hsuan Chung#ifndef CHRE_MAX_EVENT_COUNT 35cbf0967e920840e21bcd6aeda67d88b70d30a558Meng-hsuan Chung#define CHRE_MAX_EVENT_COUNT 96 36cbf0967e920840e21bcd6aeda67d88b70d30a558Meng-hsuan Chung#endif 37cbf0967e920840e21bcd6aeda67d88b70d30a558Meng-hsuan Chung 38cbf0967e920840e21bcd6aeda67d88b70d30a558Meng-hsuan Chung#ifndef CHRE_MAX_UNSCHEDULED_EVENT_COUNT 39cbf0967e920840e21bcd6aeda67d88b70d30a558Meng-hsuan Chung#define CHRE_MAX_UNSCHEDULED_EVENT_COUNT 96 40cbf0967e920840e21bcd6aeda67d88b70d30a558Meng-hsuan Chung#endif 41cbf0967e920840e21bcd6aeda67d88b70d30a558Meng-hsuan Chung 42e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddienamespace chre { 43e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 44e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie/** 45977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie * The EventLoop represents a single thread of execution that is shared among 46977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie * zero or more nanoapps. As the name implies, the EventLoop is built around a 47977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie * loop that delivers events to the nanoapps managed within for processing. 48e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie */ 49e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddieclass EventLoop : public NonCopyable { 50e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie public: 51fbb213b072fec0a14f437ad55685c4d95eec829eAndrew Rossignol /** 52a2f5add27054c406f36528cf8a5cbc6d4c79d246Brian Duddie * Synchronous callback used with forEachNanoapp 53a2f5add27054c406f36528cf8a5cbc6d4c79d246Brian Duddie */ 54a2f5add27054c406f36528cf8a5cbc6d4c79d246Brian Duddie typedef void (NanoappCallbackFunction)(const Nanoapp *nanoapp, void *data); 55a2f5add27054c406f36528cf8a5cbc6d4c79d246Brian Duddie 56a2f5add27054c406f36528cf8a5cbc6d4c79d246Brian Duddie /** 57977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie * Searches the set of nanoapps managed by this EventLoop for one with the 58977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie * given app ID. If found, provides its instance ID, which can be used to send 59977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie * events to the app. 60977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie * 61977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie * This function is safe to call from any thread. 62977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie * 63977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie * @param appId The nanoapp identifier to search for. 64977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie * @param instanceId If this function returns true, will be populated with the 65977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie * instanceId associated with the given appId; otherwise unmodified. 66977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie * Must not be null. 67977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie * @return true if the given app ID was found and instanceId was populated 68977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie */ 692fce52a25d14fcdcba888f8ff7892dffe3f55abaBrian Duddie bool findNanoappInstanceIdByAppId(uint64_t appId, uint32_t *instanceId) const; 70e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 71e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie /** 72a2f5add27054c406f36528cf8a5cbc6d4c79d246Brian Duddie * Iterates over the list of Nanoapps managed by this EventLoop, and invokes 73a2f5add27054c406f36528cf8a5cbc6d4c79d246Brian Duddie * the supplied callback for each one. This holds a lock if necessary, so it 74a2f5add27054c406f36528cf8a5cbc6d4c79d246Brian Duddie * is safe to call from any thread. 75a2f5add27054c406f36528cf8a5cbc6d4c79d246Brian Duddie * 76a2f5add27054c406f36528cf8a5cbc6d4c79d246Brian Duddie * @param callback Function to invoke on each Nanoapp (synchronously) 77a2f5add27054c406f36528cf8a5cbc6d4c79d246Brian Duddie * @param data Arbitrary data to pass to the callback 78a2f5add27054c406f36528cf8a5cbc6d4c79d246Brian Duddie */ 79a2f5add27054c406f36528cf8a5cbc6d4c79d246Brian Duddie void forEachNanoapp(NanoappCallbackFunction *callback, void *data); 80a2f5add27054c406f36528cf8a5cbc6d4c79d246Brian Duddie 81a2f5add27054c406f36528cf8a5cbc6d4c79d246Brian Duddie /** 8209a4783208b5ba1e14d0f0102eb31e688caca28dBrian Duddie * Invokes a message to host free callback supplied by the given nanoapp 8309a4783208b5ba1e14d0f0102eb31e688caca28dBrian Duddie * (identified by app ID). Ensures that the calling context is updated 8409a4783208b5ba1e14d0f0102eb31e688caca28dBrian Duddie * appropriately. 8509a4783208b5ba1e14d0f0102eb31e688caca28dBrian Duddie * 8609a4783208b5ba1e14d0f0102eb31e688caca28dBrian Duddie * @param appId Identifies the nanoapp that sent this message and supplied the 8709a4783208b5ba1e14d0f0102eb31e688caca28dBrian Duddie * free callback 8809a4783208b5ba1e14d0f0102eb31e688caca28dBrian Duddie * @param freeFunction The non-null message free callback given by the nanoapp 8909a4783208b5ba1e14d0f0102eb31e688caca28dBrian Duddie * @param message Pointer to the message data 9009a4783208b5ba1e14d0f0102eb31e688caca28dBrian Duddie * @param messageSize Size of the message 9109a4783208b5ba1e14d0f0102eb31e688caca28dBrian Duddie */ 9209a4783208b5ba1e14d0f0102eb31e688caca28dBrian Duddie void invokeMessageFreeFunction( 9309a4783208b5ba1e14d0f0102eb31e688caca28dBrian Duddie uint64_t appId, chreMessageFreeFunction *freeFunction, void *message, 9409a4783208b5ba1e14d0f0102eb31e688caca28dBrian Duddie size_t messageSize); 9509a4783208b5ba1e14d0f0102eb31e688caca28dBrian Duddie 9609a4783208b5ba1e14d0f0102eb31e688caca28dBrian Duddie /** 979d5b500a223ef73560f0dce38f50b809bde5dd0dBrian Duddie * Invokes the Nanoapp's start callback, and if successful, adds it to the 989d5b500a223ef73560f0dce38f50b809bde5dd0dBrian Duddie * set of Nanoapps managed by this EventLoop. This function must only be 999d5b500a223ef73560f0dce38f50b809bde5dd0dBrian Duddie * called from the context of the thread that runs this event loop (i.e. from 1009d5b500a223ef73560f0dce38f50b809bde5dd0dBrian Duddie * the same thread that will call run() or from a callback invoked within 1019d5b500a223ef73560f0dce38f50b809bde5dd0dBrian Duddie * run()). 102e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * 1039d5b500a223ef73560f0dce38f50b809bde5dd0dBrian Duddie * @param nanoapp The nanoapp that will be started. Upon success, this 1049d5b500a223ef73560f0dce38f50b809bde5dd0dBrian Duddie * UniquePtr will become invalid, as the underlying Nanoapp instance 1059d5b500a223ef73560f0dce38f50b809bde5dd0dBrian Duddie * will have been transferred to be managed by this EventLoop. 1069d5b500a223ef73560f0dce38f50b809bde5dd0dBrian Duddie * @return true if the app was started successfully 107e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie */ 1089d5b500a223ef73560f0dce38f50b809bde5dd0dBrian Duddie bool startNanoapp(UniquePtr<Nanoapp>& nanoapp); 109e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 110e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie /** 11199f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie * Stops and unloads a nanoapp identified by its instance ID. The end entry 11299f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie * point will be invoked, and the chre::Nanoapp instance will be destroyed. 11399f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie * After this function returns, all references to the Nanoapp instance are 11499f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie * invalidated. 115e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * 11699f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie * @param instanceId The nanoapp's unique instance identifier 11799f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie * @param allowSystemNanoappUnload If false, this function will reject 11899f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie * attempts to unload a system nanoapp 11999f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie * 12099f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie * @return true if the nanoapp with the given instance ID was found & unloaded 121e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie */ 12299f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie bool unloadNanoapp(uint32_t instanceId, bool allowSystemNanoappUnload); 123e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 124e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie /** 125977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie * Executes the loop that blocks on the event queue and delivers received 126977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie * events to nanoapps. Only returns after stop() is called (from another 127977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie * context). 128e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie */ 129e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie void run(); 130e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 131e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie /** 132e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * Signals the event loop currently executing in run() to exit gracefully at 133f80ea015d077330cfdbd619680b250915ffcf1d2Brian Duddie * the next available opportunity. This function is thread-safe. 134e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie */ 135e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie void stop(); 136e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 1374927ee586656424c827920876673228fbdcf27c3Andrew Rossignol /** 1384927ee586656424c827920876673228fbdcf27c3Andrew Rossignol * Posts an event to a nanoapp that is currently running (or all nanoapps if 1393c8d7a9746ec61c1677ed33f9fcd25d3830392c7Andrew Rossignol * the target instance ID is kBroadcastInstanceId). If the senderInstanceId is 1403c8d7a9746ec61c1677ed33f9fcd25d3830392c7Andrew Rossignol * kSystemInstanceId and the event fails to post, this is considered a fatal 1413c8d7a9746ec61c1677ed33f9fcd25d3830392c7Andrew Rossignol * error. 142042f73e3b7f019c818f69b2c097c4b6f9db839b5Brian Duddie * 143042f73e3b7f019c818f69b2c097c4b6f9db839b5Brian Duddie * This function is safe to call from any thread. 1444927ee586656424c827920876673228fbdcf27c3Andrew Rossignol * 1455d9b2d68940f7dac47bf2fbad6f6069ed3b2faaaBrian Duddie * @param eventType The type of data being posted. 1465d9b2d68940f7dac47bf2fbad6f6069ed3b2faaaBrian Duddie * @param eventData The data being posted. 1475d9b2d68940f7dac47bf2fbad6f6069ed3b2faaaBrian Duddie * @param freeCallback The callback to invoke when the event is no longer 1485d9b2d68940f7dac47bf2fbad6f6069ed3b2faaaBrian Duddie * needed. 1495d9b2d68940f7dac47bf2fbad6f6069ed3b2faaaBrian Duddie * @param senderInstanceId The instance ID of the sender of this event. 1505d9b2d68940f7dac47bf2fbad6f6069ed3b2faaaBrian Duddie * @param targetInstanceId The instance ID of the destination of this event. 1514927ee586656424c827920876673228fbdcf27c3Andrew Rossignol * 152a12d05f5b1b8bd8d953a328758426b7ca8b5e6deBrian Duddie * @return true if the event was successfully added to the queue. Note that 153a12d05f5b1b8bd8d953a328758426b7ca8b5e6deBrian Duddie * unlike chreSendEvent, this does *not* invoke the free callback if 154a12d05f5b1b8bd8d953a328758426b7ca8b5e6deBrian Duddie * it failed to post the event. 1555d9b2d68940f7dac47bf2fbad6f6069ed3b2faaaBrian Duddie * 1565d9b2d68940f7dac47bf2fbad6f6069ed3b2faaaBrian Duddie * @see chreSendEvent 1574927ee586656424c827920876673228fbdcf27c3Andrew Rossignol */ 158042f73e3b7f019c818f69b2c097c4b6f9db839b5Brian Duddie bool postEvent(uint16_t eventType, void *eventData, 1594927ee586656424c827920876673228fbdcf27c3Andrew Rossignol chreEventCompleteFunction *freeCallback, 1604927ee586656424c827920876673228fbdcf27c3Andrew Rossignol uint32_t senderInstanceId = kSystemInstanceId, 1614927ee586656424c827920876673228fbdcf27c3Andrew Rossignol uint32_t targetInstanceId = kBroadcastInstanceId); 162e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 163e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie /** 16453bc18a9e15f478ea0332a733b77c718114a8610Meng-hsuan Chung * Post an event to a nanoapp. If it fails, free the event with freeCallback. 16553bc18a9e15f478ea0332a733b77c718114a8610Meng-hsuan Chung * 16653bc18a9e15f478ea0332a733b77c718114a8610Meng-hsuan Chung * @see postEvent 16753bc18a9e15f478ea0332a733b77c718114a8610Meng-hsuan Chung */ 16853bc18a9e15f478ea0332a733b77c718114a8610Meng-hsuan Chung bool postEventOrFree(uint16_t eventType, void *eventData, 16953bc18a9e15f478ea0332a733b77c718114a8610Meng-hsuan Chung chreEventCompleteFunction *freeCallback, 17053bc18a9e15f478ea0332a733b77c718114a8610Meng-hsuan Chung uint32_t senderInstanceId = kSystemInstanceId, 17153bc18a9e15f478ea0332a733b77c718114a8610Meng-hsuan Chung uint32_t targetInstanceId = kBroadcastInstanceId); 17253bc18a9e15f478ea0332a733b77c718114a8610Meng-hsuan Chung 17353bc18a9e15f478ea0332a733b77c718114a8610Meng-hsuan Chung /** 174e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * Returns a pointer to the currently executing Nanoapp, or nullptr if none is 175977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie * currently executing. Must only be called from within the thread context 176977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie * associated with this EventLoop. 177e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * 178977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie * @return the currently executing nanoapp, or nullptr 179e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie */ 180b75315a3e185b4559d73c69eea3b30679239fac1Andrew Rossignol Nanoapp *getCurrentNanoapp() const { 181b75315a3e185b4559d73c69eea3b30679239fac1Andrew Rossignol return mCurrentApp; 182b75315a3e185b4559d73c69eea3b30679239fac1Andrew Rossignol } 183e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 184e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie /** 185a2f5add27054c406f36528cf8a5cbc6d4c79d246Brian Duddie * Gets the number of nanoapps currently associated with this event loop. Must 186a2f5add27054c406f36528cf8a5cbc6d4c79d246Brian Duddie * only be called within the context of this EventLoop. 187a2f5add27054c406f36528cf8a5cbc6d4c79d246Brian Duddie * 188a2f5add27054c406f36528cf8a5cbc6d4c79d246Brian Duddie * @return The number of nanoapps managed by this event loop 189a2f5add27054c406f36528cf8a5cbc6d4c79d246Brian Duddie */ 190b75315a3e185b4559d73c69eea3b30679239fac1Andrew Rossignol size_t getNanoappCount() const { 191b75315a3e185b4559d73c69eea3b30679239fac1Andrew Rossignol return mNanoapps.size(); 192b75315a3e185b4559d73c69eea3b30679239fac1Andrew Rossignol } 193a2f5add27054c406f36528cf8a5cbc6d4c79d246Brian Duddie 194a2f5add27054c406f36528cf8a5cbc6d4c79d246Brian Duddie /** 195725bef45ca127971b3ea798cd1f4e4b2c0d8fe9dAndrew Rossignol * Obtains the TimerPool associated with this event loop. 196725bef45ca127971b3ea798cd1f4e4b2c0d8fe9dAndrew Rossignol * 197725bef45ca127971b3ea798cd1f4e4b2c0d8fe9dAndrew Rossignol * @return The timer pool owned by this event loop. 198725bef45ca127971b3ea798cd1f4e4b2c0d8fe9dAndrew Rossignol */ 199b75315a3e185b4559d73c69eea3b30679239fac1Andrew Rossignol TimerPool& getTimerPool() { 200b75315a3e185b4559d73c69eea3b30679239fac1Andrew Rossignol return mTimerPool; 201b75315a3e185b4559d73c69eea3b30679239fac1Andrew Rossignol } 202725bef45ca127971b3ea798cd1f4e4b2c0d8fe9dAndrew Rossignol 20330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol /** 20430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol * Searches the set of nanoapps managed by this EventLoop for one with the 20530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol * given instance ID. 20630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol * 20730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol * This function is safe to call from any thread. 20830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol * 20930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol * @param instanceId The nanoapp instance ID to search for. 21030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol * @return a pointer to the found nanoapp or nullptr if no match was found. 21130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol */ 2122fce52a25d14fcdcba888f8ff7892dffe3f55abaBrian Duddie Nanoapp *findNanoappByInstanceId(uint32_t instanceId) const; 21330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 21499f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie /** 21562f187d9d736346275492e916f6001576b68bb00Brian Duddie * Looks for an app with the given ID and if found, populates info with its 21662f187d9d736346275492e916f6001576b68bb00Brian Duddie * metadata. Safe to call from any thread. 21762f187d9d736346275492e916f6001576b68bb00Brian Duddie * 21862f187d9d736346275492e916f6001576b68bb00Brian Duddie * @see chreGetNanoappInfoByAppId 21962f187d9d736346275492e916f6001576b68bb00Brian Duddie */ 22062f187d9d736346275492e916f6001576b68bb00Brian Duddie bool populateNanoappInfoForAppId(uint64_t appId, 22162f187d9d736346275492e916f6001576b68bb00Brian Duddie struct chreNanoappInfo *info) const; 22262f187d9d736346275492e916f6001576b68bb00Brian Duddie 22362f187d9d736346275492e916f6001576b68bb00Brian Duddie /** 22462f187d9d736346275492e916f6001576b68bb00Brian Duddie * Looks for an app with the given instance ID and if found, populates info 22562f187d9d736346275492e916f6001576b68bb00Brian Duddie * with its metadata. Safe to call from any thread. 22662f187d9d736346275492e916f6001576b68bb00Brian Duddie * 22762f187d9d736346275492e916f6001576b68bb00Brian Duddie * @see chreGetNanoappInfoByInstanceId 22862f187d9d736346275492e916f6001576b68bb00Brian Duddie */ 22962f187d9d736346275492e916f6001576b68bb00Brian Duddie bool populateNanoappInfoForInstanceId(uint32_t instanceId, 23062f187d9d736346275492e916f6001576b68bb00Brian Duddie struct chreNanoappInfo *info) const; 23162f187d9d736346275492e916f6001576b68bb00Brian Duddie 23262f187d9d736346275492e916f6001576b68bb00Brian Duddie /** 23399f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie * @return true if the current Nanoapp (or entire CHRE) is being unloaded, and 23499f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie * therefore it should not be allowed to send events or messages, etc. 23599f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie */ 2362fce52a25d14fcdcba888f8ff7892dffe3f55abaBrian Duddie bool currentNanoappIsStopping() const; 23799f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie 238d0530f420d8bdaee755ec2834af407424de195e0Arthur Ishiguro /** 239d0530f420d8bdaee755ec2834af407424de195e0Arthur Ishiguro * Prints state in a string buffer. Must only be called from the context of 240d0530f420d8bdaee755ec2834af407424de195e0Arthur Ishiguro * the main CHRE thread. 241d0530f420d8bdaee755ec2834af407424de195e0Arthur Ishiguro * 242d0530f420d8bdaee755ec2834af407424de195e0Arthur Ishiguro * @param buffer Pointer to the start of the buffer. 243d0530f420d8bdaee755ec2834af407424de195e0Arthur Ishiguro * @param bufferPos Pointer to buffer position to start the print (in-out). 244d0530f420d8bdaee755ec2834af407424de195e0Arthur Ishiguro * @param size Size of the buffer in bytes. 245d0530f420d8bdaee755ec2834af407424de195e0Arthur Ishiguro * 246d0530f420d8bdaee755ec2834af407424de195e0Arthur Ishiguro * @return true if entire log printed, false if overflow or error. 247d0530f420d8bdaee755ec2834af407424de195e0Arthur Ishiguro */ 248d0530f420d8bdaee755ec2834af407424de195e0Arthur Ishiguro bool logStateToBuffer(char *buffer, size_t *bufferPos, 249d0530f420d8bdaee755ec2834af407424de195e0Arthur Ishiguro size_t bufferSize) const; 250d0530f420d8bdaee755ec2834af407424de195e0Arthur Ishiguro 251ff1c1a2ab3ff2614bb6cea1f1d6f6e9c44a87464Arthur Ishiguro 252ff1c1a2ab3ff2614bb6cea1f1d6f6e9c44a87464Arthur Ishiguro /** 253ff1c1a2ab3ff2614bb6cea1f1d6f6e9c44a87464Arthur Ishiguro * Returns a reference to the power control manager. This allows power 254ff1c1a2ab3ff2614bb6cea1f1d6f6e9c44a87464Arthur Ishiguro * controls from subsystems outside the event loops. 255ff1c1a2ab3ff2614bb6cea1f1d6f6e9c44a87464Arthur Ishiguro */ 256ff1c1a2ab3ff2614bb6cea1f1d6f6e9c44a87464Arthur Ishiguro PowerControlManager& getPowerControlManager() { 257ff1c1a2ab3ff2614bb6cea1f1d6f6e9c44a87464Arthur Ishiguro return mPowerControlManager; 258ff1c1a2ab3ff2614bb6cea1f1d6f6e9c44a87464Arthur Ishiguro } 259ff1c1a2ab3ff2614bb6cea1f1d6f6e9c44a87464Arthur Ishiguro 260e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie private: 2614927ee586656424c827920876673228fbdcf27c3Andrew Rossignol //! The maximum number of events that can be active in the system. 262cbf0967e920840e21bcd6aeda67d88b70d30a558Meng-hsuan Chung static constexpr size_t kMaxEventCount = CHRE_MAX_EVENT_COUNT; 2634927ee586656424c827920876673228fbdcf27c3Andrew Rossignol 2643c8d7a9746ec61c1677ed33f9fcd25d3830392c7Andrew Rossignol //! The minimum number of events to reserve in the event pool for system 2653c8d7a9746ec61c1677ed33f9fcd25d3830392c7Andrew Rossignol //! events. 2663c8d7a9746ec61c1677ed33f9fcd25d3830392c7Andrew Rossignol static constexpr size_t kMinReservedSystemEventCount = 16; 2673c8d7a9746ec61c1677ed33f9fcd25d3830392c7Andrew Rossignol 268022cc6c770c299bb364e35377a2661791475bbceAndrew Rossignol //! The maximum number of events that are awaiting to be scheduled. These 269022cc6c770c299bb364e35377a2661791475bbceAndrew Rossignol //! events are in a queue to be distributed to apps. 270cbf0967e920840e21bcd6aeda67d88b70d30a558Meng-hsuan Chung static constexpr size_t kMaxUnscheduledEventCount = 271cbf0967e920840e21bcd6aeda67d88b70d30a558Meng-hsuan Chung CHRE_MAX_UNSCHEDULED_EVENT_COUNT; 272022cc6c770c299bb364e35377a2661791475bbceAndrew Rossignol 2734927ee586656424c827920876673228fbdcf27c3Andrew Rossignol //! The memory pool to allocate incoming events from. 274f7914d0fbadf2644c0c4096380c741bee2a026e0Andrew Rossignol SynchronizedMemoryPool<Event, kMaxEventCount> mEventPool; 2754927ee586656424c827920876673228fbdcf27c3Andrew Rossignol 276fbb213b072fec0a14f437ad55685c4d95eec829eAndrew Rossignol //! The timer used schedule timed events for tasks running in this event loop. 277fbb213b072fec0a14f437ad55685c4d95eec829eAndrew Rossignol TimerPool mTimerPool; 278fbb213b072fec0a14f437ad55685c4d95eec829eAndrew Rossignol 279c03d7df169f13195652de29f4452830130a0c53fAndrew Rossignol //! The list of nanoapps managed by this event loop. 2802de17c9c5c541d72248f8371dfb4d7e402dc93e8Andrew Rossignol DynamicVector<UniquePtr<Nanoapp>> mNanoapps; 281725bef45ca127971b3ea798cd1f4e4b2c0d8fe9dAndrew Rossignol 282977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie //! This lock *must* be held whenever we: 283977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie //! (1) make changes to the mNanoapps vector, or 284977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie //! (2) read the mNanoapps vector from a thread other than the one 285977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie //! associated with this EventLoop 286977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie //! It is not necessary to acquire the lock when reading mNanoapps from within 287977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie //! the thread context of this EventLoop. 2882fce52a25d14fcdcba888f8ff7892dffe3f55abaBrian Duddie mutable Mutex mNanoappsLock; 289977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie 290c03d7df169f13195652de29f4452830130a0c53fAndrew Rossignol //! The blocking queue of incoming events from the system that have not been 29199f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie //! distributed out to apps yet. 2921795db1e2282dac8454cf59d23314f70b6930f7bAndrew Rossignol FixedSizeBlockingQueue<Event *, kMaxUnscheduledEventCount> mEvents; 293e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 294977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie // TODO: should probably be atomic to be fully correct 2958c56d08e149720fcb99e6ddc71289ebb5ee594e6Brian Duddie volatile bool mRunning = true; 296e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 29799f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie //! The nanoapp that is currently executing - must be set any time we call 29899f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie //! into the nanoapp's entry points or callbacks 299e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie Nanoapp *mCurrentApp = nullptr; 300e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 30199f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie //! Set to the nanoapp we are in the process of unloading in unloadNanoapp() 30299f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie Nanoapp *mStoppingNanoapp = nullptr; 30399f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie 304ff1c1a2ab3ff2614bb6cea1f1d6f6e9c44a87464Arthur Ishiguro //! The object which manages power related controls. 305ff1c1a2ab3ff2614bb6cea1f1d6f6e9c44a87464Arthur Ishiguro PowerControlManager mPowerControlManager; 306ff1c1a2ab3ff2614bb6cea1f1d6f6e9c44a87464Arthur Ishiguro 30788f21c7ca23d96f6ef568a06c98f3a5c4538140fAndrew Rossignol //! The maximum number of events ever waiting in the event pool. 30888f21c7ca23d96f6ef568a06c98f3a5c4538140fAndrew Rossignol size_t mMaxEventPoolUsage = 0; 30988f21c7ca23d96f6ef568a06c98f3a5c4538140fAndrew Rossignol 31099f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie /** 31153bc18a9e15f478ea0332a733b77c718114a8610Meng-hsuan Chung * Allolcates an event from the event pool and post it. 31253bc18a9e15f478ea0332a733b77c718114a8610Meng-hsuan Chung * 31353bc18a9e15f478ea0332a733b77c718114a8610Meng-hsuan Chung * @return true if the event has been successfully allocated and posted. 31453bc18a9e15f478ea0332a733b77c718114a8610Meng-hsuan Chung * 31553bc18a9e15f478ea0332a733b77c718114a8610Meng-hsuan Chung * @see postEvent and postEventOrFree 31653bc18a9e15f478ea0332a733b77c718114a8610Meng-hsuan Chung */ 31753bc18a9e15f478ea0332a733b77c718114a8610Meng-hsuan Chung bool allocateAndPostEvent(uint16_t eventType, void *eventData, 31853bc18a9e15f478ea0332a733b77c718114a8610Meng-hsuan Chung chreEventCompleteFunction *freeCallback, uint32_t senderInstanceId, 31953bc18a9e15f478ea0332a733b77c718114a8610Meng-hsuan Chung uint32_t targetInstanceId); 32053bc18a9e15f478ea0332a733b77c718114a8610Meng-hsuan Chung 32153bc18a9e15f478ea0332a733b77c718114a8610Meng-hsuan Chung /** 32299f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie * Do one round of Nanoapp event delivery, only considering events in 32399f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie * Nanoapps' own queues (not mEvents). 32499f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie * 32599f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie * @return true if there are more events pending in Nanoapps' own queues 32699f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie */ 32799f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie bool deliverEvents(); 32899f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie 329977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie /** 3305d9b2d68940f7dac47bf2fbad6f6069ed3b2faaaBrian Duddie * Delivers the next event pending in the Nanoapp's queue, and takes care of 3315d9b2d68940f7dac47bf2fbad6f6069ed3b2faaaBrian Duddie * freeing events once they have been delivered to all nanoapps. Must only be 3325d9b2d68940f7dac47bf2fbad6f6069ed3b2faaaBrian Duddie * called after confirming that the app has at least 1 pending event. 3335d9b2d68940f7dac47bf2fbad6f6069ed3b2faaaBrian Duddie * 3345d9b2d68940f7dac47bf2fbad6f6069ed3b2faaaBrian Duddie * @return true if the nanoapp has another event pending in its queue 3355d9b2d68940f7dac47bf2fbad6f6069ed3b2faaaBrian Duddie */ 3365d9b2d68940f7dac47bf2fbad6f6069ed3b2faaaBrian Duddie bool deliverNextEvent(const UniquePtr<Nanoapp>& app); 3375d9b2d68940f7dac47bf2fbad6f6069ed3b2faaaBrian Duddie 3385d9b2d68940f7dac47bf2fbad6f6069ed3b2faaaBrian Duddie /** 33999f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie * Given an event pulled from the main incoming event queue (mEvents), deliver 34099f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie * it to all Nanoapps that should receive the event, or free the event if 34199f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie * there are no valid recipients. 34299f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie * 34399f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie * @param event The Event to distribute to Nanoapps 34499f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie */ 34599f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie void distributeEvent(Event *event); 34699f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie 34799f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie /** 34899f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie * Distribute all events pending in the inbound event queue. Note that this 34999f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie * function only guarantees that any events in the inbound queue at the time 35099f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie * it is called will be distributed to Nanoapp event queues - new events may 35199f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie * still be posted during or after this function call from other threads as 35299f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie * long as postEvent() will accept them. 35399f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie */ 35499f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie void flushInboundEventQueue(); 35599f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie 35699f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie /** 35799f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie * Delivers events pending in Nanoapps' own queues until they are all empty. 35899f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie */ 35999f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie void flushNanoappEventQueues(); 36099f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie 36199f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie /** 362977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie * Call after when an Event has been delivered to all intended recipients. 363977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie * Invokes the event's free callback (if given) and releases resources. 364977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie * 365977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie * @param event The event to be freed 366977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie */ 367e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie void freeEvent(Event *event); 368e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 369977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie /** 37009a4783208b5ba1e14d0f0102eb31e688caca28dBrian Duddie * Finds a Nanoapp with the given 64-bit appId. 37109a4783208b5ba1e14d0f0102eb31e688caca28dBrian Duddie * 3722fce52a25d14fcdcba888f8ff7892dffe3f55abaBrian Duddie * Only safe to call within this EventLoop's thread, or if mNanoappsLock is 3732fce52a25d14fcdcba888f8ff7892dffe3f55abaBrian Duddie * held. 37409a4783208b5ba1e14d0f0102eb31e688caca28dBrian Duddie * 37509a4783208b5ba1e14d0f0102eb31e688caca28dBrian Duddie * @param appId Nanoapp ID 37609a4783208b5ba1e14d0f0102eb31e688caca28dBrian Duddie * @return Pointer to Nanoapp instance in this EventLoop with the given app 37709a4783208b5ba1e14d0f0102eb31e688caca28dBrian Duddie * ID, or nullptr if not found 37809a4783208b5ba1e14d0f0102eb31e688caca28dBrian Duddie */ 3792fce52a25d14fcdcba888f8ff7892dffe3f55abaBrian Duddie Nanoapp *lookupAppByAppId(uint64_t appId) const; 38009a4783208b5ba1e14d0f0102eb31e688caca28dBrian Duddie 38109a4783208b5ba1e14d0f0102eb31e688caca28dBrian Duddie /** 382977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie * Finds a Nanoapp with the given instanceId. 383977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie * 3842fce52a25d14fcdcba888f8ff7892dffe3f55abaBrian Duddie * Only safe to call within this EventLoop's thread, or if mNanoappsLock is 3852fce52a25d14fcdcba888f8ff7892dffe3f55abaBrian Duddie * held. 386977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie * 387977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie * @param instanceId Nanoapp instance identifier 388977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie * @return Nanoapp with the given instanceId, or nullptr if not found 389977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie */ 3902fce52a25d14fcdcba888f8ff7892dffe3f55abaBrian Duddie Nanoapp *lookupAppByInstanceId(uint32_t instanceId) const; 3915d9b2d68940f7dac47bf2fbad6f6069ed3b2faaaBrian Duddie 3925d9b2d68940f7dac47bf2fbad6f6069ed3b2faaaBrian Duddie /** 39365d679851a2c062c26f685afb450f17bce177d29Brian Duddie * Sends an event with payload struct chreNanoappInfo populated from the given 39465d679851a2c062c26f685afb450f17bce177d29Brian Duddie * Nanoapp instance to inform other nanoapps about it starting/stopping. 39565d679851a2c062c26f685afb450f17bce177d29Brian Duddie * 39665d679851a2c062c26f685afb450f17bce177d29Brian Duddie * @param eventType Should be one of CHRE_EVENT_NANOAPP_{STARTED, STOPPED} 39765d679851a2c062c26f685afb450f17bce177d29Brian Duddie * @param nanoapp The nanoapp instance whose status has changed 39865d679851a2c062c26f685afb450f17bce177d29Brian Duddie */ 39965d679851a2c062c26f685afb450f17bce177d29Brian Duddie void notifyAppStatusChange(uint16_t eventType, const Nanoapp& nanoapp); 40065d679851a2c062c26f685afb450f17bce177d29Brian Duddie 40165d679851a2c062c26f685afb450f17bce177d29Brian Duddie /** 40299f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie * Stops and unloads the Nanoapp at the given index in mNanoapps. 40399f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie * 40499f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie * IMPORTANT: prior to calling this function, the event queues must be in a 40599f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie * safe condition for removal of this nanoapp. This means that there must not 40699f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie * be any pending events in this nanoapp's queue, and there must not be any 40799f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie * outstanding events sent by this nanoapp, as they may reference the 40899f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie * nanoapp's own memory (even if there is no free callback). 4095d9b2d68940f7dac47bf2fbad6f6069ed3b2faaaBrian Duddie */ 41099f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie void unloadNanoappAtIndex(size_t index); 411e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie}; 412e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 413e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie} // namespace chre 414e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 415e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie#endif // CHRE_CORE_EVENT_LOOP_H_ 416