Subversion Repositories Kolibri OS

Rev

Rev 6907 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 6907 Rev 6908
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
2
;;                                                              ;;
3
;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;;
3
;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;;
4
;; Distributed under terms of the GNU General Public License    ;;
4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
5
;;                                                              ;;
6
;;  queue.inc                                                   ;;
6
;;  queue.inc                                                   ;;
7
;;                                                              ;;
7
;;                                                              ;;
8
;;    Written by hidnplayr@kolibrios.org                        ;;
8
;;    Written by hidnplayr@kolibrios.org                        ;;
9
;;                                                              ;;
9
;;                                                              ;;
10
;;          GNU GENERAL PUBLIC LICENSE                          ;;
10
;;          GNU GENERAL PUBLIC LICENSE                          ;;
11
;;             Version 2, June 1991                             ;;
11
;;             Version 2, June 1991                             ;;
12
;;                                                              ;;
12
;;                                                              ;;
13
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
13
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
14
 
14
 
15
$Revision: 6907 $
15
$Revision: 6908 $
16
 
16
 
17
; The Queues implemented by these macros form a ring-buffer.
17
; The Queues implemented by these macros form a ring-buffer.
18
; The data to these queue's always looks like this:
18
; The data to these queue's always looks like this:
19
;
19
;
20
; At top, you have the queue struct, wich has the size (number of currently queued packets, read and write pointers.
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.
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.
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)
23
; (you can see some examples below)
24
 
24
 
25
 
25
 
26
struct  queue
26
struct  queue
27
 
27
 
28
        size            dd ?    ; number of queued packets in this queue
28
        size            dd ?    ; number of queued packets in this queue
29
        w_ptr           dd ?    ; current writing pointer in queue
29
        w_ptr           dd ?    ; current writing pointer in queue
30
        r_ptr           dd ?    ; current reading pointer
30
        r_ptr           dd ?    ; current reading pointer
31
 
31
 
32
ends
32
ends
33
 
33
 
34
; The following macros share these inputs:
34
; The following macros share these inputs:
35
 
35
 
36
; ptr           = pointer to where the queue data is located
36
; ptr           = pointer to where the queue data is located
37
; size          = number of slots/entrys in the queue
37
; size          = number of slots/entrys in the queue
38
; entry_size    = size of one slot, in bytes
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
39
; failaddr      = the address where macro will jump to when there is no data in the queue
40
 
40
 
41
; additionally, add_to_queue requires you to set esi to the data wich you want to queue
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
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
43
; PS: macros WILL destroy ecx and edi
44
 
44
 
45
macro add_to_queue ptr, size, entry_size, failaddr {
45
macro add_to_queue ptr, size, entry_size, failaddr {
46
 
46
 
47
local .ok, .no_wrap
47
local .ok, .no_wrap
48
 
48
 
49
        spin_lock_irqsave
49
        spin_lock_irqsave
50
 
50
 
51
        cmp     [ptr + queue.size], size        ; Check if queue isnt full
51
        cmp     [ptr + queue.size], size        ; Check if queue isnt full
52
        jb      .ok
52
        jb      .ok
53
        DEBUGF  1, "--- Queue is FULL!\n"
-
 
-
 
53
 
54
        spin_unlock_irqrestore
54
        spin_unlock_irqrestore
55
        jmp     failaddr
55
        jmp     failaddr
56
 
56
 
57
  .ok:
57
  .ok:
58
        inc     [ptr + queue.size]              ; if not full, queue one more
58
        inc     [ptr + queue.size]              ; if not full, queue one more
59
 
59
 
60
        mov     edi, [ptr + queue.w_ptr]        ; Current write pointer (FIFO!)
60
        mov     edi, [ptr + queue.w_ptr]        ; Current write pointer (FIFO!)
61
        mov     ecx, entry_size/4               ; Write the queue entry
61
        mov     ecx, entry_size/4               ; Write the queue entry
62
        rep movsd                               ;
62
        rep movsd                               ;
63
 
63
 
64
        lea     ecx, [size*entry_size+ptr+sizeof.queue]
64
        lea     ecx, [size*entry_size+ptr+sizeof.queue]
65
        cmp     edi, ecx                        ; entry size
65
        cmp     edi, ecx                        ; entry size
66
        jb      .no_wrap
66
        jb      .no_wrap
67
 
67
 
68
        sub     edi, size*entry_size
68
        sub     edi, size*entry_size
69
  .no_wrap:
69
  .no_wrap:
70
        mov     [ptr + queue.w_ptr], edi
70
        mov     [ptr + queue.w_ptr], edi
71
 
71
 
72
        spin_unlock_irqrestore
72
        spin_unlock_irqrestore
73
 
73
 
74
}
74
}
75
 
75
 
76
 
76
 
77
 
77
 
78
macro get_from_queue ptr, size, entry_size,  failaddr {
78
macro get_from_queue ptr, size, entry_size,  failaddr {
79
 
79
 
80
local .ok, .no_wrap
80
local .ok, .no_wrap
81
 
81
 
82
        spin_lock_irqsave
82
        spin_lock_irqsave
83
 
83
 
84
        cmp     [ptr + queue.size], 0           ; any packets queued?
84
        cmp     [ptr + queue.size], 0           ; any packets queued?
85
        ja      .ok
85
        ja      .ok
86
 
86
 
87
        spin_unlock_irqrestore
87
        spin_unlock_irqrestore
88
        jmp     failaddr
88
        jmp     failaddr
89
 
89
 
90
  .ok:
90
  .ok:
91
        dec     [ptr + queue.size]              ; if so, dequeue one
91
        dec     [ptr + queue.size]              ; if so, dequeue one
92
 
92
 
93
        mov     esi, [ptr + queue.r_ptr]
93
        mov     esi, [ptr + queue.r_ptr]
94
        push    esi
94
        push    esi
95
 
95
 
96
        add     esi, entry_size
96
        add     esi, entry_size
97
 
97
 
98
        lea     ecx, [size*entry_size+ptr+sizeof.queue]
98
        lea     ecx, [size*entry_size+ptr+sizeof.queue]
99
        cmp     esi, ecx                        ; entry size
99
        cmp     esi, ecx                        ; entry size
100
        jb      .no_wrap
100
        jb      .no_wrap
101
 
101
 
102
        sub     esi, size*entry_size
102
        sub     esi, size*entry_size
103
 
103
 
104
  .no_wrap:
104
  .no_wrap:
105
        mov     dword [ptr + queue.r_ptr], esi
105
        mov     dword [ptr + queue.r_ptr], esi
106
 
106
 
107
        pop     esi
107
        pop     esi
108
 
108
 
109
        spin_unlock_irqrestore
109
        spin_unlock_irqrestore
110
 
110
 
111
}
111
}
112
 
112
 
113
macro init_queue ptr {
113
macro init_queue ptr {
114
 
114
 
115
        mov     [ptr + queue.size] , 0
115
        mov     [ptr + queue.size] , 0
116
        lea     edi, [ptr + sizeof.queue]
116
        lea     edi, [ptr + sizeof.queue]
117
        mov     [ptr + queue.w_ptr], edi
117
        mov     [ptr + queue.w_ptr], edi
118
        mov     [ptr + queue.r_ptr], edi
118
        mov     [ptr + queue.r_ptr], edi
119
 
119
 
120
}
120
}