Subversion Repositories Kolibri OS

Rev

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

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                              ;;
  3. ;; Copyright (C) KolibriOS team 2004-2015. 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: 6908 $
  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.  
  28.         size            dd ?    ; number of queued packets in this queue
  29.         w_ptr           dd ?    ; current writing pointer in queue
  30.         r_ptr           dd ?    ; current reading pointer
  31.  
  32. ends
  33.  
  34. ; The following macros share these inputs:
  35.  
  36. ; ptr           = pointer to where the queue data is located
  37. ; size          = number of slots/entrys in the queue
  38. ; entry_size    = size of one slot, in bytes
  39. ; failaddr      = the address where macro will jump to when there is no data in the queue
  40.  
  41. ; additionally, add_to_queue requires you to set esi to the data wich you want to queue
  42. ; get_from_queue on the other hand will return a pointer in esi, to the entry you're interessed in
  43. ; PS: macros WILL destroy ecx and edi
  44.  
  45. macro add_to_queue ptr, size, entry_size, failaddr {
  46.  
  47. local .ok, .no_wrap
  48.  
  49.         spin_lock_irqsave
  50.  
  51.         cmp     [ptr + queue.size], size        ; Check if queue isnt full
  52.         jb      .ok
  53.  
  54.         spin_unlock_irqrestore
  55.         jmp     failaddr
  56.  
  57.   .ok:
  58.         inc     [ptr + queue.size]              ; if not full, queue one more
  59.  
  60.         mov     edi, [ptr + queue.w_ptr]        ; Current write pointer (FIFO!)
  61.         mov     ecx, entry_size/4               ; Write the queue entry
  62.         rep movsd                               ;
  63.  
  64.         lea     ecx, [size*entry_size+ptr+sizeof.queue]
  65.         cmp     edi, ecx                        ; entry size
  66.         jb      .no_wrap
  67.  
  68.         sub     edi, size*entry_size
  69.   .no_wrap:
  70.         mov     [ptr + queue.w_ptr], edi
  71.  
  72.         spin_unlock_irqrestore
  73.  
  74. }
  75.  
  76.  
  77.  
  78. macro get_from_queue ptr, size, entry_size,  failaddr {
  79.  
  80. local .ok, .no_wrap
  81.  
  82.         spin_lock_irqsave
  83.  
  84.         cmp     [ptr + queue.size], 0           ; any packets queued?
  85.         ja      .ok
  86.  
  87.         spin_unlock_irqrestore
  88.         jmp     failaddr
  89.  
  90.   .ok:
  91.         dec     [ptr + queue.size]              ; if so, dequeue one
  92.  
  93.         mov     esi, [ptr + queue.r_ptr]
  94.         push    esi
  95.  
  96.         add     esi, entry_size
  97.  
  98.         lea     ecx, [size*entry_size+ptr+sizeof.queue]
  99.         cmp     esi, ecx                        ; entry size
  100.         jb      .no_wrap
  101.  
  102.         sub     esi, size*entry_size
  103.  
  104.   .no_wrap:
  105.         mov     dword [ptr + queue.r_ptr], esi
  106.  
  107.         pop     esi
  108.  
  109.         spin_unlock_irqrestore
  110.  
  111. }
  112.  
  113. macro init_queue ptr {
  114.  
  115.         mov     [ptr + queue.size] , 0
  116.         lea     edi, [ptr + sizeof.queue]
  117.         mov     [ptr + queue.w_ptr], edi
  118.         mov     [ptr + queue.r_ptr], edi
  119.  
  120. }