ref: bf6941859c2762c8d98e24dfe7e3a594358f2ed4
parent: f50d02c20713102e9b90e63f7f982b7e95264d4c
author: cinap_lenrek <cinap_lenrek@gmx.de>
date: Fri May 3 15:34:48 EDT 2013
ape: get rid of fixed MUXADDR for buffered i/o instead of trying to resize the segment (which will not work when the kernel picks the address as it will allocate right before the base of the topmost segment), we create the mux segment with the maximum size needed (arround 1.4MB) for OPEN_MAX filedescriptors. buf slots will be reused and slots get demand paged once used.
--- a/sys/src/ape/lib/ap/plan9/_buf.c
+++ b/sys/src/ape/lib/ap/plan9/_buf.c
@@ -20,10 +20,9 @@
int waittime; /* time for timer process to wait */
fd_set rwant; /* fd's that select wants to read */
fd_set ewant; /* fd's that select wants to know eof info on */
- Muxbuf bufs[INITBUFS]; /* can grow, via segbrk() */
+ Muxbuf bufs[OPEN_MAX];
} Muxseg;
-#define MUXADDR ((void*)0x6000000)
static Muxseg *mux = 0; /* shared memory segment */
/* _muxsid and _killmuxsid are known in libbsd's listen.c */
@@ -50,14 +49,13 @@
int
_startbuf(int fd)
{- long i, slot;
- int pid, sid;
+ int i, pid, sid;
Fdinfo *f;
Muxbuf *b;
if(mux == 0){_RFORK(RFREND);
- mux = (Muxseg*)_SEGATTACH(0, "shared", MUXADDR, sizeof(Muxseg));
+ mux = (Muxseg*)_SEGATTACH(0, "shared", 0, sizeof(Muxseg));
if((long)mux == -1){_syserrno();
return -1;
@@ -66,7 +64,7 @@
atexit(_killmuxsid);
}
- if(fd == -1)
+ if(fd < 0)
return 0;
lock(&mux->lock);
@@ -85,17 +83,16 @@
errno = EIO;
return -1;
}
-
- slot = mux->curfds++;
- if(mux->curfds > INITBUFS) {- if(_SEGBRK(mux, mux->bufs+mux->curfds) < 0){- _syserrno();
- unlock(&mux->lock);
- return -1;
- }
+ for(b = mux->bufs; b < &mux->bufs[mux->curfds]; b++)
+ if(b->fd == -1)
+ goto Found;
+ if(mux->curfds >= OPEN_MAX){+ unlock(&mux->lock);
+ errno = ENFILE;
+ return -1;
}
-
- b = &mux->bufs[slot];
+ mux->curfds++;
+Found:
b->n = 0;
b->putnext = b->data;
b->getnext = b->data;
--
⑨