| 21 |
|
#ifndef PCTFREE |
| 22 |
|
#define PCTFREE 15 /* maximum fraction to free (%) */ |
| 23 |
|
#endif |
| 24 |
< |
#ifndef MAXFRAG |
| 25 |
< |
#define MAXFRAG 32767 /* maximum fragments/file to track (0==inf) */ |
| 24 |
> |
#ifndef MAXFRAGB |
| 25 |
> |
#define MAXFRAGB 16 /* fragment blocks/file to track (0==inf) */ |
| 26 |
|
#endif |
| 27 |
+ |
#ifndef MINDIRSEL |
| 28 |
+ |
/* minimum directory seek length */ |
| 29 |
+ |
#define MINDIRSEL (4*BUFSIZ/sizeof(BEAMI)) |
| 30 |
+ |
#endif |
| 31 |
|
|
| 32 |
|
#ifndef BSD |
| 33 |
|
#define write writebuf /* safe i/o routines */ |
| 34 |
|
#define read readbuf |
| 35 |
|
#endif |
| 36 |
|
|
| 37 |
< |
#define FRAGBLK 256 /* number of fragments to allocate at a time */ |
| 37 |
> |
#define FRAGBLK 512 /* number of fragments to allocate at a time */ |
| 38 |
|
|
| 39 |
|
unsigned hdcachesize = CACHESIZE*1024*1024; /* target cache size */ |
| 40 |
|
unsigned long hdclock; /* clock value */ |
| 107 |
|
} |
| 108 |
|
|
| 109 |
|
|
| 106 |
– |
markdirty(hp) /* mark holodeck section directory dirty */ |
| 107 |
– |
register HOLO *hp; |
| 108 |
– |
{ |
| 109 |
– |
static BEAMI smudge = {0, -1}; |
| 110 |
– |
|
| 111 |
– |
if (hp->dirty) /* already marked? */ |
| 112 |
– |
return; |
| 113 |
– |
hp->dirty = 1; |
| 114 |
– |
if (lseek(hp->fd, biglob(hp)->fo+(nbeams(hp)-1)*sizeof(BEAMI), 0) < 0 |
| 115 |
– |
|| write(hp->fd, (char *)&smudge, |
| 116 |
– |
sizeof(BEAMI)) != sizeof(BEAMI)) |
| 117 |
– |
error(SYSTEM, "seek/write error in markdirty"); |
| 118 |
– |
} |
| 119 |
– |
|
| 120 |
– |
|
| 110 |
|
HOLO * |
| 111 |
|
hdinit(fd, hproto) /* initialize a holodeck section in a file */ |
| 112 |
|
int fd; /* corresponding file descriptor */ |
| 133 |
|
if (read(fd, (char *)(hp->bi+1), n) != n) |
| 134 |
|
error(SYSTEM, "failure loading holodeck directory"); |
| 135 |
|
/* check that it's clean */ |
| 136 |
< |
if (hp->bi[nbeams(hp)].fo < 0) |
| 137 |
< |
error(WARNING, "dirty holodeck section"); |
| 136 |
> |
for (n = nbeams(hp); n > 0; n--) |
| 137 |
> |
if (hp->bi[n].fo < 0) { |
| 138 |
> |
hp->bi[n].fo = 0; |
| 139 |
> |
error(WARNING, "dirty holodeck section"); |
| 140 |
> |
break; |
| 141 |
> |
} |
| 142 |
|
} else { /* assume we're creating it */ |
| 143 |
|
if ((hp = hdalloc(hproto)) == NULL) |
| 144 |
|
goto memerr; |
| 182 |
|
} |
| 183 |
|
|
| 184 |
|
|
| 185 |
+ |
markdirty(hp, i) /* mark holodeck directory position dirty */ |
| 186 |
+ |
register HOLO *hp; |
| 187 |
+ |
int i; |
| 188 |
+ |
{ |
| 189 |
+ |
static BEAMI smudge = {0, -1}; |
| 190 |
+ |
int mindist, minpos; |
| 191 |
+ |
register int j; |
| 192 |
+ |
|
| 193 |
+ |
if (!hp->dirty++) { /* write smudge first time */ |
| 194 |
+ |
if (lseek(hp->fd, biglob(hp)->fo+(i-1)*sizeof(BEAMI), 0) < 0 |
| 195 |
+ |
|| write(hp->fd, (char *)&smudge, |
| 196 |
+ |
sizeof(BEAMI)) != sizeof(BEAMI)) |
| 197 |
+ |
error(SYSTEM, "seek/write error in markdirty"); |
| 198 |
+ |
hp->dirseg[0].s = i; |
| 199 |
+ |
hp->dirseg[0].n = 1; |
| 200 |
+ |
return; |
| 201 |
+ |
} |
| 202 |
+ |
/* insert into segment list */ |
| 203 |
+ |
for (j = hp->dirty; j--; ) { |
| 204 |
+ |
if (!j || hp->dirseg[j-1].s < i) { |
| 205 |
+ |
hp->dirseg[j].s = i; |
| 206 |
+ |
hp->dirseg[j].n = 1; |
| 207 |
+ |
break; |
| 208 |
+ |
} |
| 209 |
+ |
copystruct(hp->dirseg+j, hp->dirseg+(j-1)); |
| 210 |
+ |
} |
| 211 |
+ |
do { /* check neighbors */ |
| 212 |
+ |
mindist = nbeams(hp); /* find closest */ |
| 213 |
+ |
for (j = hp->dirty; --j; ) |
| 214 |
+ |
if (hp->dirseg[j].s - |
| 215 |
+ |
(hp->dirseg[j-1].s + hp->dirseg[j-1].n) |
| 216 |
+ |
< mindist) { |
| 217 |
+ |
minpos = j; |
| 218 |
+ |
mindist = hp->dirseg[j].s - |
| 219 |
+ |
(hp->dirseg[j-1].s + hp->dirseg[j-1].n); |
| 220 |
+ |
} |
| 221 |
+ |
/* good enough? */ |
| 222 |
+ |
if (hp->dirty <= MAXDIRSE && mindist > MINDIRSEL) |
| 223 |
+ |
break; |
| 224 |
+ |
j = minpos - 1; /* coalesce neighbors */ |
| 225 |
+ |
if (hp->dirseg[j].s + hp->dirseg[j].n < |
| 226 |
+ |
hp->dirseg[minpos].s + hp->dirseg[minpos].n) |
| 227 |
+ |
hp->dirseg[j].n = hp->dirseg[minpos].s + |
| 228 |
+ |
hp->dirseg[minpos].n - hp->dirseg[j].s; |
| 229 |
+ |
hp->dirty--; |
| 230 |
+ |
while (++j < hp->dirty) /* close the gap */ |
| 231 |
+ |
copystruct(hp->dirseg+j, hp->dirseg+(j+1)); |
| 232 |
+ |
} while (mindist <= MINDIRSEL); |
| 233 |
+ |
} |
| 234 |
+ |
|
| 235 |
+ |
|
| 236 |
|
int |
| 237 |
|
hdsync(hp, all) /* update beams and directory on disk */ |
| 238 |
|
register HOLO *hp; |
| 252 |
|
hdsyncbeam(hp, j); |
| 253 |
|
if (!hp->dirty) /* directory clean? */ |
| 254 |
|
return(0); |
| 255 |
< |
errno = 0; |
| 256 |
< |
if (lseek(hp->fd, biglob(hp)->fo, 0) < 0) |
| 257 |
< |
error(SYSTEM, "cannot seek on holodeck file"); |
| 258 |
< |
n = nbeams(hp)*sizeof(BEAMI); |
| 259 |
< |
if (write(hp->fd, (char *)(hp->bi+1), n) != n) |
| 260 |
< |
error(SYSTEM, "cannot update holodeck section directory"); |
| 261 |
< |
hp->dirty = 0; |
| 255 |
> |
errno = 0; /* write dirty segments */ |
| 256 |
> |
for (j = 0; j < hp->dirty; j++) { |
| 257 |
> |
if (lseek(hp->fd, biglob(hp)->fo + |
| 258 |
> |
(hp->dirseg[j].s-1)*sizeof(BEAMI), 0) < 0) |
| 259 |
> |
error(SYSTEM, "cannot seek on holodeck file"); |
| 260 |
> |
n = hp->dirseg[j].n * sizeof(BEAMI); |
| 261 |
> |
if (write(hp->fd, (char *)(hp->bi+hp->dirseg[j].s), n) != n) |
| 262 |
> |
error(SYSTEM, "cannot update section directory"); |
| 263 |
> |
} |
| 264 |
> |
hp->dirty = 0; /* all clean */ |
| 265 |
|
return(1); |
| 266 |
|
} |
| 267 |
|
|
| 501 |
|
f->nfrags = j; |
| 502 |
|
} |
| 503 |
|
j = f->nfrags++; /* allocate a slot in free list */ |
| 504 |
< |
#if MAXFRAG |
| 505 |
< |
if (j >= MAXFRAG-1) |
| 506 |
< |
f->nfrags--; |
| 504 |
> |
#if MAXFRAGB |
| 505 |
> |
if (j >= MAXFRAGB*FRAGBLK) { |
| 506 |
> |
f->nfrags = j--; /* stop list growth */ |
| 507 |
> |
if (bi->nrd <= f->fi[j].nrd) |
| 508 |
> |
return; /* new one no better than discard */ |
| 509 |
> |
} |
| 510 |
|
#endif |
| 511 |
|
if (j % FRAGBLK == 0) { /* more free list space */ |
| 512 |
|
register BEAMI *newp; |
| 617 |
|
hp->bi[i].fo = 0L; |
| 618 |
|
biglob(hp)->nrd += nrays - hp->bi[i].nrd; |
| 619 |
|
hp->bi[i].nrd = nrays; |
| 620 |
< |
markdirty(hp); /* section directory now out of date */ |
| 620 |
> |
markdirty(hp, i); /* section directory now out of date */ |
| 621 |
|
return(1); |
| 622 |
|
} |
| 623 |
|
|