Subversion Repositories Kolibri OS

Rev

Rev 6908 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
3545 hidnplayr 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
10051 ace_dent 3
;; Copyright (C) KolibriOS team 2004-2024. All rights reserved. ;;
3545 hidnplayr 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
 
16
; The Queues implemented by these macros form a ring-buffer.
17
; The data to these queue's always looks like this:
18
;
19
; At top, you have the queue struct, wich has the size (number of currently queued packets, read and write pointers.
20
; This struct is followed by a number of slots wich you can read and write to using the macros.
21
; 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.
22
; (you can see some examples below)
23
 
24
 
3698 hidnplayr 25
struct  queue
3545 hidnplayr 26
 
3698 hidnplayr 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
3545 hidnplayr 30
 
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
 
3698 hidnplayr 46
local .ok, .no_wrap
3545 hidnplayr 47
 
4510 hidnplayr 48
        spin_lock_irqsave
3545 hidnplayr 49
 
3698 hidnplayr 50
        cmp     [ptr + queue.size], size        ; Check if queue isnt full
51
        jb      .ok
6908 ashmew2 52
 
4510 hidnplayr 53
        spin_unlock_irqrestore
3698 hidnplayr 54
        jmp     failaddr
3545 hidnplayr 55
 
3698 hidnplayr 56
  .ok:
57
        inc     [ptr + queue.size]              ; if not full, queue one more
3545 hidnplayr 58
 
3698 hidnplayr 59
        mov     edi, [ptr + queue.w_ptr]        ; Current write pointer (FIFO!)
60
        mov     ecx, entry_size/4               ; Write the queue entry
3711 clevermous 61
        rep movsd                               ;
3698 hidnplayr 62
 
63
        lea     ecx, [size*entry_size+ptr+sizeof.queue]
64
        cmp     edi, ecx                        ; entry size
65
        jb      .no_wrap
66
 
67
        sub     edi, size*entry_size
3545 hidnplayr 68
  .no_wrap:
3698 hidnplayr 69
        mov     [ptr + queue.w_ptr], edi
3545 hidnplayr 70
 
4510 hidnplayr 71
        spin_unlock_irqrestore
3698 hidnplayr 72
 
3545 hidnplayr 73
}
74
 
75
 
76
 
77
macro get_from_queue ptr, size, entry_size,  failaddr {
78
 
3698 hidnplayr 79
local .ok, .no_wrap
3545 hidnplayr 80
 
4510 hidnplayr 81
        spin_lock_irqsave
3545 hidnplayr 82
 
3698 hidnplayr 83
        cmp     [ptr + queue.size], 0           ; any packets queued?
84
        ja      .ok
3545 hidnplayr 85
 
4510 hidnplayr 86
        spin_unlock_irqrestore
3698 hidnplayr 87
        jmp     failaddr
3545 hidnplayr 88
 
3698 hidnplayr 89
  .ok:
90
        dec     [ptr + queue.size]              ; if so, dequeue one
3545 hidnplayr 91
 
3698 hidnplayr 92
        mov     esi, [ptr + queue.r_ptr]
93
        push    esi
3545 hidnplayr 94
 
3698 hidnplayr 95
        add     esi, entry_size
96
 
97
        lea     ecx, [size*entry_size+ptr+sizeof.queue]
98
        cmp     esi, ecx                        ; entry size
99
        jb      .no_wrap
100
 
101
        sub     esi, size*entry_size
102
 
3545 hidnplayr 103
  .no_wrap:
3698 hidnplayr 104
        mov     dword [ptr + queue.r_ptr], esi
3545 hidnplayr 105
 
3698 hidnplayr 106
        pop     esi
3545 hidnplayr 107
 
4510 hidnplayr 108
        spin_unlock_irqrestore
3698 hidnplayr 109
 
3545 hidnplayr 110
}
111
 
112
macro init_queue ptr {
113
 
3698 hidnplayr 114
        mov     [ptr + queue.size] , 0
115
        lea     edi, [ptr + sizeof.queue]
116
        mov     [ptr + queue.w_ptr], edi
117
        mov     [ptr + queue.r_ptr], edi
118
 
10051 ace_dent 119
}