Subversion Repositories Kolibri OS

Compare Revisions

No changes between revisions

Regard whitespace Rev 3544 → Rev 3545

/kernel/trunk/network/queue.inc
1,229 → 1,100
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2004-2010. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; queue.inc ;;
;; ;;
;; QUEUE.INC ;;
;; Written by hidnplayr@kolibrios.org ;;
;; ;;
;; Buffer queue management for Menuet OS TCP/IP Stack ;;
;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;;
;; ;;
;; Copyright 2002 Mike Hibbett, mikeh@oceanfree.net ;;
;; ;;
;; See file COPYING for details ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
$Revision: 2305 $
 
 
;*******************************************************************
; Interface
; The Queues implemented by these macros form a ring-buffer.
; The data to these queue's always looks like this:
;
; queueInit Configures the queues to empty
; dequeue Removes a buffer pointer from a queue
; queue Inserts a buffer pointer into a queue
; freeBuff Adds the buffer pointer to the list of free buffers
; queueSize Returns the number of entries in a queue
;
; The various defines for queue names can be found in stack.inc
;
;*******************************************************************
; At top, you have the queue struct, wich has the size (number of currently queued packets, read and write pointers.
; This struct is followed by a number of slots wich you can read and write to using the macros.
; 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.
; (you can see some examples below)
 
 
;***************************************************************************
; Function
; freeBuff
;
; Description
; Adds a buffer number to the beginning of the free list.
; buffer number in eax ( ms word zeroed )
; all other registers preserved
; This always works, so no error returned
;***************************************************************************
;uglobal
; freeBuff_cnt dd ?
;endg
freeBuff:
; inc [freeBuff_cnt]
; DEBUGF 1, "K : freeBuff (%u)\n", [freeBuff_cnt]
push ebx
push ecx
mov ebx, queues + EMPTY_QUEUE * 2
cli ; Ensure that another process does not interfer
mov cx, [ebx]
mov [ebx], ax
mov [queueList + eax * 2], cx
sti
pop ecx
pop ebx
struct queue
 
ret
size dd ? ; number of queued packets in this queue
w_ptr dd ? ; current writing pointer in queue
r_ptr dd ? ; current reading pointer
 
ends
 
;***************************************************************************
; Function
; queueSize
;
; Description
; Counts the number of entries in a queue
; queue number in ebx ( ms word zeroed )
; Queue size returned in eax
; This always works, so no error returned
;***************************************************************************
queueSize:
xor eax, eax
shl ebx, 1
add ebx, queues
movzx ecx, word [ebx]
cmp cx, NO_BUFFER
je qs_exit
; The following macros share these inputs:
 
qs_001:
inc eax
shl ecx, 1
add ecx, queueList
movzx ecx, word [ecx]
cmp cx, NO_BUFFER
je qs_exit
jmp qs_001
; ptr = pointer to where the queue data is located
; size = number of slots/entrys in the queue
; entry_size = size of one slot, in bytes
; failaddr = the address where macro will jump to when there is no data in the queue
 
qs_exit:
ret
; additionally, add_to_queue requires you to set esi to the data wich you want to queue
; get_from_queue on the other hand will return a pointer in esi, to the entry you're interessed in
; PS: macros WILL destroy ecx and edi
 
macro add_to_queue ptr, size, entry_size, failaddr {
 
;***************************************************************************
; Function
; queue
;
; Description
; Adds a buffer number to the *end* of a queue
; This is quite quick because these queues will be short
; queue number in eax ( ms word zeroed )
; buffer number in ebx ( ms word zeroed )
; all other registers preserved
; This always works, so no error returned
;***************************************************************************
;uglobal
; queue_cnt dd ?
;endg
queue:
; inc [queue_cnt]
; DEBUGF 1, "K : queue (%u)\n", [queue_cnt]
push ebx
shl ebx, 1
add ebx, queueList ; eax now holds address of queue entry
mov [ebx], word NO_BUFFER; This buffer will be the last
cmp [ptr + queue.size], size ; Check if queue isnt full
jae failaddr
 
cli
shl eax, 1
add eax, queues ; eax now holds address of queue
movzx ebx, word [eax]
inc [ptr + queue.size] ; if not full, queue one more
 
cmp bx, NO_BUFFER
jne qu_001
mov edi, [ptr + queue.w_ptr] ; Current write pointer (FIFO!)
mov ecx, entry_size/4 ; Write the queue entry
rep movsd ;
 
pop ebx
; The list is empty, so add this to the head
mov [eax], bx
jmp qu_exit
lea ecx, [size*entry_size+ptr+sizeof.queue]
cmp edi, ecx ; entry size
jb .no_wrap
 
qu_001:
; Find the last entry
shl ebx, 1
add ebx, queueList
mov eax, ebx
movzx ebx, word [ebx]
cmp bx, NO_BUFFER
jne qu_001
sub edi, size*entry_size
 
mov ebx, eax
pop eax
mov [ebx], ax
.no_wrap:
mov [ptr + queue.w_ptr], edi
 
qu_exit:
sti
ret
}
 
 
 
;***************************************************************************
; Function
; dequeue
;
; Description
; removes a buffer number from the head of a queue
; This is fast, as it unlinks the first entry in the list
; queue number in eax ( ms word zeroed )
; buffer number returned in eax ( ms word zeroed )
; all other registers preserved
;
;***************************************************************************
;uglobal
; dequeue_cnt dd ?
;endg
dequeue:
push ebx
shl eax, 1
add eax, queues ; eax now holds address of queue
mov ebx, eax
cli
movzx eax, word [eax]
cmp ax, NO_BUFFER
je dq_exit
; inc [dequeue_cnt]
; DEBUGF 1, "K : dequeue (%u)\n", [dequeue_cnt]
push eax
shl eax, 1
add eax, queueList ; eax now holds address of queue entry
mov ax, [eax]
mov [ebx], ax
pop eax
macro get_from_queue ptr, size, entry_size, failaddr {
 
dq_exit:
sti
pop ebx
ret
cmp [ptr + queue.size], 0 ; any packets queued?
je failaddr
 
dec [ptr + queue.size] ; if so, dequeue one
 
;***************************************************************************
; Function
; queueInit
;
; Description
; Initialises the queues to empty, and creates the free queue
; list.
;
;***************************************************************************
queueInit:
mov esi, queues
mov ecx, NUMQUEUES
mov ax, NO_BUFFER
mov esi, [ptr + queue.r_ptr]
push esi
 
qi001:
mov [esi], ax
inc esi
inc esi
loop qi001
add esi, entry_size
 
mov esi, queues + ( 2 * EMPTY_QUEUE )
lea ecx, [size*entry_size+ptr+sizeof.queue]
cmp esi, ecx ; entry size
jb .no_wrap
 
; Initialise empty queue list
sub esi, size*entry_size
 
xor ax, ax
mov [esi], ax
.no_wrap:
mov dword [ptr + queue.r_ptr], esi
 
mov ecx, NUMQUEUEENTRIES - 1
mov esi, queueList
pop esi
 
qi002:
inc ax
mov [esi], ax
inc esi
inc esi
loop qi002
}
 
mov ax, NO_BUFFER
mov [esi], ax
macro init_queue ptr {
 
ret
mov [ptr + queue.size] , 0
lea edi, [ptr + sizeof.queue]
mov [ptr + queue.w_ptr], edi
mov [ptr + queue.r_ptr], edi
}
Property changes:
Deleted: svn:keywords
-Rev
\ No newline at end of property