event_loop.h revision c03d7df169f13195652de29f4452830130a0c53f
1/* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#ifndef CHRE_CORE_EVENT_LOOP_H_ 18#define CHRE_CORE_EVENT_LOOP_H_ 19 20// TODO: using std lib for initial test... we can't do this in the real world 21#include <atomic> 22 23#include "chre/core/event.h" 24#include "chre/core/nanoapp.h" 25#include "chre/core/timer_pool.h" 26#include "chre/util/blocking_queue.h" 27#include "chre/util/dynamic_vector.h" 28#include "chre/util/non_copyable.h" 29#include "chre/util/synchronized_memory_pool.h" 30 31namespace chre { 32 33/** 34 * TODO: document this better 35 */ 36class EventLoop : public NonCopyable { 37 public: 38 /** 39 * Setup the event loop. 40 */ 41 EventLoop(); 42 43 // TODO: need a clear delineation for which methods are safe to call from 44 // threads other than the one calling run()... should include stop() and 45 // postEvent()... everything else would decidedly be not thread-safe 46 47 /** 48 * Starts a nanoapp by invoking the start entry point. If this is successful, 49 * the app is managed by the event loop and the pointer passed in must remain 50 * valid. 51 * 52 * @param A pointer to the nanoapp to start. 53 * @return True if the app was started successfully. 54 */ 55 bool startNanoapp(Nanoapp *nanoapp); 56 57 /** 58 * Stops a nanoapp by invoking the stop entry point. The nanoapp passed in 59 * must have been previously started by the startNanoapp method. 60 * 61 * @param A pointer to the nanoapp to stop. 62 */ 63 void stopNanoapp(Nanoapp *nanoapp); 64 65 /** 66 * Start the main task run loop. Only returns after stop() is called 67 * (from another context). 68 */ 69 void run(); 70 71 /** 72 * Signals the event loop currently executing in run() to exit gracefully at 73 * the next available opportunity. 74 */ 75 void stop(); 76 77 /** 78 * Posts an event to a nanoapp that is currently running (or all nanoapps if 79 * the broadcast instance ID is used). 80 * 81 * @param The type of data being posted. 82 * @param The data being posted. 83 * @param The callback to invoke when the event is no longer needed. 84 * @param The instance ID of the sender of this event. 85 * @param The instance ID of the destination of this event. 86 * 87 * TODO: this is safe to call from other threads, and posts to the incoming 88 * event queue, then it is doled out to interested nanoapp queues later 89 */ 90 void postEvent(uint16_t eventType, void *eventData, 91 chreEventCompleteFunction *freeCallback, 92 uint32_t senderInstanceId = kSystemInstanceId, 93 uint32_t targetInstanceId = kBroadcastInstanceId); 94 95 // TODO: static method that allocates + constructs + posts an Event to all 96 // EventLoops (i.e. just the one for now), to simplify external code that will 97 // call this (they don't need to worry about how events are allocated, etc) 98 99 // TODO: do we need this? it might be a helpful convenience function that 100 // handles creation of a timer and stuff 101 void postEventDelayed(Event *event, uint64_t delayNs); 102 103 /** 104 * Returns a pointer to the currently executing Nanoapp, or nullptr if none is 105 * currently executing. 106 * 107 * @return a pointer to the currently executing nanoapp and nullptr if not 108 * currently in an app context. 109 */ 110 const Nanoapp *getCurrentNanoapp() const; 111 112 /** 113 * Returns a guaranteed unique instance ID that can be used to construct a 114 * nanoapp. 115 * 116 * @return a unique instance ID to assign to a nanoapp. 117 */ 118 uint32_t getNextInstanceId(); 119 120 /** 121 * Obtains the TimerPool associated with this event loop. 122 * 123 * @return The timer pool owned by this event loop. 124 */ 125 TimerPool& getTimerPool(); 126 127 private: 128 //! The maximum number of events that can be active in the system. 129 static constexpr size_t kMaxEventCount = 1024; 130 131 //! The instance ID that was previously generated by getNextInstanceId. 132 uint32_t mLastInstanceId = kSystemInstanceId; 133 134 //! The memory pool to allocate incoming events from. 135 SynchronizedMemoryPool<Event, kMaxEventCount> mEventPool; 136 137 //! The timer used schedule timed events for tasks running in this event loop. 138 TimerPool mTimerPool; 139 140 //! The list of nanoapps managed by this event loop. 141 DynamicVector<Nanoapp*> mNanoapps; 142 143 //! The blocking queue of incoming events from the system that have not been 144 //! distributed out to apps yet. 145 FixedSizeBlockingQueue<Event*, kMaxUnscheduledEventCount> mEvents; 146 147 // TODO: we probably want our own atomic platform abstraction too 148 std::atomic<bool> mRunning{false}; 149 150 Nanoapp *mCurrentApp = nullptr; 151 152 void freeEvent(Event *event); 153 Nanoapp *lookupAppByInstanceId(uint32_t instanceId); 154 155 // TODO: we probably want a to model kSystemInstanceId as an actual nanoapp 156 // with entry points and all that to make it simpler to post events to ourself 157 // and the like... 158}; 159 160} // namespace chre 161 162#endif // CHRE_CORE_EVENT_LOOP_H_ 163