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: cabs.c,v 1.1.1.1 2002-03-29 14:12:52 pj Exp $
24
 
25
 File:        $File$
26
 Revision:    $Revision: 1.1.1.1 $
27
 Last update: $Date: 2002-03-29 14:12:52 $
28
 ------------
29
 
30
 Date:        2/7/96
31
 
32
 File:           Cabs.C
33
 Translated by : Giuseppe Lipari
34
 Revision:       1.1
35
 
36
**/
37
 
38
/*
39
 * Copyright (C) 2000 Paolo Gai
40
 *
41
 * This program is free software; you can redistribute it and/or modify
42
 * it under the terms of the GNU General Public License as published by
43
 * the Free Software Foundation; either version 2 of the License, or
44
 * (at your option) any later version.
45
 *
46
 * This program is distributed in the hope that it will be useful,
47
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
48
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
49
 * GNU General Public License for more details.
50
 *
51
 * You should have received a copy of the GNU General Public License
52
 * along with this program; if not, write to the Free Software
53
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
54
 *
55
 */
56
 
57
 
58
#include <modules/cabs.h>
59
 
60
#include <kernel/config.h>
61
#include <ll/ll.h>
62
#include <ll/string.h>
63
#include <kernel/model.h>
64
#include <kernel/const.h>
65
#include <sys/types.h>
66
#include <kernel/descr.h>
67
#include <errno.h>
68
#include <kernel/var.h>
69
#include <kernel/func.h>
70
 
71
/* "cab":       contiene dei buffer per memorizzare messaggi            */
72
/* "cab_data":  buffer contenente il messaggio e informazioni relative  */
73
/* "messaggio": si trova a partire da (*cab_data + 1)                   */
74
 
75
struct cab_data {               /* struttura del buffer di cab  */
76
    struct cab_data *next;      /* successivo buffer del cab    */
77
    unsigned short n_uso;       /* processi che usano il buffer */
78
};
79
 
80
struct cab_desc {                       /* struttura descrittore di cab */
81
        char    name[MAX_CAB_NAME+1];   /* nome del CAB                 */
82
        CAB     next_cab_free;          /* indice successivo cab libero */
83
        BYTE    busy;                   /* cab libero/occcupato         */
84
        char    *mem_cab;               /* memoria globale cab          */
85
        BYTE    n_buf;                  /* numero dei buffer nel cab    */
86
        BYTE    nfree;                  /* numero buffer liberi         */
87
        unsigned dim_mes;               /* dimensione del messaggio     */
88
        struct  cab_data *free;         /* puntatore primo buffer libero*/
89
        struct  cab_data *mrd;          /* puntatore must_recent_data   */
90
};
91
 
92
static struct   cab_desc  cabs[MAX_CAB]; /* vettore descrittori dei CAB  */
93
static CAB      free_cab;                /* indice del primo cab libero  */
94
 
95
static int checkcab(CAB id)
96
{
97
    if (id >= MAX_CAB) {
98
        errno = ECAB_UNVALID_ID;
99
        return -1;
100
    }
101
    if (cabs[id].busy == TRUE) return TRUE;
102
    else errno = ECAB_CLOSED;
103
    return -1;
104
}
105
 
106
/*----------------------------------------------------------------------*/
107
/* cab_init -- inizializza le strutture dei cab                         */
108
/*----------------------------------------------------------------------*/
109
void CABS_register_module(void)
110
{
111
    int i;
112
 
113
    free_cab = 0;
114
    for (i=0; i < MAX_CAB - 1; i++) {
115
        cabs[i].next_cab_free = i+1;
116
        cabs[i].busy = FALSE;
117
    }
118
    cabs[MAX_CAB-1].next_cab_free = NIL;
119
    cabs[MAX_CAB-1].busy = FALSE;
120
//    for (i = CAB_UNVALID_MSG_NUM; i <= CAB_CLOSED; i++)
121
//      exc_set(i,cab_exception);
122
}
123
 
124
/*----------------------------------------------------------------------*/
125
/* cab_create -- crea un cab, lo inizializza e restituisce l'indice     */
126
/*----------------------------------------------------------------------*/
127
CAB cab_create(char *name, int dim_mes, BYTE num_mes)
128
{
129
    CAB id;                     /* indice del cab da restituire         */
130
    struct cab_desc *pid;       /* puntatore al cab (velocizza accesso) */
131
    char *mem;                  /* puntatore di appoggio al buffer      */
132
    struct cab_data *tmp;       /* puntatore di scorrimento lista cab   */
133
    int i;                      /* variabile indice                     */
134
    SYS_FLAGS f;
135
 
136
    f = kern_fsave();
137
 
138
    /* Se non ci sono piu' cab liberi o il parametro num_mes < 1 */
139
    /* solleva l'eccezioni                                       */
140
 
141
    if (num_mes < 1) {
142
        errno = ECAB_UNVALID_MSG_NUM;
143
        kern_frestore(f);
144
        return -1;
145
    }
146
    if ((id=free_cab) != MAX_CAB) {
147
        pid = &cabs[id];        /* prendo l'indirizzo del cab */
148
        free_cab = pid->next_cab_free;
149
    }
150
    else {
151
        errno = ECAB_NO_MORE_ENTRY;
152
        kern_frestore(f);
153
        return -1;
154
    }
155
 
156
    /* richiede un identificatore e la memoria */
157
    mem = kern_alloc((dim_mes + sizeof(struct cab_data)) * num_mes);
158
 
159
    kern_frestore(f);
160
    /* inizializzazione del descrittore del cab */
161
 
162
    strcpy(pid->name, name);
163
    pid->mem_cab = mem;
164
    pid->dim_mes = dim_mes;
165
    pid->n_buf = num_mes;
166
 
167
    /* inizializzazione primo messaggio e buffer liberi */
168
 
169
    pid->mrd = (struct cab_data *)mem;
170
    i = (int)num_mes;
171
        tmp = NULL;
172
    while (i--) {
173
        tmp = (struct cab_data *)mem;
174
        mem += sizeof(struct cab_data) + dim_mes;
175
        tmp->next = (struct cab_data *)mem;
176
        tmp->n_uso = 0;
177
    }
178
 
179
    tmp->next = NULL;
180
    pid->free = pid->mrd->next;
181
 
182
    mem = (char *)(pid->mrd + 1);
183
    for (i=0; i<dim_mes; i++) *(mem++) = 0;
184
    pid->nfree = num_mes - 1;
185
 
186
    f = kern_fsave();
187
    pid->busy = TRUE;
188
    kern_frestore(f);
189
 
190
    return(id);
191
}
192
 
193
/*----------------------------------------------------------------------*/
194
/* cab_reserve --  richiede un buffer in cui mettere i dati da inviare  */
195
/*              ritorna un puntatore al buffer                          */
196
/*----------------------------------------------------------------------*/
197
char *cab_reserve(CAB id)
198
{
199
    struct cab_desc *pid;
200
    char *buf;
201
    SYS_FLAGS f;
202
 
203
    /* controlla l'identificatore del CAB */
204
    if (checkcab(id) == -1) return(NULL);
205
 
206
    pid = &cabs[id];
207
    f = kern_fsave();
208
    /* Se il numero di elementi assegnati non e` = al massimo */
209
    if ((pid->nfree)--) {
210
        buf = (char *)(pid->free + 1);
211
        pid->free = pid->free->next;
212
        kern_frestore(f);
213
        return(buf);
214
    }
215
    else {
216
        errno = ECAB_TOO_MUCH_MSG;
217
        kern_frestore(f);
218
        return(NULL);
219
    }
220
}
221
 
222
/*----------------------------------------------------------------------*/
223
/*  cab_putmes -- immette un nuovo messaggio nel cab                    */
224
/*----------------------------------------------------------------------*/
225
int cab_putmes(CAB id, char *pbuf)
226
{
227
    struct cab_data *pold;
228
    struct cab_desc *pid;
229
    SYS_FLAGS f;
230
 
231
    if (checkcab(id) == -1) return -1;
232
    pid = &cabs[id];
233
 
234
    f = kern_fsave();
235
    pold = pid->mrd;
236
    if (pold->n_uso == 0) {
237
        pold->next = pid->free;
238
        pid->free = pold;
239
        (pid->nfree)++;
240
    }
241
 
242
    pid->mrd = ((struct cab_data *)pbuf) - 1;
243
    kern_frestore(f);
244
    return 1;
245
}
246
 
247
/*----------------------------------------------------------------------*/
248
/*  cab_getmes  --  richiede l'ultimo messaggio presente nel cab.       */
249
/*               Ritorna un puntatore al buffer piu' recente            */
250
/*----------------------------------------------------------------------*/
251
char *cab_getmes(CAB id)
252
{
253
    char *tmp;
254
    SYS_FLAGS f;
255
 
256
    if (checkcab(id) == -1) return(NULL);
257
    f = kern_fsave();
258
 
259
    /* cabs[id].mrd punta all'ultimo buffer inserito, incremento        */
260
    /* il puntatore di uno e ottengo l'area del messaggio, converto     */
261
    /* quindi il puntatore al tipo carattere. Segue l'incremento        */
262
    /* del campo contatore di uso buffer                                */
263
 
264
    (cabs[id].mrd->n_uso)++;
265
    tmp = (char *)(cabs[id].mrd + 1);
266
 
267
    kern_frestore(f);
268
    return(tmp);
269
}
270
 
271
/*----------------------------------------------------------------------*/
272
/* cab_unget -- segnala che il task non usa piu' il messaggio,          */
273
/*              se questo non e' piu' usato da nessuno viene rilasciato */
274
/*              ritorna un risultato                                    */
275
/*----------------------------------------------------------------------*/
276
int cab_unget(CAB id, char *pun_mes)
277
/* small id;                            indice del cab di lavoro        */
278
/* char *pun_mes;                       puntatore al messaggio          */
279
{
280
    struct cab_data *pbuf;
281
    struct cab_desc *pid;
282
    SYS_FLAGS f;
283
 
284
    if (checkcab(id) == -1) return -1;
285
    pid = &cabs[id];
286
 
287
    f = kern_fsave();
288
    pbuf = ((struct cab_data *)(pun_mes)) - 1;
289
 
290
    if ((--(pbuf->n_uso) == 0) && (pbuf != pid->mrd)) {
291
        pbuf->next = pid->free;
292
        pid->free = pbuf;
293
        (pid->nfree)++;
294
    }
295
    kern_frestore(f);
296
    return 1;
297
}
298
 
299
/*----------------------------------------------------------------------*/
300
/*      cab_delete -- libera la memoria e rilascia il cab               */
301
/*----------------------------------------------------------------------*/
302
void cab_delete(CAB id)
303
{
304
    struct cab_desc *pid;
305
    SYS_FLAGS f;
306
 
307
    pid = &cabs[id];
308
    f = kern_fsave();
309
    kern_free(pid->mem_cab,(pid->dim_mes + sizeof(struct cab_data))*pid->n_buf);
310
 
311
    pid->busy = FALSE;
312
    pid->next_cab_free = free_cab;
313
    free_cab = id;
314
    kern_frestore(f);
315
}