You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
150 lines
5.3 KiB
150 lines
5.3 KiB
#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;
|
|
|
|
/// <summary>
|
|
/// WatchOS kernel providing the supervisor that makes it all go
|
|
/// </summary>
|
|
class Kernel
|
|
{
|
|
private:
|
|
/// <summary>
|
|
/// Holds the accounting of all handles the kernel has allocated
|
|
/// </summary>
|
|
KernelHandle* m_handle[KERNEL_MAX_HANDLES];
|
|
/// <summary>
|
|
/// Id of the next handle to allocate
|
|
/// </summary>
|
|
int m_next_handle = 1;
|
|
/// <summary>
|
|
/// Holds a reference and metadata for every task registered with the kernel
|
|
/// </summary>
|
|
KernelTask* m_task[KERNEL_MAX_TASKS];
|
|
/// <summary>
|
|
/// Holds a reference and metadata for every event subscription
|
|
/// </summary>
|
|
KernelEventSubscription* m_event_subscription[KERNEL_MAX_EVENT_SUBSCRIPTIONS];
|
|
|
|
/// <summary>
|
|
/// Perform the actual actions to free a handle
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// Calls the destructor (if set), and removes it from the kernel's internal tracking
|
|
/// </remarks>
|
|
/// <param name="handle">handle to free</param>
|
|
void freeHandle(kernel_handle_t handle);
|
|
|
|
public:
|
|
Kernel();
|
|
|
|
/// <summary>
|
|
/// Initialize the kernel on first boot and notify tasks to do the same
|
|
/// </summary>
|
|
void initialize();
|
|
/// <summary>
|
|
/// Have all tasks perform startup after booting
|
|
/// </summary>
|
|
void start();
|
|
/// <summary>
|
|
/// Notify all tasks and the kernel to prepare for deep sleep by saving any state
|
|
/// required to persistent storage.
|
|
/// </summary>
|
|
void suspend();
|
|
|
|
/// <summary>
|
|
/// Create a new kernel handle pointing to an object
|
|
/// </summary>
|
|
/// <param name="type">type of the handle, one of WATCHOS_HANDLE_TYPE_ consts</param>
|
|
/// <param name="object">pointer to the object this handle references</param>
|
|
/// <param name="destructor">function to call when this handle has released all references</param>
|
|
/// <param name="well_known">specify a 'well_known' value this pointer can be fetched by</param>
|
|
/// <returns>a handle which can be used to fetch or release this object</returns>
|
|
kernel_handle_t allocHandle(byte type, void* object, kernel_handle_destructor_t destructor = nullptr, uint32_t well_known = 0);
|
|
|
|
/// <summary>
|
|
/// Fetch the object referenced by this handle
|
|
/// </summary>
|
|
/// <param name="handle">handle to fetch</param>
|
|
/// <returns>a pointer to the object the handle references</returns>
|
|
void* getHandle(kernel_handle_t handle);
|
|
|
|
/// <summary>
|
|
/// Increase the reference count of a handle
|
|
/// </summary>
|
|
/// <param name="handle">handle to increase reference count on</param>
|
|
void useHandle(kernel_handle_t handle);
|
|
|
|
/// <summary>
|
|
/// Decrease the reference count of a handle
|
|
/// </summary>
|
|
/// <param name="handle">handle to decrease reference count on</param>
|
|
void releaseHandle(kernel_handle_t handle);
|
|
|
|
/// <summary>
|
|
/// Fetch the handle associated with a "well known" handle
|
|
/// </summary>
|
|
/// <param name="handle">a well known handle we're trying to locate</param>
|
|
/// <returns>the kernel handle of the well known object</returns>
|
|
kernel_handle_t getHandleForWellKnown(well_known_handle_t handle);
|
|
|
|
/// <summary>
|
|
/// Register a new task with the kernel
|
|
/// </summary>
|
|
/// <param name="task">task implementation to register</param>
|
|
/// <param name="wk_handle">optionally, register this as a well known object</param>
|
|
/// <returns>the handle of the registered task</returns>
|
|
kernel_handle_t registerTask(Task* task, well_known_handle_t wk_handle = WATCHOS_HANDLE_NULL);
|
|
/// <summary>
|
|
/// Unregisters a task with the kernel
|
|
/// </summary>
|
|
/// <param name="task">task implementation to unregister</param>
|
|
void unregisterTask(Task* task);
|
|
|
|
/// <summary>
|
|
/// Push an event to all relevant subscribers
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// 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.
|
|
/// </remarks>
|
|
/// <param name="source">handle of the sender</param>
|
|
/// <param name="event">id of the event; what the event means</param>
|
|
/// <param name="param1">event-defined data</param>
|
|
/// <param name="param2">event-defined data</param>
|
|
void pushEvent(well_known_handle_t source, uint16_t event, byte param1, byte param2);
|
|
|
|
/// <summary>
|
|
/// Subscribe a listener to an event
|
|
/// </summary>
|
|
/// <param name="listener">listener that should receive events</param>
|
|
/// <param name="source_mask">a bitmask of the event sources that we want to receive</param>
|
|
/// <param name="event_mask">a bitmask of the event types that we want to receive</param>
|
|
/// <returns>a handle to the subscription</returns>
|
|
kernel_handle_t subscribeEvent(EventListener* listener, well_known_handle_t source_mask, uint16_t event_mask);
|
|
/// <summary>
|
|
/// Remove an event subscription
|
|
/// </summary>
|
|
/// <param name="subscription">the subscription to remove</param>
|
|
void unsubscribeEvent(KernelEventSubscription* subscription);
|
|
|
|
/// <summary>
|
|
/// Have the kernel and any runnable tasks do processing
|
|
/// </summary>
|
|
void tick();
|
|
};
|
|
|
|
#endif
|
|
|
|
|