even though it's a lost cause, try a little harder to guess at the amout of free memory on nix. it's at least the free pages plus the unallocated physical memory of any color Reference: /n/atom/patch/applied/ventinixfreemem Date: Thu Apr 3 18:25:17 CES 2014 Signed-off-by: quanstro@quanstro.net --- /sys/src/cmd/venti/srv/venti.c Thu Apr 3 18:25:12 2014 +++ /sys/src/cmd/venti/srv/venti.c Thu Apr 3 18:25:13 2014 @@ -25,41 +25,91 @@ static void ventiserver(void*); +static uvlong +capmem(uvlong size) +{ + char buf[64], *s; + uvlong bos; + Biobuf *b; + + /* don't run into the stack */ + snprint(buf, sizeof buf, "/proc/%d/segment", getpid()); + if((b = Bopen(buf, OREAD)) != nil){ + for(; (s = Brdstr(b, '\n', 1)) != nil; free(s)){ + if(strncmp(s, "Stack", 5) != 0) + continue; + bos = strtoull(s+10, 0, 16); + if(size >= bos){ + fprint(2, "warning: memsize stack limited %lld\n", bos); + size = bos; + } + } + Bterm(b); + } + + /* malloc is limited */ +// if(sizeof(uintptr) < 8) + if (size >= 3840ull * 1024 * 1024) + size = 3840ull * 1024 * 1024; + return size; +} + static ulong freemem(void) { int nf, pgsize = 0; - uvlong size, userpgs = 0, userused = 0; + uvlong size, n, userpgs = 0, userused = 0; char *ln, *sl; - char *fields[2]; + char *fields[10]; Biobuf *bp; - size = 64*1024*1024; + size = 0; bp = Bopen("#c/swap", OREAD); if (bp != nil) { while ((ln = Brdline(bp, '\n')) != nil) { ln[Blinelen(bp)-1] = '\0'; nf = tokenize(ln, fields, nelem(fields)); - if (nf != 2) - continue; - if (strcmp(fields[1], "pagesize") == 0) + if (nf == 2 && strcmp(fields[1], "pagesize") == 0) pgsize = atoi(fields[0]); - else if (strcmp(fields[1], "user") == 0) { + else if (nf == 2 && strcmp(fields[1], "user") == 0) { sl = strchr(fields[0], '/'); if (sl == nil) continue; userpgs = atoll(sl+1); userused = atoll(fields[0]); } + else if (nf>2 && strcmp(fields[2], "user") == 0){ + /* nix */ + n = unittoull(fields[1]); + if(n == 0) + continue; + sl = strchr(fields[0], '/'); + if (sl == nil) + continue; + if(0)fprint(2, "size += (%lld - %lld)*%lld\n", atoll(sl+1), atoll(fields[0]), n); + size += (atoll(sl+1) - atoll(fields[0]))*n; + } + else if(nf>2 && strcmp(fields[1], "blocks") == 0){ + if(strcmp(fields[2], "avail") != 0) + continue; + /* nix: add in unpreallocated pages */ + sl = strchr(fields[0], '/'); + if (sl == nil) + continue; + n = unittoull(fields[3]); + if(n == 0) + continue; + if(0)fprint(2, "*size += %lld*%lld\n", atoll(sl+1), n); + size += atoll(sl+1)*n; + } } Bterm(bp); - if (pgsize > 0 && userpgs > 0 && userused > 0) + if (size == 0 && pgsize > 0 && userpgs > 0 && userused > 0) size = (userpgs - userused) * pgsize; } - /* cap it to keep the size within 32 bits */ - if (size >= 3840UL * 1024 * 1024) - size = 3840UL * 1024 * 1024; - return size; + if(size == 0) + size = 64*1024*1024; + return capmem(size); } static void @@ -97,8 +147,7 @@ fprint(2, "%s: bloom filter bigger than mem pcnt; " "resorting to minimum values (9MB total)\n", argv0); else { - if (avail >= 3840UL * 1024 * 1024) - avail = 3840UL * 1024 * 1024; /* sanity */ + avail = capmem(avail); avail /= 2; all.icmem = avail; avail /= 3; @@ -247,7 +296,7 @@ configfile = "venti.conf"; /* remember free memory before initventi & loadbloom, for auto-sizing */ - stfree = freemem(); + stfree = freemem(); fprint(2, "conf..."); if(initventi(configfile, &config) < 0) sysfatal("can't init server: %r");