event_loop.h revision f80ea015d077330cfdbd619680b250915ffcf1d2
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// TODO: using std lib for initial test... we can't do this in the real world 21e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie#include <atomic> 22e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 23e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie#include "chre/core/event.h" 24e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie#include "chre/core/nanoapp.h" 25fbb213b072fec0a14f437ad55685c4d95eec829eAndrew Rossignol#include "chre/core/timer_pool.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" 30e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 31e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddienamespace chre { 32e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 33e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie/** 34e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * TODO: document this better 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 43e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie // TODO: need a clear delineation for which methods are safe to call from 44e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie // threads other than the one calling run()... should include stop() and 45e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie // postEvent()... everything else would decidedly be not thread-safe 46e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 47e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie /** 48e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * Starts a nanoapp by invoking the start entry point. If this is successful, 49e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * the app is managed by the event loop and the pointer passed in must remain 50e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * valid. 51e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * 52e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * @param A pointer to the nanoapp to start. 53e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * @return True if the app was started successfully. 54e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie */ 55e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie bool startNanoapp(Nanoapp *nanoapp); 56e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 57e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie /** 58e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * Stops a nanoapp by invoking the stop entry point. The nanoapp passed in 59e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * must have been previously started by the startNanoapp method. 60e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * 61e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * @param A pointer to the nanoapp to stop. 62e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie */ 63e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie void stopNanoapp(Nanoapp *nanoapp); 64e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 65e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie /** 66e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * Start the main task run loop. Only returns after stop() is called 67e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * (from another context). 68e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie */ 69e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie void run(); 70e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 71e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie /** 72e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * Signals the event loop currently executing in run() to exit gracefully at 73f80ea015d077330cfdbd619680b250915ffcf1d2Brian Duddie * the next available opportunity. This function is thread-safe. 74e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie */ 75e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie void stop(); 76e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 774927ee586656424c827920876673228fbdcf27c3Andrew Rossignol /** 784927ee586656424c827920876673228fbdcf27c3Andrew Rossignol * Posts an event to a nanoapp that is currently running (or all nanoapps if 794927ee586656424c827920876673228fbdcf27c3Andrew Rossignol * the broadcast instance ID is used). 804927ee586656424c827920876673228fbdcf27c3Andrew Rossignol * 814927ee586656424c827920876673228fbdcf27c3Andrew Rossignol * @param The type of data being posted. 824927ee586656424c827920876673228fbdcf27c3Andrew Rossignol * @param The data being posted. 834927ee586656424c827920876673228fbdcf27c3Andrew Rossignol * @param The callback to invoke when the event is no longer needed. 844927ee586656424c827920876673228fbdcf27c3Andrew Rossignol * @param The instance ID of the sender of this event. 854927ee586656424c827920876673228fbdcf27c3Andrew Rossignol * @param The instance ID of the destination of this event. 864927ee586656424c827920876673228fbdcf27c3Andrew Rossignol * 874927ee586656424c827920876673228fbdcf27c3Andrew Rossignol * TODO: this is safe to call from other threads, and posts to the incoming 884927ee586656424c827920876673228fbdcf27c3Andrew Rossignol * event queue, then it is doled out to interested nanoapp queues later 894927ee586656424c827920876673228fbdcf27c3Andrew Rossignol */ 904927ee586656424c827920876673228fbdcf27c3Andrew Rossignol void postEvent(uint16_t eventType, void *eventData, 914927ee586656424c827920876673228fbdcf27c3Andrew Rossignol chreEventCompleteFunction *freeCallback, 924927ee586656424c827920876673228fbdcf27c3Andrew Rossignol uint32_t senderInstanceId = kSystemInstanceId, 934927ee586656424c827920876673228fbdcf27c3Andrew Rossignol uint32_t targetInstanceId = kBroadcastInstanceId); 94e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 95e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie // TODO: static method that allocates + constructs + posts an Event to all 96e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie // EventLoops (i.e. just the one for now), to simplify external code that will 97e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie // call this (they don't need to worry about how events are allocated, etc) 98e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 99e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie // TODO: do we need this? it might be a helpful convenience function that 100e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie // handles creation of a timer and stuff 101e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie void postEventDelayed(Event *event, uint64_t delayNs); 102e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 103e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie /** 104e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * Returns a pointer to the currently executing Nanoapp, or nullptr if none is 105e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * currently executing. 106e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * 107e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * @return a pointer to the currently executing nanoapp and nullptr if not 108e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * currently in an app context. 109e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie */ 1107983050d7cd84f1d5736f220ef9fd49be716b2c8Andrew Rossignol Nanoapp *getCurrentNanoapp() const; 111e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 112e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie /** 113e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * Returns a guaranteed unique instance ID that can be used to construct a 114e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * nanoapp. 115e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * 116e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * @return a unique instance ID to assign to a nanoapp. 117e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie */ 118e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie uint32_t getNextInstanceId(); 119e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 120725bef45ca127971b3ea798cd1f4e4b2c0d8fe9dAndrew Rossignol /** 121725bef45ca127971b3ea798cd1f4e4b2c0d8fe9dAndrew Rossignol * Obtains the TimerPool associated with this event loop. 122725bef45ca127971b3ea798cd1f4e4b2c0d8fe9dAndrew Rossignol * 123725bef45ca127971b3ea798cd1f4e4b2c0d8fe9dAndrew Rossignol * @return The timer pool owned by this event loop. 124725bef45ca127971b3ea798cd1f4e4b2c0d8fe9dAndrew Rossignol */ 125725bef45ca127971b3ea798cd1f4e4b2c0d8fe9dAndrew Rossignol TimerPool& getTimerPool(); 126725bef45ca127971b3ea798cd1f4e4b2c0d8fe9dAndrew Rossignol 127e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie private: 1284927ee586656424c827920876673228fbdcf27c3Andrew Rossignol //! The maximum number of events that can be active in the system. 1294927ee586656424c827920876673228fbdcf27c3Andrew Rossignol static constexpr size_t kMaxEventCount = 1024; 1304927ee586656424c827920876673228fbdcf27c3Andrew Rossignol 131022cc6c770c299bb364e35377a2661791475bbceAndrew Rossignol //! The maximum number of events that are awaiting to be scheduled. These 132022cc6c770c299bb364e35377a2661791475bbceAndrew Rossignol //! events are in a queue to be distributed to apps. 133022cc6c770c299bb364e35377a2661791475bbceAndrew Rossignol static constexpr size_t kMaxUnscheduledEventCount = 1024; 134022cc6c770c299bb364e35377a2661791475bbceAndrew Rossignol 135e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie //! The instance ID that was previously generated by getNextInstanceId. 136e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie uint32_t mLastInstanceId = kSystemInstanceId; 137e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 1384927ee586656424c827920876673228fbdcf27c3Andrew Rossignol //! The memory pool to allocate incoming events from. 139f7914d0fbadf2644c0c4096380c741bee2a026e0Andrew Rossignol SynchronizedMemoryPool<Event, kMaxEventCount> mEventPool; 1404927ee586656424c827920876673228fbdcf27c3Andrew Rossignol 141fbb213b072fec0a14f437ad55685c4d95eec829eAndrew Rossignol //! The timer used schedule timed events for tasks running in this event loop. 142fbb213b072fec0a14f437ad55685c4d95eec829eAndrew Rossignol TimerPool mTimerPool; 143fbb213b072fec0a14f437ad55685c4d95eec829eAndrew Rossignol 144c03d7df169f13195652de29f4452830130a0c53fAndrew Rossignol //! The list of nanoapps managed by this event loop. 1451795db1e2282dac8454cf59d23314f70b6930f7bAndrew Rossignol DynamicVector<Nanoapp *> mNanoapps; 146725bef45ca127971b3ea798cd1f4e4b2c0d8fe9dAndrew Rossignol 147c03d7df169f13195652de29f4452830130a0c53fAndrew Rossignol //! The blocking queue of incoming events from the system that have not been 148c03d7df169f13195652de29f4452830130a0c53fAndrew Rossignol //! distributed out to apps yet. 1491795db1e2282dac8454cf59d23314f70b6930f7bAndrew Rossignol FixedSizeBlockingQueue<Event *, kMaxUnscheduledEventCount> mEvents; 150e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 151e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie // TODO: we probably want our own atomic platform abstraction too 152e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie std::atomic<bool> mRunning{false}; 153e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 154e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie Nanoapp *mCurrentApp = nullptr; 155e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 156e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie void freeEvent(Event *event); 157e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie Nanoapp *lookupAppByInstanceId(uint32_t instanceId); 158e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 159e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie // TODO: we probably want a to model kSystemInstanceId as an actual nanoapp 160e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie // with entry points and all that to make it simpler to post events to ourself 161e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie // and the like... 162e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie}; 163e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 164e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie} // namespace chre 165e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 166e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie#endif // CHRE_CORE_EVENT_LOOP_H_ 167