event_loop.h revision 4927ee586656424c827920876673228fbdcf27c3
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#include <vector> 23e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 24e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie#include "chre/core/event.h" 25e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie#include "chre/core/nanoapp.h" 26e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie#include "chre/util/blocking_queue.h" 274927ee586656424c827920876673228fbdcf27c3Andrew Rossignol#include "chre/util/memory_pool.h" 28e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie#include "chre/util/non_copyable.h" 29e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 30e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddienamespace chre { 31e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 32e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie/** 33e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * TODO: document this better 34e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie */ 35e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddieclass EventLoop : public NonCopyable { 36e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie public: 37e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie // TODO: need a clear delineation for which methods are safe to call from 38e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie // threads other than the one calling run()... should include stop() and 39e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie // postEvent()... everything else would decidedly be not thread-safe 40e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 41e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie /** 42e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * Starts a nanoapp by invoking the start entry point. If this is successful, 43e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * the app is managed by the event loop and the pointer passed in must remain 44e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * valid. 45e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * 46e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * @param A pointer to the nanoapp to start. 47e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * @return True if the app was started successfully. 48e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie */ 49e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie bool startNanoapp(Nanoapp *nanoapp); 50e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 51e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie /** 52e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * Stops a nanoapp by invoking the stop entry point. The nanoapp passed in 53e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * must have been previously started by the startNanoapp method. 54e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * 55e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * @param A pointer to the nanoapp to stop. 56e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie */ 57e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie void stopNanoapp(Nanoapp *nanoapp); 58e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 59e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie /** 60e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * Start the main task run loop. Only returns after stop() is called 61e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * (from another context). 62e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie */ 63e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie void run(); 64e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 65e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie /** 66e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * Signals the event loop currently executing in run() to exit gracefully at 67e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * the next available opportunity. 68e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie */ 69e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie void stop(); 70e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 714927ee586656424c827920876673228fbdcf27c3Andrew Rossignol /** 724927ee586656424c827920876673228fbdcf27c3Andrew Rossignol * Posts an event to a nanoapp that is currently running (or all nanoapps if 734927ee586656424c827920876673228fbdcf27c3Andrew Rossignol * the broadcast instance ID is used). 744927ee586656424c827920876673228fbdcf27c3Andrew Rossignol * 754927ee586656424c827920876673228fbdcf27c3Andrew Rossignol * @param The type of data being posted. 764927ee586656424c827920876673228fbdcf27c3Andrew Rossignol * @param The data being posted. 774927ee586656424c827920876673228fbdcf27c3Andrew Rossignol * @param The callback to invoke when the event is no longer needed. 784927ee586656424c827920876673228fbdcf27c3Andrew Rossignol * @param The instance ID of the sender of this event. 794927ee586656424c827920876673228fbdcf27c3Andrew Rossignol * @param The instance ID of the destination of this event. 804927ee586656424c827920876673228fbdcf27c3Andrew Rossignol * 814927ee586656424c827920876673228fbdcf27c3Andrew Rossignol * TODO: this is safe to call from other threads, and posts to the incoming 824927ee586656424c827920876673228fbdcf27c3Andrew Rossignol * event queue, then it is doled out to interested nanoapp queues later 834927ee586656424c827920876673228fbdcf27c3Andrew Rossignol */ 844927ee586656424c827920876673228fbdcf27c3Andrew Rossignol void postEvent(uint16_t eventType, void *eventData, 854927ee586656424c827920876673228fbdcf27c3Andrew Rossignol chreEventCompleteFunction *freeCallback, 864927ee586656424c827920876673228fbdcf27c3Andrew Rossignol uint32_t senderInstanceId = kSystemInstanceId, 874927ee586656424c827920876673228fbdcf27c3Andrew Rossignol uint32_t targetInstanceId = kBroadcastInstanceId); 88e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 89e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie // TODO: static method that allocates + constructs + posts an Event to all 90e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie // EventLoops (i.e. just the one for now), to simplify external code that will 91e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie // call this (they don't need to worry about how events are allocated, etc) 92e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 93e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie // TODO: do we need this? it might be a helpful convenience function that 94e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie // handles creation of a timer and stuff 95e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie void postEventDelayed(Event *event, uint64_t delayNs); 96e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 97e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie /** 98e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * Returns a pointer to the currently executing Nanoapp, or nullptr if none is 99e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * currently executing. 100e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * 101e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * @return a pointer to the currently executing nanoapp and nullptr if not 102e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * currently in an app context. 103e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie */ 104e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie const Nanoapp *getCurrentNanoapp() const; 105e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 106e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie /** 107e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * Returns a guaranteed unique instance ID that can be used to construct a 108e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * nanoapp. 109e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * 110e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * @return a unique instance ID to assign to a nanoapp. 111e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie */ 112e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie uint32_t getNextInstanceId(); 113e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 114e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie private: 1154927ee586656424c827920876673228fbdcf27c3Andrew Rossignol //! The maximum number of events that can be active in the system. 1164927ee586656424c827920876673228fbdcf27c3Andrew Rossignol static constexpr size_t kMaxEventCount = 1024; 1174927ee586656424c827920876673228fbdcf27c3Andrew Rossignol 118e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie //! The instance ID that was previously generated by getNextInstanceId. 119e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie uint32_t mLastInstanceId = kSystemInstanceId; 120e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 1214927ee586656424c827920876673228fbdcf27c3Andrew Rossignol //! The memory pool to allocate incoming events from. 1224927ee586656424c827920876673228fbdcf27c3Andrew Rossignol MemoryPool<Event, kMaxEventCount> mEventPool; 1234927ee586656424c827920876673228fbdcf27c3Andrew Rossignol 124e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie // TODO: replace STL use with our own data structures 125e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie std::vector<Nanoapp*> mNanoapps; 126e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie BlockingQueue<Event*> mEvents; 127e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 128e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie // TODO: we probably want our own atomic platform abstraction too 129e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie std::atomic<bool> mRunning{false}; 130e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 131e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie Nanoapp *mCurrentApp = nullptr; 132e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 133e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie void freeEvent(Event *event); 134e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie Nanoapp *lookupAppByInstanceId(uint32_t instanceId); 135e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 136e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie // TODO: we probably want a to model kSystemInstanceId as an actual nanoapp 137e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie // with entry points and all that to make it simpler to post events to ourself 138e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie // and the like... 139e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie}; 140e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 141e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie} // namespace chre 142e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 143e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie#endif // CHRE_CORE_EVENT_LOOP_H_ 144