Subversion Repositories shark

Rev

Rev 1655 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1655 giacomo 1
/*
2
 *
3
 *
4
 *
5
 *
6
 */
7
 
8
#include "config.h"
9
 
10
#include <ll/i386/cons.h>
11
 
12
#include <kernel/func.h>
13
#include <kernel/int_sem.h>
14
#define seminit(s,v) internal_sem_init(s,v)
15
#define semwait(s)   internal_sem_wait(s)
16
#define semsignal(s) internal_sem_post(s)
17
 
18
#include <stdio.h>
19
#include <stdlib.h>
20
#include <unistd.h>
21
#include <time.h>
22
 
23
#include <assert.h>
24
 
25
#include "xread.h"
26
 
27
/**/
28
 
29
/*
30
 */
31
 
32
#ifndef ACTIVATE
33
int x_fseek(FILE *file, long where, int from)
34
{
35
  return fseek(file,where,from);
36
}
37
 
38
size_t x_fread(void *buffer, size_t size, size_t n, FILE *file)
39
{
40
  return fread(buffer,size,n,file);
41
}
42
 
43
void x_init(void)
44
{}
45
 
46
int x_initbuffer(int group, FILE *f, int rate, int band)
47
{
48
  return XUNUSEDPID;
49
}
50
 
51
#endif
52
 
53
#ifdef ACTIVATE
54
int x_fseek(FILE *file, long where, int from)
55
{
56
  return -1;
57
}
58
 
59
#define BLOCKSIZE (512*4)
60
#define BLOCKSPERBUFFER (BUFFERMAXSIZE/BLOCKSIZE)
61
 
62
/* in millisecondi */
63
#define PRELOAD 500
64
 
65
struct xbuffer *table[OPEN_MAX];
66
 
67
int end_counter=0;
68
 
69
static TASK bufferfiller(void *arg)
70
{
71
  struct xbuffer *ptr=(struct xbuffer *)arg;
72
  int n;
73
 
74
  for (;;) {
75
    if (freespace(ptr)>BLOCKSIZE+8) {
76
      //assert(ptr->writeptr>=0);
77
      //assert(ptr->writeptr+BLOCKSIZE<=BUFFERMAXSIZE);
78
      n=read(ptr->handle,ptr->buffer+ptr->writeptr,BLOCKSIZE);
79
#ifdef NOGRX
80
      cprintf("²");
81
#endif
82
      kern_cli();
83
      ptr->writeptr+=n;
84
      /* ipotesi: non si legge mai piu' di BUFFERMAXSIZE */
85
      if (ptr->writeptr>=BUFFERMAXSIZE) ptr->writeptr-=BUFFERMAXSIZE;
86
      kern_sti();
87
      if (n!=BLOCKSIZE) {
88
        //cprintf("<XXX>");     
89
        break;
90
      }
91
      //assert(ptr->writeptr%512==0);      
92
    }
93
    task_endcycle();
94
  }
95
 
96
  end_counter++;
97
 
98
  return NULL;
99
}
100
 
101
void x_init(void)
102
{
103
  int i;
104
  for (i=0;i<OPEN_MAX;i++) table[i]=NULL;
105
}
106
 
107
/* rate in bits/sec */
108
/* band in percentuale *100 */
109
int x_initbuffer(int group, FILE *f, int rate, int band)
110
{
111
#ifdef EDFSCHED
112
  BDEDF_RES_MODEL resource;
113
#endif
114
#ifdef PSCANSCHED
115
  BDPSCAN_RES_MODEL resource;
116
#endif
117
  SOFT_TASK_MODEL model;
118
  struct xbuffer *ptr;
119
  int handle;
120
  int period,wcet;
121
  int n,preload;
122
  PID pid;
123
 
124
  handle=fileno(f);
125
  if (handle>OPEN_MAX||handle<0) return -11;
126
 
127
  if (table[handle]!=NULL) return -2;
128
 
129
  ptr=table[handle]=(struct xbuffer *)malloc(sizeof(struct xbuffer));
130
  if (ptr==NULL) return -3;
131
 
132
  ptr->handle=handle;
133
  ptr->writeptr=ptr->readptr=0;
134
  n=lseek(ptr->handle,0,SEEK_SET);
135
  if (n!=0) {
136
    cprintf("can't seek to 0\n");
137
    return -12;
138
  }
139
 
140
  /* PRELOAD */
141
  preload=rate*PRELOAD/8/1000;
142
  if (preload<100*1024) preload=100*1024;
143
  preload=(preload/BLOCKSIZE+1)*BLOCKSIZE;
144
  if (preload>BUFFERMAXSIZE-BLOCKSIZE) return -4;  
145
  n=read(ptr->handle,ptr->buffer,preload);
146
  if (n!=preload) {
147
    cprintf("preload: request %li bytes (%li returned)\n",
148
            (long)preload,(long)n);
149
    return -5;
150
  }
151
  ptr->writeptr+=n;
152
 
153
  //cprintf("%li bytes preloaded\n",(long)n);
154
  if (rate==0) sys_abort(997);
155
  period=1000000l*BLOCKSIZE/rate*8;
156
  wcet=period*band/10000;
157
 
158
  soft_task_default_model(model);    
159
  soft_task_def_met(model,wcet);
160
  soft_task_def_wcet(model,wcet);
161
  soft_task_def_period(model,period);  
162
  soft_task_def_periodic(model);
163
  soft_task_def_arg(model,(void*)ptr);
164
  soft_task_def_group(model,group);
165
 
166
#if defined(EDFSCHED)
167
  BDEDF_res_default_model(resource);
168
  BDEDF_res_def_dl(resource,period);
169
  pid=task_createn("xfill", bufferfiller,(TASK_MODEL*)&model, &resource, NULL);
170
#elif defined(PSCANSCHED)
171
  BDPSCAN_res_default_model(resource);
172
  BDPSCAN_res_def_priority(resource,0);
173
  pid=task_createn("xfill", bufferfiller,(TASK_MODEL*)&model, &resource, NULL);
174
#else
175
  pid=task_create("xfill", bufferfiller, &model, NULL);
176
#endif
177
  if (pid!=-1) {
178
    cprintf("task wcet=%10li period=%10li\n",(long)wcet,(long)period);
179
  }
180
 
181
  return pid;
182
}
183
 
184
size_t x_fread(void *buffer, size_t objsize, size_t n, FILE *file)
185
{
186
  struct xbuffer *ptr;
187
  int size,sz;
188
  int nv;
189
 
190
  ptr=table[fileno(file)];
191
  if (ptr==NULL) {
192
    cprintf("x_fread with bad fd\n");
193
    return 0;
194
  }
195
 
196
  size=objsize*n;
197
  //cprintf("[for %i]",size);
198
REDO:
199
  if (filledspace(ptr)<size) {
200
    /*
201
    cprintf("x_fread called for %li bytes (%li available)\n",
202
            (long)size,
203
            (long)filledspace(ptr));
204
    */
205
    nv=n;
206
    n=filledspace(ptr)/objsize;
207
    if (n==0) {
208
      struct timespec delay;
209
      delay.tv_sec=0;
210
      delay.tv_nsec=15000000;
211
      n=nv;
212
      nanosleep(&delay, 0);
213
      goto REDO;
214
      return 0;
215
    }
216
    size=objsize*n;
217
    /*cprintf("%i will return\n",size);*/
218
  }
219
 
220
  sz=BUFFERMAXSIZE-ptr->readptr;
221
  if (sz>=size) {
222
    //cprintf("X");
223
    memcpy(buffer,ptr->buffer+ptr->readptr,size);
224
  } else {
225
    //cprintf("Y");
226
    memcpy(buffer,ptr->buffer+ptr->readptr,sz);
227
    assert(size-sz>0);
228
    memcpy(buffer+sz,ptr->buffer,size-sz);
229
  }
230
 
231
  kern_cli();
232
  ptr->readptr+=size;
233
  /* ipotesi: non si legge mai piu' di BUFFERMAXSIZE */
234
  if (ptr->readptr>=BUFFERMAXSIZE) ptr->readptr-=BUFFERMAXSIZE;
235
  kern_sti();
236
 
237
  return n;
238
}
239
 
240
#endif