Subversion Repositories Kolibri OS

Rev

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

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