Subversion Repositories shark

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 pj 1
/*
2
 * Project: S.Ha.R.K.
3
 *
4
 * Coordinators:
5
 *   Giorgio Buttazzo    <giorgio@sssup.it>
6
 *   Paolo Gai           <pj@gandalf.sssup.it>
7
 *
8
 * Authors     :
9
 *   Paolo Gai           <pj@gandalf.sssup.it>
10
 *   Massimiliano Giorgi <massy@gandalf.sssup.it>
11
 *   Luca Abeni          <luca@gandalf.sssup.it>
12
 *   (see the web pages for full authors list)
13
 *
14
 * ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
15
 *
16
 * http://www.sssup.it
17
 * http://retis.sssup.it
18
 * http://shark.sssup.it
19
 */
20
 
21
/**
22
 ------------
23
 CVS :        $Id: netbuff.c,v 1.1.1.1 2002-03-29 14:12:50 pj Exp $
24
 
25
 File:        $File$
26
 Revision:    $Revision: 1.1.1.1 $
27
 Last update: $Date: 2002-03-29 14:12:50 $
28
 ------------
29
**/
30
 
31
/*
32
 * Copyright (C) 2000 Luca Abeni
33
 *
34
 * This program is free software; you can redistribute it and/or modify
35
 * it under the terms of the GNU General Public License as published by
36
 * the Free Software Foundation; either version 2 of the License, or
37
 * (at your option) any later version.
38
 *
39
 * This program is distributed in the hope that it will be useful,
40
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
41
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
42
 * GNU General Public License for more details.
43
 *
44
 * You should have received a copy of the GNU General Public License
45
 * along with this program; if not, write to the Free Software
46
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
47
 *
48
 */
49
 
50
/* Author:      Luca Abeni                                      */
51
/* Date:        25/9/1997                                       */
52
 
53
/* File:        NetBuff.c                                       */
54
/* Revision:    1.00                                            */
55
 
56
/*
57
   This module manages all the buffers used by the network driver:
58
   the buffers are grouped in netbuff structures (initialized by
59
   netbuff_init) and can be allocated by netbuff_get or released
60
   by netbuff_released. A netbuff_sequentialget function is also
61
   provided for beeing used by tasks that have their own buffer (
62
   if a buffer can be allocated by only one task, it is useless to
63
   allocate it in mutual exclusion). It is usefull for the receive
64
   buffers allocated by the receive process.
65
*/
66
#include <kernel/kern.h>
67
#include <semaphore.h>
68
 
69
#include "netbuff.h"
70
 
71
/* Init the buffer structures */
72
void netbuff_init(struct netbuff *netb, BYTE nbuffs, WORD buffdim)
73
{
74
    int i;
75
 
76
    kern_cli();
77
    netb->b = kern_alloc(nbuffs * buffdim);
78
    netb->pb = kern_alloc(nbuffs * sizeof(void *));
79
    netb->free = kern_alloc(nbuffs * sizeof(char));
80
    kern_sti();
81
    if ((netb->b == 0) || (netb->pb ==0) || (netb->free == 0)) {
82
        kern_raise(XNETBUFF_INIT_EXC,exec_shadow);
83
    }
84
    netb->nbuffs = nbuffs;
85
    for (i = 0; i < nbuffs; i++) {
86
        netb->pb[i] = netb->b + (i * buffdim);
87
        netb->free[i] = 1;
88
    }
89
    sem_init(&(netb->buffersem), 0, nbuffs);
90
}
91
 
92
/*
93
   Get the first free buffer in the netb pool. All the tasks can call this
94
   function, so a kern_cli is needed
95
*/
96
void *netbuff_get(struct netbuff *netb, BYTE to)
97
{
98
    int i, done;
99
static int mycount = 0;
100
 
101
    if (sem_xwait(&(netb->buffersem), 1, to) != 0) {
102
        return NULL;
103
    } else {
104
mycount++;
105
}
106
 
107
    done = 0; i = 0;
108
    kern_cli();
109
    while ((i < netb->nbuffs) && !done) {
110
        if (netb->free[i]) {
111
            done = 1;
112
            netb->free[i] = 0;
113
        } else i++;
114
    }
115
    kern_sti();
116
    if (!done) {
117
        kern_raise(XNETBUFF_GET_EXC,exec_shadow);
118
    }
119
    return netb->pb[i];
120
}
121
 
122
/*
123
   Get the first free buffer in the netb pool. This function can be called
124
   only if netb is private of the process that wants to get the buffer, so
125
   kern_cli is not needed
126
*/
127
void *netbuff_sequentialget(struct netbuff *netb, BYTE to)
128
{
129
    int i, done;
130
 
131
    if (!sem_xwait(&(netb->buffersem), 1, to)) {
132
        return NULL;
133
    }
134
 
135
    done = 0; i = 0;
136
    while ((i < netb->nbuffs) && !done) {
137
        if (netb->free[i]) {
138
            done = 1;
139
            netb->free[i] = 0;
140
        } else i++;
141
    }
142
    if (!done) {
143
        kern_raise(XNETBUFF_GET_EXC,exec_shadow);
144
    }
145
    return netb->pb[i];
146
}
147
 
148
/* Release the buffer m of the pool netb */
149
void netbuff_release(struct netbuff *netb, void *m)
150
{
151
    int i, done;
152
 
153
    done = 0; i = 0;
154
    while ((i < netb->nbuffs) && !done) {
155
        if (netb->pb[i] == m) {
156
            if (netb->free[i] == 1) {
157
                cprintf("Trying to free a free buffer :( \n");
158
                kern_raise(XNETBUFF_ALREADYFREE_EXC,exec_shadow);
159
            }
160
            done = 1;
161
            netb->free[i] = 1;
162
        } else i++;
163
    }
164
    if (!done) {
165
        cprintf("Trying to free a STRANGE buffer :( \n");
166
        kern_raise(XNETBUFF_RELEASE_EXC,exec_shadow);
167
    }
168
    sem_post(&(netb->buffersem));
169
}