Optimizes run_once(_safe) (XCC)
[akaros.git] / kern / include / ros / event.h
1 /* Copyright (c) 2010-2011 The Regents of the University of California
2  * Barret Rhoden <brho@cs.berkeley.edu>
3  * See LICENSE for details.
4  *
5  * Kernel interface for event/notification delivery and preemption. */
6
7 #ifndef ROS_INC_EVENT_H
8 #define ROS_INC_EVENT_H
9
10 #include <ros/common.h>
11 #include <ros/atomic.h>
12 #include <ros/arch/trapframe.h>
13 /* #include <ros/ucq.h> included below */
14
15 /* Event Delivery Flags from the process to the kernel */
16 #define EVENT_IPI                               0x001   /* IPI the vcore (usually with INDIR) */
17 #define EVENT_NOMSG                             0x002   /* just send the bit, not the msg */
18 #define EVENT_SPAM_PUBLIC               0x004   /* spam the msg to public vcpd mboxes */
19 #define EVENT_INDIR                             0x008   /* send an indirection event to vcore */
20 #define EVENT_VCORE_PRIVATE             0x010   /* Will go to the private VCPD mbox */
21 /* Delivery style flags */
22 #define EVENT_FALLBACK                  0x020   /* spam INDIRs if the vcore's offline */
23 #define EVENT_VCORE_MUST_RUN    0x040   /* Alerts go to a vcore that will run */
24 #define EVENT_NOTHROTTLE                0x080   /* send all INDIRs (no throttling) */
25 /* Not seriously used flags */
26 #define EVENT_ROUNDROBIN                0x100   /* pick a vcore, RR style */
27 #define EVENT_VCORE_APPRO               0x200   /* send to where the kernel wants */
28
29 /* Flags from the program to the 2LS */
30 #define EVENT_JUSTHANDLEIT              0x400   /* 2LS should handle the ev_q */
31 #define EVENT_THREAD                    0x800   /* spawn thread to handle ev_q */
32
33 /* Certain event flags apply to spam/fallback messages */
34 #define EVENT_SPAM_FLAGS                (EVENT_IPI | EVENT_VCORE_MUST_RUN)
35
36 /* Event Message Types */
37 #define EV_NONE                                  0
38 #define EV_PREEMPT_PENDING               1
39 #define EV_GANG_PREMPT_PENDING   2
40 #define EV_VCORE_PREEMPT                 3
41 #define EV_GANG_RETURN                   4
42 #define EV_USER_IPI                              5
43 #define EV_PAGE_FAULT                    6
44 #define EV_ALARM                                 7
45 #define EV_EVENT                                 8
46 #define EV_FREE_APPLE_PIE                9
47 #define EV_SYSCALL                              10
48 #define EV_CHECK_MSGS                   11
49 #define EV_POSIX_SIGNAL                 12
50 #define NR_EVENT_TYPES                  25 /* keep me last (and 1 > the last one) */
51
52 /* Will probably have dynamic notifications later */
53 #define MAX_NR_DYN_EVENT                25
54 #define MAX_NR_EVENT                    (NR_EVENT_TYPES + MAX_NR_DYN_EVENT)
55
56 /* Want to keep this small and generic, but add items as you need them.  One
57  * item some will need is an expiration time, which ought to be put in the 64
58  * bit arg.  Will need tweaking / thought as we come up with events.  These are
59  * what get put on the per-core queue in procdata. */
60 struct event_msg {
61         uint16_t                                        ev_type;
62         uint16_t                                        ev_arg1;
63         uint32_t                                        ev_arg2;
64         void                                            *ev_arg3;
65         uint64_t                                        ev_arg4;
66 };
67
68 /* Including here since ucq.h needs to know about struct event_msg */
69 #include <ros/ucq.h>
70
71 /* Structure for storing / receiving event messages.  An overflow causes the
72  * bit of the event to get set in the bitmap.  You can also have just the bit
73  * sent (and no message). */
74 struct event_mbox {
75         struct ucq                                      ev_msgs;
76         bool                                            ev_check_bits;
77         uint8_t                                         ev_bitmap[(MAX_NR_EVENT - 1) / 8 + 1];
78 };
79
80 /* The kernel sends messages to this structure, which describes how and where
81  * to receive messages, including optional IPIs. */
82 struct event_queue {
83         struct event_mbox                       *ev_mbox;
84         int                                                     ev_flags;
85         bool                                            ev_alert_pending;
86         uint32_t                                        ev_vcore;
87         void                                            (*ev_handler)(struct event_queue *);
88 };
89
90 /* Big version, contains storage space for the ev_mbox.  Never access the
91  * internal mbox directly. */
92 struct event_queue_big {
93         struct event_mbox                       *ev_mbox;
94         int                                                     ev_flags;
95         bool                                            ev_alert_pending;
96         uint32_t                                        ev_vcore;
97         void                                            (*ev_handler)(struct event_queue *);
98         struct event_mbox                       ev_imbox;
99 };
100
101 /* Vcore state flags.  K_LOCK means the kernel is writing */
102 #define VC_K_LOCK                               0x001                           /* CASing with the kernel */
103 #define VC_PREEMPTED                    0x002                           /* VC is preempted */
104 #define VC_CAN_RCV_MSG                  0x004                           /* can receive FALLBACK */
105 #define VC_UTHREAD_STEALING             0x008                           /* Uthread being stolen */
106 #define VC_SCP_NOVCCTX                  0x010                           /* can't go into vc ctx */
107
108 /* Per-core data about preemptions and notifications */
109 struct preempt_data {
110         struct user_trapframe           preempt_tf;                     /* slot for vcore ctx */
111         struct ancillary_state          preempt_anc;
112         struct user_trapframe           notif_tf;                       /* slot for uthread ctx */
113         uintptr_t                                       transition_stack;       /* advertised by the user */
114         atomic_t                                        flags;
115         bool                                            notif_disabled;         /* vcore unwilling to recv*/
116         bool                                            notif_pending;          /* notif k_msg on the way */
117         struct event_mbox                       ev_mbox_public;         /* can be read remotely */
118         struct event_mbox                       ev_mbox_private;        /* for this vcore only */
119 };
120
121 #endif /* ROS_INC_EVENT_H */