#ifndef _KERNEL_h #define _KERNEL_h #include "Task.h" #include "EventListener.h" #define KERNEL_MAX_HANDLES 256 #define KERNEL_MAX_TASKS 32 #define KERNEL_MAX_EVENT_SUBSCRIPTIONS 64 typedef void (*kernel_handle_destructor_t)(kernel_handle_t, void*); struct KernelHandle; struct KernelTask; struct KernelEventSubscription; /// /// WatchOS kernel providing the supervisor that makes it all go /// class Kernel { private: /// /// Holds the accounting of all handles the kernel has allocated /// KernelHandle* m_handle[KERNEL_MAX_HANDLES]; /// /// Id of the next handle to allocate /// int m_next_handle = 1; /// /// Holds a reference and metadata for every task registered with the kernel /// KernelTask* m_task[KERNEL_MAX_TASKS]; /// /// Holds a reference and metadata for every event subscription /// KernelEventSubscription* m_event_subscription[KERNEL_MAX_EVENT_SUBSCRIPTIONS]; /// /// Perform the actual actions to free a handle /// /// /// Calls the destructor (if set), and removes it from the kernel's internal tracking /// /// handle to free void freeHandle(kernel_handle_t handle); public: Kernel(); /// /// Initialize the kernel on first boot and notify tasks to do the same /// void initialize(); /// /// Have all tasks perform startup after booting /// void start(); /// /// Notify all tasks and the kernel to prepare for deep sleep by saving any state /// required to persistent storage. /// void suspend(); /// /// Create a new kernel handle pointing to an object /// /// type of the handle, one of WATCHOS_HANDLE_TYPE_ consts /// pointer to the object this handle references /// function to call when this handle has released all references /// specify a 'well_known' value this pointer can be fetched by /// a handle which can be used to fetch or release this object kernel_handle_t allocHandle(byte type, void* object, kernel_handle_destructor_t destructor = nullptr, uint32_t well_known = 0); /// /// Fetch the object referenced by this handle /// /// handle to fetch /// a pointer to the object the handle references void* getHandle(kernel_handle_t handle); /// /// Increase the reference count of a handle /// /// handle to increase reference count on void useHandle(kernel_handle_t handle); /// /// Decrease the reference count of a handle /// /// handle to decrease reference count on void releaseHandle(kernel_handle_t handle); /// /// Fetch the handle associated with a "well known" handle /// /// a well known handle we're trying to locate /// the kernel handle of the well known object kernel_handle_t getHandleForWellKnown(well_known_handle_t handle); /// /// Register a new task with the kernel /// /// task implementation to register /// optionally, register this as a well known object /// the handle of the registered task kernel_handle_t registerTask(Task* task, well_known_handle_t wk_handle = WATCHOS_HANDLE_NULL); /// /// Unregisters a task with the kernel /// /// task implementation to unregister void unregisterTask(Task* task); /// /// Push an event to all relevant subscribers /// /// /// This will look through all subscriptions and see which subscriptions' masks are /// set to receive events of this source/type, and push the event through to the /// applicable listeners. /// /// handle of the sender /// id of the event; what the event means /// event-defined data /// event-defined data void pushEvent(well_known_handle_t source, uint16_t event, byte param1, byte param2); /// /// Subscribe a listener to an event /// /// listener that should receive events /// a bitmask of the event sources that we want to receive /// a bitmask of the event types that we want to receive /// a handle to the subscription kernel_handle_t subscribeEvent(EventListener* listener, well_known_handle_t source_mask, uint16_t event_mask); /// /// Remove an event subscription /// /// the subscription to remove void unsubscribeEvent(KernelEventSubscription* subscription); /// /// Have the kernel and any runnable tasks do processing /// void tick(); }; #endif