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