Subversion Repositories Kolibri OS

Rev

Rev 7136 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  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.
  179.         Waiting thread is frozen by setting TASKDATA.state <= TSTATE_WAITING=5.
  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.
  196.         Waiting thread is frozen by setting TASKDATA.state <= TSTATE_WAITING=5.
  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
  215.         frozen by setting TASKDATA.state <= TSTATE_WAITING = 5. Event data
  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
  235.         frozen by setting TASKDATA.state <= TSTATE_WAITING = 5. Event data
  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
  249.