Subversion Repositories Kolibri OS

Rev

Rev 2465 | Rev 3725 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2465 Rev 3555
Line 1... Line 1...
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
2
;;                                                              ;;
3
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;;
3
;; Copyright (C) KolibriOS team 2004-2010. 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
;;                                                              ;;
7
;;                                                              ;;
7
;;  QUEUE.INC                                                   ;;
8
;;    Written by hidnplayr@kolibrios.org                        ;;
8
;;                                                              ;;
9
;;                                                              ;;
9
;;  Buffer queue management for Menuet OS TCP/IP Stack          ;;
-
 
10
;;                                                              ;;
10
;;          GNU GENERAL PUBLIC LICENSE                          ;;
11
;;  Copyright 2002 Mike Hibbett, mikeh@oceanfree.net            ;;
-
 
12
;;                                                              ;;
11
;;             Version 2, June 1991                             ;;
13
;;  See file COPYING for details                                ;;
-
 
14
;;                                                              ;;
12
;;                                                              ;;
15
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
13
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Line 16... Line 14...
16
 
14
 
17
$Revision: 2465 $
-
 
Line 18... Line -...
18
 
-
 
19
 
-
 
20
;*******************************************************************
-
 
21
;   Interface
-
 
22
;
-
 
23
;       queueInit   Configures the queues to empty
-
 
24
;       dequeue     Removes a buffer pointer from a queue
-
 
25
;       queue       Inserts a buffer pointer into a queue
15
$Revision: 3555 $
26
;       freeBuff    Adds the buffer pointer to the list of free buffers
-
 
27
;       queueSize   Returns the number of entries in a queue
16
 
28
;
17
; The Queues implemented by these macros form a ring-buffer.
-
 
18
; The data to these queue's always looks like this:
29
;      The various defines for queue names can be found in stack.inc
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.
Line 30... Line -...
30
;
-
 
31
;*******************************************************************
-
 
32
 
-
 
33
 
-
 
34
;***************************************************************************
-
 
35
;   Function
-
 
36
;      freeBuff
-
 
37
;
-
 
38
;   Description
-
 
39
;       Adds a buffer number to the beginning of the free list.
-
 
40
;       buffer number in eax  ( ms word zeroed )
-
 
41
;       all other registers preserved
-
 
42
;        This always works, so no error returned
-
 
43
;***************************************************************************
-
 
44
;uglobal
-
 
45
;  freeBuff_cnt dd ?
-
 
46
;endg
-
 
47
freeBuff:
-
 
48
;        inc     [freeBuff_cnt]
-
 
49
;        DEBUGF  1, "K : freeBuff (%u)\n", [freeBuff_cnt]
-
 
50
        push    ebx
-
 
51
        push    ecx
-
 
52
        mov     ebx, queues + EMPTY_QUEUE * 2
-
 
53
        cli     ; Ensure that another process does not interfer
-
 
54
        mov     cx, [ebx]
-
 
55
        mov     [ebx], ax
-
 
56
        mov     [queueList + eax * 2], cx
-
 
57
        sti
-
 
58
        pop     ecx
-
 
59
        pop     ebx
-
 
60
 
-
 
61
        ret
-
 
62
 
-
 
63
 
-
 
64
;***************************************************************************
-
 
65
;   Function
-
 
66
;      queueSize
-
 
67
;
-
 
68
;   Description
-
 
69
;       Counts the number of entries in a queue
-
 
70
;       queue number in ebx ( ms word zeroed )
-
 
71
;       Queue size returned in eax
-
 
72
;    This always works, so no error returned
-
 
73
;***************************************************************************
-
 
74
queueSize:
-
 
75
        xor     eax, eax
-
 
76
        shl     ebx, 1
-
 
77
        add     ebx, queues
-
 
78
        movzx   ecx, word [ebx]
-
 
79
        cmp     cx, NO_BUFFER
-
 
80
        je      qs_exit
-
 
81
 
-
 
82
qs_001:
-
 
83
        inc     eax
-
 
84
        shl     ecx, 1
-
 
85
        add     ecx, queueList
-
 
86
        movzx   ecx, word [ecx]
-
 
87
        cmp     cx, NO_BUFFER
-
 
88
        je      qs_exit
-
 
89
        jmp     qs_001
-
 
90
 
-
 
91
qs_exit:
-
 
92
        ret
-
 
93
 
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.
94
 
-
 
95
;***************************************************************************
-
 
96
;   Function
-
 
97
;      queue
-
 
98
;
-
 
99
;   Description
-
 
100
;       Adds a buffer number to the *end* of a queue
-
 
101
;       This is quite quick because these queues will be short
-
 
102
;       queue number in eax ( ms word zeroed )
-
 
103
;       buffer number in ebx  ( ms word zeroed )
-
 
104
;       all other registers preserved
-
 
105
;        This always works, so no error returned
-
 
106
;***************************************************************************
-
 
107
;uglobal
-
 
108
;  queue_cnt dd ?
-
 
109
;endg
-
 
110
queue:
-
 
111
;        inc     [queue_cnt]
-
 
112
;        DEBUGF  1, "K : queue (%u)\n", [queue_cnt]
-
 
113
        push    ebx
-
 
114
        shl     ebx, 1
-
 
115
        add     ebx, queueList    ; eax now holds address of queue entry
-
 
116
        mov     [ebx], word NO_BUFFER; This buffer will be the last
-
 
117
 
-
 
118
        cli
-
 
119
        shl     eax, 1
-
 
120
        add     eax, queues        ; eax now holds address of queue
-
 
121
        movzx   ebx, word [eax]
-
 
122
 
-
 
123
        cmp     bx, NO_BUFFER
-
 
124
        jne     qu_001
-
 
125
 
-
 
126
        pop     ebx
-
 
127
    ; The list is empty, so add this to the head
-
 
128
        mov     [eax], bx
-
 
129
        jmp     qu_exit
-
 
130
 
-
 
131
qu_001:
-
 
132
    ; Find the last entry
-
 
133
        shl     ebx, 1
-
 
134
        add     ebx, queueList
-
 
135
        mov     eax, ebx
-
 
136
        movzx   ebx, word [ebx]
-
 
137
        cmp     bx, NO_BUFFER
-
 
138
        jne     qu_001
-
 
139
 
-
 
140
        mov     ebx, eax
-
 
141
        pop     eax
-
 
142
        mov     [ebx], ax
-
 
Line -... Line 23...
-
 
23
; (you can see some examples below)
-
 
24
 
-
 
25
 
Line -... Line 26...
-
 
26
struct	queue
Line 143... Line -...
143
 
-
 
144
qu_exit:
-
 
145
        sti
27
 
146
        ret
28
	size	       dd ?    ; number of queued packets in this queue
147
 
-
 
148
 
29
	w_ptr	       dd ?    ; current writing pointer in queue
149
 
30
	r_ptr	       dd ?    ; current reading pointer
150
;***************************************************************************
31
 
151
;   Function
32
ends
152
;      dequeue
-
 
153
;
33
 
154
;   Description
34
; The following macros share these inputs:
155
;       removes a buffer number from the head of a queue
-
 
156
;       This is fast, as it unlinks the first entry in the list
-
 
157
;       queue number in eax ( ms word zeroed )
-
 
158
;       buffer number returned in eax ( ms word zeroed )
-
 
159
;       all other registers preserved
-
 
160
;
-
 
161
;***************************************************************************
35
 
162
;uglobal
36
; ptr           = pointer to where the queue data is located
163
;  dequeue_cnt dd ?
37
; size          = number of slots/entrys in the queue
164
;endg
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
165
dequeue:
40
 
166
        push    ebx
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
167
        shl     eax, 1
43
; PS: macros WILL destroy ecx and edi
-
 
44
 
168
        add     eax, queues        ; eax now holds address of queue
45
macro add_to_queue ptr, size, entry_size, failaddr {
169
        mov     ebx, eax
46
 
170
        cli
47
	cmp	[ptr + queue.size], size	; Check if queue isnt full
-
 
48
	jae	failaddr
171
        movzx   eax, word [eax]
49
 
172
        cmp     ax, NO_BUFFER
50
	inc	[ptr + queue.size]		; if not full, queue one more
173
        je      dq_exit
51
 
-
 
52
	mov	edi, [ptr + queue.w_ptr]	; Current write pointer (FIFO!)
174
;        inc     [dequeue_cnt]
53
	mov	ecx, entry_size/4		; Write the queue entry
175
;        DEBUGF  1, "K : dequeue (%u)\n", [dequeue_cnt]
54
	rep	movsd				;
176
        push    eax
-
 
177
        shl     eax, 1
55
 
178
        add     eax, queueList    ; eax now holds address of queue entry
56
	lea	ecx, [size*entry_size+ptr+sizeof.queue]
-
 
57
	cmp	edi, ecx			; entry size
179
        mov     ax, [eax]
58
	jb	.no_wrap
-
 
59
 
180
        mov     [ebx], ax
60
	sub	edi, size*entry_size
181
        pop     eax
61
 
182
 
62
  .no_wrap:
183
dq_exit:
-
 
184
        sti
-
 
185
        pop     ebx
63
	mov	[ptr + queue.w_ptr], edi
186
        ret
-
 
187
 
64
 
188
 
65
}
189
;***************************************************************************
66
 
190
;   Function
-
 
191
;      queueInit
-
 
192
;
67
 
193
;   Description
-
 
194
;       Initialises the queues to empty, and creates the free queue
-
 
195
;       list.
68
 
196
;
-
 
197
;***************************************************************************
69
macro get_from_queue ptr, size, entry_size,  failaddr {
198
queueInit:
70
 
-
 
71
	cmp	[ptr + queue.size], 0		; any packets queued?
199
        mov     esi, queues
72
	je	failaddr
200
        mov     ecx, NUMQUEUES
-
 
201
        mov     ax, NO_BUFFER
73
 
202
 
74
	dec	[ptr + queue.size]		; if so, dequeue one
-
 
75
 
-
 
76
	mov	esi, [ptr + queue.r_ptr]
203
qi001:
77
	push	esi
204
        mov     [esi], ax
78
 
205
        inc     esi
79
	add	esi, entry_size
206
        inc     esi
80
 
207
        loop    qi001
81
	lea	ecx, [size*entry_size+ptr+sizeof.queue]
208
 
82
	cmp	esi, ecx			; entry size
209
        mov     esi, queues + ( 2 * EMPTY_QUEUE )
-
 
210
 
83
	jb	.no_wrap
211
    ; Initialise empty queue list
84
 
212
 
85
	sub	esi, size*entry_size
213
        xor     ax, ax
-
 
214
        mov     [esi], ax
-
 
215
 
-
 
216
        mov     ecx, NUMQUEUEENTRIES - 1
-
 
217
        mov     esi, queueList
-
 
Line 218... Line -...
218
 
-
 
219
qi002:
86
 
Line -... Line 87...
-
 
87
  .no_wrap:
-
 
88
	mov	dword [ptr + queue.r_ptr], esi
-
 
89
 
220
        inc     ax
90
	pop	esi
-
 
91
 
221
        mov     [esi], ax
92
}