Go to most recent revision |
Blame |
Compare with Previous |
Last modification |
View Log
| RSS feed
/*
*
*
*
*
*/
#include "config.h"
#include <ll/i386/cons.h>
#include <kernel/func.h>
#include <kernel/int_sem.h>
#define seminit(s,v) internal_sem_init(s,v)
#define semwait(s) internal_sem_wait(s)
#define semsignal(s) internal_sem_post(s)
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <assert.h>
#include "xread.h"
/**/
/*
*/
#ifndef ACTIVATE
int x_fseek
(FILE
*file
, long where
, int from
)
{
return fseek(file
,where
,from
);
}
size_t x_fread
(void *buffer
, size_t size
, size_t n
, FILE
*file
)
{
return fread(buffer
,size
,n
,file
);
}
void x_init
(void)
{}
int x_initbuffer
(int group
, FILE
*f
, int rate
, int band
)
{
return XUNUSEDPID
;
}
#endif
#ifdef ACTIVATE
int x_fseek
(FILE
*file
, long where
, int from
)
{
return -1;
}
#define BLOCKSIZE (512*4)
#define BLOCKSPERBUFFER (BUFFERMAXSIZE/BLOCKSIZE)
/* in millisecondi */
#define PRELOAD 500
struct xbuffer
*table
[OPEN_MAX
];
int end_counter
=0;
static TASK bufferfiller
(void *arg
)
{
struct xbuffer
*ptr
=(struct xbuffer
*)arg
;
int n
;
for (;;) {
if (freespace
(ptr
)>BLOCKSIZE
+8) {
//assert(ptr->writeptr>=0);
//assert(ptr->writeptr+BLOCKSIZE<=BUFFERMAXSIZE);
n
=read
(ptr
->handle
,ptr
->buffer
+ptr
->writeptr
,BLOCKSIZE
);
#ifdef NOGRX
cprintf
("²");
#endif
kern_cli
();
ptr
->writeptr
+=n
;
/* ipotesi: non si legge mai piu' di BUFFERMAXSIZE */
if (ptr
->writeptr
>=BUFFERMAXSIZE
) ptr
->writeptr
-=BUFFERMAXSIZE
;
kern_sti
();
if (n
!=BLOCKSIZE
) {
//cprintf("<XXX>");
break;
}
//assert(ptr->writeptr%512==0);
}
task_endcycle
();
}
end_counter
++;
return NULL
;
}
void x_init
(void)
{
int i
;
for (i
=0;i
<OPEN_MAX
;i
++) table
[i
]=NULL
;
}
/* rate in bits/sec */
/* band in percentuale *100 */
int x_initbuffer
(int group
, FILE
*f
, int rate
, int band
)
{
#ifdef EDFSCHED
BDEDF_RES_MODEL resource
;
#endif
#ifdef PSCANSCHED
BDPSCAN_RES_MODEL resource
;
#endif
SOFT_TASK_MODEL model
;
struct xbuffer
*ptr
;
int handle
;
int period
,wcet
;
int n
,preload
;
PID pid
;
handle
=fileno
(f
);
if (handle
>OPEN_MAX
||handle
<0) return -11;
if (table
[handle
]!=NULL
) return -2;
ptr
=table
[handle
]=(struct xbuffer
*)malloc(sizeof(struct xbuffer
));
if (ptr
==NULL
) return -3;
ptr
->handle
=handle
;
ptr
->writeptr
=ptr
->readptr
=0;
n
=lseek
(ptr
->handle
,0,SEEK_SET
);
if (n
!=0) {
cprintf
("can't seek to 0\n");
return -12;
}
/* PRELOAD */
preload
=rate
*PRELOAD
/8/1000;
if (preload
<100*1024) preload
=100*1024;
preload
=(preload
/BLOCKSIZE
+1)*BLOCKSIZE
;
if (preload
>BUFFERMAXSIZE
-BLOCKSIZE
) return -4;
n
=read
(ptr
->handle
,ptr
->buffer
,preload
);
if (n
!=preload
) {
cprintf
("preload: request %li bytes (%li returned)\n",
(long)preload
,(long)n
);
return -5;
}
ptr
->writeptr
+=n
;
//cprintf("%li bytes preloaded\n",(long)n);
if (rate
==0) sys_abort
(997);
period
=1000000l*BLOCKSIZE
/rate
*8;
wcet
=period
*band
/10000;
soft_task_default_model
(model
);
soft_task_def_met
(model
,wcet
);
soft_task_def_wcet
(model
,wcet
);
soft_task_def_period
(model
,period
);
soft_task_def_periodic
(model
);
soft_task_def_arg
(model
,(void*)ptr
);
soft_task_def_group
(model
,group
);
#if defined(EDFSCHED)
BDEDF_res_default_model
(resource
);
BDEDF_res_def_dl
(resource
,period
);
pid
=task_createn
("xfill", bufferfiller
,(TASK_MODEL
*)&model
, &resource
, NULL
);
#elif defined(PSCANSCHED)
BDPSCAN_res_default_model
(resource
);
BDPSCAN_res_def_priority
(resource
,0);
pid
=task_createn
("xfill", bufferfiller
,(TASK_MODEL
*)&model
, &resource
, NULL
);
#else
pid
=task_create
("xfill", bufferfiller
, &model
, NULL
);
#endif
if (pid
!=-1) {
cprintf
("task wcet=%10li period=%10li\n",(long)wcet
,(long)period
);
}
return pid
;
}
size_t x_fread
(void *buffer
, size_t objsize
, size_t n
, FILE
*file
)
{
struct xbuffer
*ptr
;
int size
,sz
;
int nv
;
ptr
=table
[fileno
(file
)];
if (ptr
==NULL
) {
cprintf
("x_fread with bad fd\n");
return 0;
}
size
=objsize
*n
;
//cprintf("[for %i]",size);
REDO
:
if (filledspace
(ptr
)<size
) {
/*
cprintf("x_fread called for %li bytes (%li available)\n",
(long)size,
(long)filledspace(ptr));
*/
nv
=n
;
n
=filledspace
(ptr
)/objsize
;
if (n
==0) {
struct timespec delay
;
delay.
tv_sec=0;
delay.
tv_nsec=15000000;
n
=nv
;
nanosleep
(&delay
, 0);
goto REDO
;
return 0;
}
size
=objsize
*n
;
/*cprintf("%i will return\n",size);*/
}
sz
=BUFFERMAXSIZE
-ptr
->readptr
;
if (sz
>=size
) {
//cprintf("X");
memcpy(buffer
,ptr
->buffer
+ptr
->readptr
,size
);
} else {
//cprintf("Y");
memcpy(buffer
,ptr
->buffer
+ptr
->readptr
,sz
);
assert(size
-sz
>0);
memcpy(buffer
+sz
,ptr
->buffer
,size
-sz
);
}
kern_cli
();
ptr
->readptr
+=size
;
/* ipotesi: non si legge mai piu' di BUFFERMAXSIZE */
if (ptr
->readptr
>=BUFFERMAXSIZE
) ptr
->readptr
-=BUFFERMAXSIZE
;
kern_sti
();
return n
;
}
#endif