From 551995dfc4fe7579eaea9e1ae1bbfb23b0ce742d Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Tue, 28 May 1996 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1996-05-28 --- port/segment.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 51 insertions(+), 3 deletions(-) diff --git a/port/segment.c b/port/segment.c index f199700810685c385cd38aa476c59f3cfe936726..a1a6ee0a923e1cf391e366ce980a56f5f3f67df2 100644 --- a/port/segment.c +++ b/port/segment.c @@ -8,11 +8,13 @@ Page* lkpage(Segment*, ulong); void lkpgfree(Page*); void imagereclaim(void); +void imagechanreclaim(void); /* System specific segattach devices */ #include "io.h" #include "segment.h" +#define NFREECHAN 64 #define IHASHSIZE 64 #define ihash(s) imagealloc.hash[s%IHASHSIZE] struct @@ -20,7 +22,12 @@ struct Lock; Image *free; Image *hash[IHASHSIZE]; - QLock ireclaim; + QLock ireclaim; /* mutex on reclaiming free images */ + + Chan **freechan; /* free image channels */ + int nfreechan; /* number of free channels */ + int szfreechan; /* size of freechan array */ + QLock fcreclaim; /* mutex on reclaiming free channels */ }imagealloc; void @@ -33,6 +40,8 @@ initseg(void) for(i = imagealloc.free; i < ie; i++) i->next = i+1; i->next = 0; + imagealloc.freechan = malloc(NFREECHAN * sizeof(Chan*)); + imagealloc.szfreechan = NFREECHAN; } Segment * @@ -201,6 +210,10 @@ attachimage(int type, Chan *c, ulong base, ulong len) { Image *i, **l; + /* reclaim any free channels from reclaimed segments */ + if(imagealloc.nfreechan) + imagechanreclaim(); + lock(&imagealloc); /* @@ -285,10 +298,34 @@ imagereclaim(void) qunlock(&imagealloc.ireclaim); } +/* + * since close can block, this has to be called outside of + * spin locks. + */ void -putimage(Image *i) +imagechanreclaim(void) { Chan *c; + + /* Somebody is already cleaning the image chans */ + if(!canqlock(&imagealloc.fcreclaim)) + return; + + while(imagealloc.nfreechan > 0){ + lock(&imagealloc); + imagealloc.nfreechan--; + c = imagealloc.freechan[imagealloc.nfreechan]; + unlock(&imagealloc); + close(c); + } + + qunlock(&imagealloc.fcreclaim); +} + +void +putimage(Image *i) +{ + Chan *c, **cp; Image *f, **l; if(i->notext) @@ -312,9 +349,20 @@ putimage(Image *i) i->next = imagealloc.free; imagealloc.free = i; + + /* defer freeing channel till we're out of spin lock's */ + if(imagealloc.nfreechan == imagealloc.szfreechan){ + imagealloc.szfreechan += NFREECHAN; + cp = malloc(imagealloc.szfreechan*sizeof(Chan*)); + if(cp == nil) + panic("putimage"); + memmove(cp, imagealloc.freechan, imagealloc.nfreechan*sizeof(Chan*)); + free(imagealloc.freechan); + imagealloc.freechan = cp; + } + imagealloc.freechan[imagealloc.nfreechan++] = c; unlock(&imagealloc); - close(c); return; } unlock(i);