Subversion Repositories shark

Rev

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

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