event_loop.h revision 30f18903edc1dfe46e12b9989760ef7a56cb31d3
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" 24c03d7df169f13195652de29f4452830130a0c53fAndrew Rossignol#include "chre/util/dynamic_vector.h" 25022cc6c770c299bb364e35377a2661791475bbceAndrew Rossignol#include "chre/util/fixed_size_blocking_queue.h" 26e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie#include "chre/util/non_copyable.h" 27a1d5686c7513f6b8a436efd9f554d8c2227a2291Brian Duddie#include "chre/util/synchronized_memory_pool.h" 28e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 29e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddienamespace chre { 30e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 31e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie/** 32977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie * The EventLoop represents a single thread of execution that is shared among 33977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie * zero or more nanoapps. As the name implies, the EventLoop is built around a 34977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie * loop that delivers events to the nanoapps managed within for processing. 35e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie */ 36e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddieclass EventLoop : public NonCopyable { 37e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie public: 38fbb213b072fec0a14f437ad55685c4d95eec829eAndrew Rossignol /** 39fbb213b072fec0a14f437ad55685c4d95eec829eAndrew Rossignol * Setup the event loop. 40fbb213b072fec0a14f437ad55685c4d95eec829eAndrew Rossignol */ 41fbb213b072fec0a14f437ad55685c4d95eec829eAndrew Rossignol EventLoop(); 42fbb213b072fec0a14f437ad55685c4d95eec829eAndrew Rossignol 43977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie /** 44977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie * Searches the set of nanoapps managed by this EventLoop for one with the 45977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie * given app ID. If found, provides its instance ID, which can be used to send 46977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie * events to the app. 47977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie * 48977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie * This function is safe to call from any thread. 49977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie * 50977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie * @param appId The nanoapp identifier to search for. 51977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie * @param instanceId If this function returns true, will be populated with the 52977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie * instanceId associated with the given appId; otherwise unmodified. 53977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie * Must not be null. 54977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie * @return true if the given app ID was found and instanceId was populated 55977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie */ 56977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie bool findNanoappInstanceIdByAppId(uint64_t appId, uint32_t *instanceId); 57e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 58e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie /** 59e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * Starts a nanoapp by invoking the start entry point. If this is successful, 60e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * the app is managed by the event loop and the pointer passed in must remain 61e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * valid. 62e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * 63e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * @param A pointer to the nanoapp to start. 64e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * @return True if the app was started successfully. 65e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie */ 66e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie bool startNanoapp(Nanoapp *nanoapp); 67e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 68e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie /** 69e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * Stops a nanoapp by invoking the stop entry point. The nanoapp passed in 70e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * must have been previously started by the startNanoapp method. 71e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * 72e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * @param A pointer to the nanoapp to stop. 73e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie */ 74e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie void stopNanoapp(Nanoapp *nanoapp); 75e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 76e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie /** 77977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie * Executes the loop that blocks on the event queue and delivers received 78977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie * events to nanoapps. Only returns after stop() is called (from another 79977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie * context). 80e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie */ 81e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie void run(); 82e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 83e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie /** 84e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * Signals the event loop currently executing in run() to exit gracefully at 85f80ea015d077330cfdbd619680b250915ffcf1d2Brian Duddie * the next available opportunity. This function is thread-safe. 86e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie */ 87e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie void stop(); 88e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 894927ee586656424c827920876673228fbdcf27c3Andrew Rossignol /** 904927ee586656424c827920876673228fbdcf27c3Andrew Rossignol * Posts an event to a nanoapp that is currently running (or all nanoapps if 91042f73e3b7f019c818f69b2c097c4b6f9db839b5Brian Duddie * the target instance ID is kBroadcastInstanceId). 92042f73e3b7f019c818f69b2c097c4b6f9db839b5Brian Duddie * 93042f73e3b7f019c818f69b2c097c4b6f9db839b5Brian Duddie * This function is safe to call from any thread. 944927ee586656424c827920876673228fbdcf27c3Andrew Rossignol * 954927ee586656424c827920876673228fbdcf27c3Andrew Rossignol * @param The type of data being posted. 964927ee586656424c827920876673228fbdcf27c3Andrew Rossignol * @param The data being posted. 974927ee586656424c827920876673228fbdcf27c3Andrew Rossignol * @param The callback to invoke when the event is no longer needed. 984927ee586656424c827920876673228fbdcf27c3Andrew Rossignol * @param The instance ID of the sender of this event. 994927ee586656424c827920876673228fbdcf27c3Andrew Rossignol * @param The instance ID of the destination of this event. 1004927ee586656424c827920876673228fbdcf27c3Andrew Rossignol * 101042f73e3b7f019c818f69b2c097c4b6f9db839b5Brian Duddie * @return true if the event was successfully added to the queue 1024927ee586656424c827920876673228fbdcf27c3Andrew Rossignol */ 103042f73e3b7f019c818f69b2c097c4b6f9db839b5Brian Duddie bool postEvent(uint16_t eventType, void *eventData, 1044927ee586656424c827920876673228fbdcf27c3Andrew Rossignol chreEventCompleteFunction *freeCallback, 1054927ee586656424c827920876673228fbdcf27c3Andrew Rossignol uint32_t senderInstanceId = kSystemInstanceId, 1064927ee586656424c827920876673228fbdcf27c3Andrew Rossignol uint32_t targetInstanceId = kBroadcastInstanceId); 107e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 108e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie /** 109e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * Returns a pointer to the currently executing Nanoapp, or nullptr if none is 110977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie * currently executing. Must only be called from within the thread context 111977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie * associated with this EventLoop. 112e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * 113977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie * @return the currently executing nanoapp, or nullptr 114e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie */ 1157983050d7cd84f1d5736f220ef9fd49be716b2c8Andrew Rossignol Nanoapp *getCurrentNanoapp() const; 116e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 117e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie /** 118e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * Returns a guaranteed unique instance ID that can be used to construct a 119e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * nanoapp. 120e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * 121e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * @return a unique instance ID to assign to a nanoapp. 122e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie */ 123977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie // TODO: move this to EventLoopManager as it must be unique across all event 124977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie // loops; we currently really only support one EventLoop so it's OK for now 125e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie uint32_t getNextInstanceId(); 126e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 127725bef45ca127971b3ea798cd1f4e4b2c0d8fe9dAndrew Rossignol /** 128725bef45ca127971b3ea798cd1f4e4b2c0d8fe9dAndrew Rossignol * Obtains the TimerPool associated with this event loop. 129725bef45ca127971b3ea798cd1f4e4b2c0d8fe9dAndrew Rossignol * 130725bef45ca127971b3ea798cd1f4e4b2c0d8fe9dAndrew Rossignol * @return The timer pool owned by this event loop. 131725bef45ca127971b3ea798cd1f4e4b2c0d8fe9dAndrew Rossignol */ 132725bef45ca127971b3ea798cd1f4e4b2c0d8fe9dAndrew Rossignol TimerPool& getTimerPool(); 133725bef45ca127971b3ea798cd1f4e4b2c0d8fe9dAndrew Rossignol 13430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol /** 13530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol * Searches the set of nanoapps managed by this EventLoop for one with the 13630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol * given instance ID. 13730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol * 13830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol * This function is safe to call from any thread. 13930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol * 14030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol * @param instanceId The nanoapp instance ID to search for. 14130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol * @return a pointer to the found nanoapp or nullptr if no match was found. 14230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol */ 14330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol Nanoapp *findNanoappByInstanceId(uint32_t instanceId); 14430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 145e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie private: 1464927ee586656424c827920876673228fbdcf27c3Andrew Rossignol //! The maximum number of events that can be active in the system. 1474927ee586656424c827920876673228fbdcf27c3Andrew Rossignol static constexpr size_t kMaxEventCount = 1024; 1484927ee586656424c827920876673228fbdcf27c3Andrew Rossignol 149022cc6c770c299bb364e35377a2661791475bbceAndrew Rossignol //! The maximum number of events that are awaiting to be scheduled. These 150022cc6c770c299bb364e35377a2661791475bbceAndrew Rossignol //! events are in a queue to be distributed to apps. 151022cc6c770c299bb364e35377a2661791475bbceAndrew Rossignol static constexpr size_t kMaxUnscheduledEventCount = 1024; 152022cc6c770c299bb364e35377a2661791475bbceAndrew Rossignol 153e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie //! The instance ID that was previously generated by getNextInstanceId. 154e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie uint32_t mLastInstanceId = kSystemInstanceId; 155e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 1564927ee586656424c827920876673228fbdcf27c3Andrew Rossignol //! The memory pool to allocate incoming events from. 157f7914d0fbadf2644c0c4096380c741bee2a026e0Andrew Rossignol SynchronizedMemoryPool<Event, kMaxEventCount> mEventPool; 1584927ee586656424c827920876673228fbdcf27c3Andrew Rossignol 159fbb213b072fec0a14f437ad55685c4d95eec829eAndrew Rossignol //! The timer used schedule timed events for tasks running in this event loop. 160fbb213b072fec0a14f437ad55685c4d95eec829eAndrew Rossignol TimerPool mTimerPool; 161fbb213b072fec0a14f437ad55685c4d95eec829eAndrew Rossignol 162c03d7df169f13195652de29f4452830130a0c53fAndrew Rossignol //! The list of nanoapps managed by this event loop. 1631795db1e2282dac8454cf59d23314f70b6930f7bAndrew Rossignol DynamicVector<Nanoapp *> mNanoapps; 164725bef45ca127971b3ea798cd1f4e4b2c0d8fe9dAndrew Rossignol 165977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie //! This lock *must* be held whenever we: 166977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie //! (1) make changes to the mNanoapps vector, or 167977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie //! (2) read the mNanoapps vector from a thread other than the one 168977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie //! associated with this EventLoop 169977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie //! It is not necessary to acquire the lock when reading mNanoapps from within 170977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie //! the thread context of this EventLoop. 171977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie Mutex mNanoappsLock; 172977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie 173c03d7df169f13195652de29f4452830130a0c53fAndrew Rossignol //! The blocking queue of incoming events from the system that have not been 174c03d7df169f13195652de29f4452830130a0c53fAndrew Rossignol //! distributed out to apps yet. 1751795db1e2282dac8454cf59d23314f70b6930f7bAndrew Rossignol FixedSizeBlockingQueue<Event *, kMaxUnscheduledEventCount> mEvents; 176e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 177977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie // TODO: should probably be atomic to be fully correct 178977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie volatile bool mRunning = false; 179e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 180e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie Nanoapp *mCurrentApp = nullptr; 181e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 182977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie /** 183977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie * Call after when an Event has been delivered to all intended recipients. 184977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie * Invokes the event's free callback (if given) and releases resources. 185977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie * 186977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie * @param event The event to be freed 187977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie */ 188e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie void freeEvent(Event *event); 189e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 190977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie /** 191977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie * Finds a Nanoapp with the given instanceId. 192977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie * 193977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie * Only safe to call within this EventLoop's thread. 194977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie * 195977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie * @param instanceId Nanoapp instance identifier 196977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie * @return Nanoapp with the given instanceId, or nullptr if not found 197977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie */ 198977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie Nanoapp *lookupAppByInstanceId(uint32_t instanceId); 199e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie}; 200e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 201e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie} // namespace chre 202e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 203e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie#endif // CHRE_CORE_EVENT_LOOP_H_ 204