1#pragma once
  2
  3#include <time.h>
  4
  5#include <pw_types.h>
  6
  7#ifdef __cplusplus
  8extern "C" {
  9#endif
 10
 11typedef bool (*_PmFunc)();
 12/*
 13 * _PmFunc is an uninterruptible unit of PetCode.
 14 */
 15
 16#define _PM_INITIAL_CS_PAGE_SIZE     64
 17#define _PM_MAXIMAL_CS_PAGE_SIZE  16384
 18#define _PM_INITIAL_DS_PAGE_SIZE    256
 19#define _PM_MAXIMAL_DS_PAGE_SIZE  16384
 20/*
 21 * Sizes for stack pages.
 22 *
 23 * The size doubles for the next page until it reaches max page size.
 24 */
 25
 26PW_STRUCT(_PwDataStackPage) {
 27    _PwDataStackPage* prev;
 28    _PwDataStackPage* next;
 29    uint16_t block_size;
 30    uint16_t capacity;
 31    uint16_t count;
 32    _PwValue items[];
 33};
 34
 35PW_STRUCT(_PwControlStackPage) {
 36    _PwControlStackPage* prev;
 37    _PwControlStackPage* next;
 38    uint16_t block_size;
 39    uint16_t capacity;
 40    uint16_t count;
 41    _PmFunc* items[];
 42};
 43
 44typedef enum PwTaskState {
 45    PW_TASK_STATE_ACTIVE = 0,
 46    PW_TASK_STATE_SUSPENDED,
 47    PW_TASK_STATE_TERMINATED
 48} PwTaskState;
 49
 50PW_STRUCT(PwTaskList) {
 51    PwTask* next;
 52    PwTask* prev;
 53};
 54
 55PW_STRUCT(PwTask) {
 56
 57    // task hierarchy
 58    PwTask* parent;       // points to the parent task; nullptr for the root task
 59    PwTask* children;     // points to a child task
 60    PwTaskList sibling;   // the list of siblings
 61
 62    // task may be either on run or wakeup list; which list the task_list refers to depends on task state
 63    PwTaskList task_list;
 64
 65    PwTaskList wait_list; // the list of tasks awaiting this task
 66
 67    _PwValue blocker;     // a synchronization object the task is blocked on
 68    PwValuePtr parent_blocker;  // if `blocker` is an instance of Task or ChldTasks, this is a link to a compound blocker
 69    /*
 70
 71    kinda special wait objects:
 72
 73    void pw_make_task_syncobj(PwTask* task, PwValuePtr result);
 74    -- makes a synchronization object from task that can be awaited for termination; no alloc, never fails
 75
 76    void pw_make_children_tasks_syncobj(PwTask* task, PwValuePtr result);
 77    -- makes a synchronization object that can be awaited for children termination; no alloc, never fails
 78
 79    special wait objects cannot participate in multiple awaitables
 80    because they have no link to parent awaitable -- fuck, add this link!
 81
 82    General sync objects:
 83
 84    It's a PwValue, a subtype of Struct, with allocated memory block.
 85    It contains wait_list
 86
 87    */
 88
 89    unsigned refcount;
 90    /*
 91     * The number of PwValues of Task type referencing this structure plus one, which means self.
 92     * Except self, this does not count other internal references, such as siblings or run lists.
 93     *
 94     * The value is not atomic because tasks are bound to a single thread.
 95     */
 96
 97    PwTaskState state;
 98    bool hold_exception;  // do not propagate exception to the parent; propagation is enabled when parent enters `try` block
 99    struct timespec wakeup_time;  // when to wake up if the task is suspended; zero means infinite timeout
100
101    _PmFunc* ip;  // instruction pointer
102
103    _PwDataStackPage* data_stack;
104    /*
105     * current page of the data stack
106     *
107     * The data stack is allocated in a relatively small blocks of fixed size,
108     * organized in a doubly-linked list using values of Pointer type.
109     * The first element is a pointer to the previous block,
110     * when the block is full, the last element is a pointer to the next block
111     */
112
113    _PwControlStackPage* control_stack;
114    /*
115     * current page of the control stack
116     *
117     * the allocation scheme is the same as for the data stack
118     */
119
120    /*
121     * stats/profiling?
122     */
123    /*
124    unsigned abs_data_sp;      // current absolute value of the data stack pointer
125    unsigned max_abs_data_sp;  // max absolute value of the data stack pointer
126    unsigned abs_control_sp;      // current absolute value of the control stack pointer
127    unsigned max_abs_control_sp;  // max absolute value of the control stack pointer
128    */
129
130    _PwValue status;
131};
132
133extern PwTask _pw_default_task;
134extern thread_local PwTask* current_task;
135
136#ifdef __cplusplus
137}
138#endif