From 047a748631f76d72434486633d41ca65e9f49241 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Sat, 14 May 1994 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1994-05-14 --- port/segment.c | 54 +++++++++++++++++++++++++++++++++++--------------- 1 file changed, 38 insertions(+), 16 deletions(-) diff --git a/port/segment.c b/port/segment.c index 0452a655b1e89624db1f893dad4867a71f68daec..40f953db3282616aec4137a3bf1d41aec484adb9 100644 --- a/port/segment.c +++ b/port/segment.c @@ -405,40 +405,62 @@ mfreeseg(Segment *s, ulong start, int pages) } } +int +isoverlap(Proc *p, ulong va, int len) +{ + int i; + Segment *ns; + ulong newtop; + + newtop = va+len; + for(i = 0; i < NSEG; i++) { + ns = p->seg[i]; + if(ns == 0) + continue; + if((newtop > ns->base && newtop <= ns->top) || + (va >= ns->base && va < ns->top)) + return 1; + } + return 0; +} + ulong segattach(Proc *p, ulong attr, char *name, ulong va, ulong len) { - Segment *s, *ns; - Physseg *ps; - ulong newtop; int i, sno; + Segment *s; + Physseg *ps; USED(p); - if((va&KZERO) == KZERO) /* BUG: Only ok for now */ + if(va != 0 && (va&KZERO) == KZERO) /* BUG: Only ok for now */ error(Ebadarg); validaddr((ulong)name, 1, 0); vmemchr(name, 0, ~0); for(sno = 0; sno < NSEG; sno++) - if(up->seg[sno] == 0 && sno != ESEG) + if(p->seg[sno] == 0 && sno != ESEG) break; if(sno == NSEG) error(Enovmem); - va = va&~(BY2PG-1); len = PGROUND(len); - newtop = va+len; - for(i = 0; i < NSEG; i++) { - ns = up->seg[i]; - if(ns == 0) - continue; - if((newtop > ns->base && newtop <= ns->top) || - (va >= ns->base && va < ns->top)) - error(Esoverlap); + + /* Find a hole in the address space */ + if(va == 0) { + va = p->seg[SSEG]->base - len; + for(i = 0; i < 20; i++) { + if(isoverlap(p, va, len) == 0) + break; + va -= len; + } } + va = va&~(BY2PG-1); + if(isoverlap(p, va, len)) + error(Esoverlap); + for(ps = physseg; ps->name; ps++) if(strcmp(name, ps->name) == 0) goto found; @@ -453,9 +475,9 @@ found: s = newseg(attr, va, len/BY2PG); s->pseg = ps; - up->seg[sno] = s; + p->seg[sno] = s; - return 0; + return va; } void