Subversion Repositories Kolibri OS

Rev

Rev 1514 | Blame | Last modification | View Log | Download | RSS feed

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                              ;;
  3. ;; Copyright (C) KolibriOS team 2004-2010. All rights reserved. ;;
  4. ;; Distributed under terms of the GNU General Public License    ;;
  5. ;;                                                              ;;
  6. ;;  queue.inc                                                   ;;
  7. ;;                                                              ;;
  8. ;;    Written by hidnplayr@kolibrios.org                        ;;
  9. ;;                                                              ;;
  10. ;;          GNU GENERAL PUBLIC LICENSE                          ;;
  11. ;;             Version 2, June 1991                             ;;
  12. ;;                                                              ;;
  13. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  14.  
  15. $Revision: 1543 $
  16.  
  17. ; The Queues implemented by these macros form a ring-buffer.
  18. ; The data to these queue's always looks like this:
  19. ;
  20. ; At top, you have the queue struct, wich has the size (number of currently queued packets, read and write pointers.
  21. ; This struct is followed by a number of slots wich you can read and write to using the macros.
  22. ; How these slots look like is up to you to chose, normally they should have at least a pointer to where the real data is.
  23. ; (you can see some examples below)
  24.  
  25.  
  26. struct  queue
  27.         .size           dd ?    ; number of queued packets in this queue
  28.         .w_ptr          dd ?    ; current writing pointer in queue
  29.         .r_ptr          dd ?    ; current reading pointer
  30.         .data:
  31. ends
  32.  
  33. ; The following macros share these inputs:
  34.  
  35. ; ptr           = pointer to where the queue data is located
  36. ; size          = number of slots/entrys in the queue
  37. ; entry_size    = size of one slot, in bytes
  38. ; failaddr      = the address where macro will jump to when there is no data in the queue
  39.  
  40. ; additionally, add_to_queue requires you to set esi to the data wich you want to queue
  41. ; get_from_queue on the other hand will return a pointer in esi, to the entry you're interessed in
  42. ; PS: macros WILL destroy ecx and edi
  43.  
  44. macro add_to_queue ptr, size, entry_size, failaddr {
  45.  
  46.         cmp     [ptr + queue.size], size        ; Check if queue isnt full
  47.         jge     failaddr
  48.  
  49.         inc     [ptr + queue.size]              ; if not full, queue one more
  50.  
  51.         mov     edi, [ptr + queue.w_ptr]        ; Current write pointer (FIFO!)
  52.         mov     ecx, entry_size/4               ; Write the queue entry
  53.         rep     movsd                           ;
  54.  
  55.         lea     ecx, [size*entry_size+ptr+queue.data]
  56.         cmp     edi, ecx                        ; entry size
  57.         jl      .no_wrap
  58.  
  59.         sub     edi, size*entry_size
  60.  
  61.   .no_wrap:
  62.         mov     [ptr + queue.w_ptr], edi
  63.  
  64. }
  65.  
  66.  
  67.  
  68. macro get_from_queue ptr, size, entry_size,  failaddr {
  69.  
  70.         cmp     [ptr + queue.size], 0           ; any packets queued?
  71.         je      failaddr
  72.  
  73.         dec     [ptr + queue.size]              ; if so, dequeue one
  74.  
  75.         mov     esi, [ptr + queue.r_ptr]
  76.         push    esi
  77.  
  78.         add     esi, entry_size
  79.  
  80.         lea     ecx, [size*entry_size+ptr+queue.data]
  81.         cmp     esi, ecx                        ; entry size
  82.         jl      .no_wrap
  83.  
  84.         sub     esi, size*entry_size
  85.  
  86.   .no_wrap:
  87.         mov     dword [ptr + queue.r_ptr], esi
  88.  
  89.         pop     esi
  90.  
  91. }
  92.  
  93. macro init_queue ptr {
  94.  
  95.         mov     [ptr + queue.size] , 0
  96.         lea     edi, [ptr + queue.data]
  97.         mov     [ptr + queue.w_ptr], edi
  98.         mov     [ptr + queue.r_ptr], edi
  99. }