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