Rev 7587 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
7587 | dunkaist | 1 | Last edit: 26/07/2013 |
2 | |||
3 | Kernel event subsystem may be useful when writing drivers and kernel space |
||
4 | services. It is not related to the subsystem of GUI events. An event, from the |
||
5 | kernel's point of view, is a kernel space object which is owned by the thread |
||
6 | that created it. |
||
7 | |||
8 | struc EVENT |
||
9 | { |
||
10 | .magic dd ? ; 'EVNT' |
||
11 | .destroy dd ? ; internal destructor |
||
12 | .fd dd ? ; next object in list |
||
13 | .bk dd ? ; prev object in list |
||
14 | .pid dd ? ; owner (thread) id |
||
15 | .id dd ? ; event uid. (just a number) |
||
16 | .state dd ? ; internal flags; see below |
||
17 | .code dd ? ; MSB: event class; next byte: priority |
||
18 | ; (used by kernel only, always 0 for reading), |
||
19 | ; The higher dword value the higher event priority. |
||
20 | ; Two LSBs: event code. |
||
21 | rd 5 ; .data: the structure of this field is not defined and |
||
22 | ; depends on .code field. (Pass any data you need here) |
||
23 | .size = $ - .magic |
||
24 | .codesize = $ - .code |
||
25 | } |
||
26 | |||
27 | Realtime events have class 0хFF. Currently defined: |
||
28 | EVENT.code= ; (Used in sound subsystem) |
||
29 | RT_INP_EMPTY = 0xFF000001 |
||
30 | RT_OUT_EMPTY = 0xFF000002 |
||
31 | RT_INP_FULL = 0xFF000003 |
||
32 | RT_OUT_FULL = 0xFF000004 |
||
33 | |||
34 | |||
35 | Flags of EVENT.state field are defined in gui/event.inc. |
||
36 | EVENT_SIGNALED = 0x20000000 ; bit 29: event is active/inactive |
||
37 | EVENT_WATCHED = 0x10000000 ; bit 28: owner thread is waiting for the |
||
38 | ; event to be active |
||
39 | MANUAL_RESET = 0x40000000 ; bit 30: do not deactivate event |
||
40 | : automatically on receive |
||
41 | MANUAL_DESTROY = 0x80000000 ; bit 31: do not return event to a list of |
||
42 | ; free ones on receive |
||
43 | |||
44 | As of SVN r3732 (assume same below) the definition is located in |
||
45 | /kernel/trunk/const.inc and is as follows: |
||
46 | |||
47 | struct APPOBJ ; common object header |
||
48 | magic dd ? ; |
||
49 | destroy dd ? ; internal destructor |
||
50 | fd dd ? ; next object in list |
||
51 | bk dd ? ; prev object in list |
||
52 | pid dd ? ; owner id |
||
53 | ends |
||
54 | |||
55 | struct EVENT APPOBJ |
||
56 | id dd ? ; event uid |
||
57 | state dd ? ; internal flags |
||
58 | code dd ? |
||
59 | rd 5 ; .data |
||
60 | ends |
||
61 | |||
62 | Code is located in gui/event.inc. |
||
63 | Event objects live in kernel memory as a double-linked list (see fields .bk and |
||
64 | .fd). While initialization the kernel reserves memory, creates 512 events and |
||
65 | places them into FreeEvents list. When out of free event, kernel creates another |
||
66 | 512 ones etc. Each thread has own double-linked lists where an event may be |
||
67 | placed to: |
||
68 | ObjList -- a list of kernel objects associated with the thread; |
||
69 | EventList -- a list of kernel events for the thread. |
||
70 | When events are moved between lists or reordered their data are not copied. This |
||
71 | is done only via modification of .fd and .bk fields. These lists work as FIFO |
||
72 | queues. Sending does not block, receiving blocks. Addressing is direct, by |
||
73 | thread id. There always is an owner thread for an event. |
||
74 | |||
75 | Event's life cycle is defined by flags while creation. By default the kernel |
||
76 | uses values MANUAL_RESET = 0 and MANUAL_DESTROY = 0. Such an event is oneshot |
||
77 | and is automatically freed by the kernel and returned to the FreeEvents list |
||
78 | when received. An event with flag MANUAL_DESTROY = 1 becomes inactive when |
||
79 | received but remains in thread's object list and can be reused. An event with |
||
80 | flags MANUAL_DESTROY = 1 and MANUAL_RESET = 1 remains active when received and |
||
81 | can be reset via call to ClearEvent. |
||
82 | |||
83 | A life cycle example of a sound subsystem event: |
||
84 | * For an audio buffer (possibly several) the driver creates an event in ObjList |
||
85 | by calling CreateEvent with flag MANUAL_DESTROY. |
||
86 | * Then driver calls WaitEvent for the event (waits for EVENT_SIGNALED event |
||
87 | flag) and blocks waiting for buffer update request. |
||
88 | * The buffer update request is sent with RaiseEvent from another thread. |
||
89 | * Sending (RaiseEvent) and receiving (WaitEvent) are repeated as buffer gets |
||
90 | empty. |
||
91 | * Driver deactivates the event with ClearEvent when playback is stopped. |
||
92 | |||
93 | Actually, the event structure is described here only for understanding of |
||
94 | subsystem work principles. Direct field access is discouraged due to possible |
||
95 | compatibility issues in the future. Only API calls should be used. A pair |
||
96 | "pointer to an event" and "event id" is considered a single 64-bit id. This id |
||
97 | should be stored somewhere after a call to CreateEvent for further work with the |
||
98 | event. |
||
99 | |||
100 | The kernel exports following event related functions: |
||
101 | (for drivers, etc; called from kernel mode) |
||
102 | |||
103 | CreateEvent |
||
104 | RaiseEvent |
||
105 | ClearEvent |
||
106 | SendEvent |
||
107 | DestroyEvent |
||
108 | WaitEvent |
||
109 | WaitEventTimeout |
||
110 | GetEvent |
||
111 | For user applications sysfn 68.14 (a wrapper to GetEvent) |
||
112 | |||
113 | -------------------------------------------------------------------------------- |
||
114 | CreateEvent: |
||
115 | Creates a new event in ObjList queue of current thread. |
||
116 | Sets: |
||
117 | EVENT.destroy <= default internal destructor |
||
118 | EVENT.pid <= current Process id |
||
119 | EVENT.id <= unique id |
||
120 | EVENT.state <= ecx: flags |
||
121 | EVENT.code <= [esi]: size is 6*dword, do not copy if esi=0 |
||
122 | Returns: |
||
123 | eax -- pointer to the event or 0 for error. |
||
124 | edx -- Event.id. |
||
125 | Destroys: eax,ebx,edx,ecx,esi,edi |
||
126 | -------------------------------------------------------------------------------- |
||
127 | RaiseEvent: |
||
128 | Activates existing event (may be owned by another thread) by setting |
||
129 | EVENT_SIGNALED flag. Sets EVENT.code data if necessary. Does nothing |
||
130 | more if EVENT_SIGNALED flag is already active in the event. If |
||
131 | EVENT_SIGNALED flag is not set in the event it will be set, except when |
||
132 | EVENT_WATCHED in edx = 1 and EVENT_WATCHED in the event = 0. I.e. while |
||
133 | setting EVENT_WATCHED in edx it is checked if owner thread is waiting |
||
134 | for event activation. No flags, except EVENT_SIGNALED, are modified in |
||
135 | the event. |
||
136 | Gets: |
||
137 | eax -- pointer to event |
||
138 | ebx -- id |
||
139 | edx -- flags (see EVENT.state) |
||
140 | Sets: |
||
141 | EVENT.code <= [esi]: size is 6*dword, do not copy if esi=0 |
||
142 | Returns: ? |
||
143 | Destroys: eax,ebx,edx,ecx,esi,edi |
||
144 | -------------------------------------------------------------------------------- |
||
145 | ClearEvent: |
||
146 | Move event to ObjList of owner thread. (May be it was already there.) |
||
147 | Reset flags EVENT_SIGNALED and EVENT_WATCHED, keep other fields (.code, |
||
148 | .id). |
||
149 | Gets: |
||
150 | eax -- pointer to event |
||
151 | ebx -- id |
||
152 | Returns: ? |
||
153 | Destroys: eax,ebx,ecx,edi |
||
154 | -------------------------------------------------------------------------------- |
||
155 | SendEvent: |
||
156 | Create a new event in the event list of target thread. Sets |
||
157 | EVENT_SIGNALED flag in the event. |
||
158 | Gets: |
||
159 | EVENT.pid <= eax: target thread id; |
||
160 | EVENT.code <= [esi]: size is 6*dword, do not copy if esi=0 |
||
161 | Returns: |
||
162 | eax -- pointer to event or 0 for error |
||
163 | edx -- Event.id |
||
164 | Destroys: eax,ebx,ecx,esi,edi |
||
165 | -------------------------------------------------------------------------------- |
||
166 | DestroyEvent: |
||
167 | Moves event to FreeEvents, clears fields .magic, .destroy, .pid, .id. |
||
168 | The event may be owned by other thread. |
||
169 | Gets: |
||
170 | eax -- pointer to event |
||
171 | ebx -- event id |
||
172 | Returns: |
||
173 | eax -- 0 for error, non-zero for success |
||
174 | Destroy: eax,ebx,ecx |
||
175 | -------------------------------------------------------------------------------- |
||
176 | WaitEvent: |
||
177 | Wait infinitely until flag EVENT_SIGNALED is set in the event owned by |
||
178 | the caller thread. This flag is set by signaling thread via RaiseEvent. |
||
9715 | Doczom | 179 | Waiting thread is frozen by setting APPDATA.state <= TSTATE_WAITING=5. |
7587 | dunkaist | 180 | Flag EVENT_WATCHED is set in the event before freeze. |
181 | If flag MANUAL_RESET is NOT set in the event then: |
||
182 | EVENT_SIGNALED and EVENT_WATCHED are reset when the event is |
||
183 | received. |
||
184 | When MANUAL_DESTROY is |
||
185 | inactive: the event is destroyed by DestroyEvent, |
||
186 | active: the event is moved to ObjList of current thread. |
||
187 | Gets: |
||
188 | eax -- pointer to event |
||
189 | ebx -- event id |
||
190 | Returns: ? |
||
191 | Destroys: eax,ebx,edx,ecx,esi,edi |
||
192 | -------------------------------------------------------------------------------- |
||
193 | WaitEventTimeout: |
||
194 | Wait with a timeout until flag EVENT_SIGNALED is set in the event owned |
||
195 | by caller thread. This flag is set by signaling thread via RaiseEvent. |
||
9715 | Doczom | 196 | Waiting thread is frozen by setting APPDATA.state <= TSTATE_WAITING=5. |
7587 | dunkaist | 197 | Flag EVENT_WATCHED is set in the event before freeze. |
198 | If flag MANUAL_RESET is NOT set in the event then: |
||
199 | EVENT_SIGNALED and EVENT_WATCHED are reset when the event is |
||
200 | received. |
||
201 | When MANUAL_DESTROY is |
||
202 | inactive: the event is destroyed by DestroyEvent, |
||
203 | active: the event is moved to ObjList of current thread. |
||
204 | Gets: |
||
205 | eax -- pointer to event |
||
206 | ebx -- event id |
||
207 | ecx -- timeout, in ticks of system timer |
||
208 | Returns: |
||
209 | eax -- 0 if the event was not activated, or |
||
210 | not 0 if activated |
||
211 | Destroys: eax,ebx,edx,ecx,esi,edi |
||
212 | -------------------------------------------------------------------------------- |
||
213 | GetEvent: |
||
214 | Waits infinitely for any event in the queue of current thread. Thread is |
||
9715 | Doczom | 215 | frozen by setting APPDATA.state <= TSTATE_WAITING = 5. Event data |
7587 | dunkaist | 216 | (EVENT.code + 5*dword) are copied to specified buffer when received. |
217 | Reset priority byte (see above) in the buffer. |
||
218 | If flag MANUAL_RESET is NOT set in the event then: |
||
219 | EVENT_SIGNALED and EVENT_WATCHED are reset when the event is |
||
220 | received. |
||
221 | When MANUAL_DESTROY is |
||
222 | inactive: the event is destroyed by DestroyEvent, |
||
223 | active: the event is moved to ObjList of current thread. |
||
224 | Gets: |
||
225 | edi -- pointer to buffer to copy data |
||
226 | Returns: |
||
227 | buffer with following data: |
||
228 | +0: (EVENT.code) dword: id of following signal data |
||
229 | +4: (EVENT.data) 5*dword: signal data, format depends on |
||
230 | EVENT.code |
||
231 | Destroys: eax,ebx,edx,ecx,esi,edi |
||
232 | -------------------------------------------------------------------------------- |
||
233 | SysFn 68.14 for application: ; wrapped GetEvent |
||
234 | Waits infinitely for any event in the queue of current thread. Thread is |
||
9715 | Doczom | 235 | frozen by setting APPDATA.state <= TSTATE_WAITING = 5. Event data |
7587 | dunkaist | 236 | (EVENT.code + 5*dword) are copied to specified buffer when received. |
237 | Reset priority byte (see above) in the buffer. |
||
238 | Gets: |
||
239 | eax -- 68: function number |
||
240 | ebx -- 14: subfunction number |
||
241 | ecx -- pointer to data buffer (size is 6*dword) |
||
242 | Returns: |
||
243 | ecx = buffer with following data: |
||
244 | +0: (EVENT.code) dword: id of following signal data |
||
245 | +4: (EVENT.data) 5*dword: signal data, format depends on |
||
246 | EVENT.code |
||
247 | Destroys: |
||
248 | eax=>=>=>=>=>=>=>=>=>=>=>=> |