kernel: add #0/brk and move brk_() to libc

This commit is contained in:
Giacomo Tesio 2016-12-31 00:43:02 +01:00
parent 0bbd79e0a5
commit 37541724d0
10 changed files with 173 additions and 157 deletions

46
qa/kern/brk.c Normal file
View File

@ -0,0 +1,46 @@
/*
* This file is part of Jehanne.
*
* Copyright (C) 2016 Giacomo Tesio <giacomo@tesio.it>
*
* Jehanne is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 2 of the License.
*
* Jehanne is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Jehanne. If not, see <http://www.gnu.org/licenses/>.
*/
#include <u.h>
#include <libc.h>
void
main(void)
{
long b, b1;
b = create("#0/brk", -1, 16*1024*1024);
if(b >= 0){
print("FAIL: create returned fd %d.\n", b);
exits("FAIL");
}
if(b == -1){
print("FAIL: create: %r.\n");
exits("FAIL");
}
b1 = brk((void*)b + 16*1024*1024);
if(b1 == -1){
print("FAIL: brk: %r.\n");
exits("FAIL");
}
if(b >= b1){
print("FAIL: b >= b1.\n");
exits("FAIL");
}
print("PASS\n");
exits("PASS");
}

View File

@ -11,6 +11,7 @@
"alarm.c",
"args.c",
"awake.c",
"brk.c",
"execl.c",
"float.c",
"fork.c",

View File

@ -1214,7 +1214,7 @@ nameerror(char *name, char *err)
* correct name so they can rewrite the stat info.
*/
Chan*
namec(char *aname, int amode, int omode, int perm)
namec(char *aname, int amode, long omode, long perm)
{
int len, n, nomount;
Chan *c, *cnew;
@ -1479,6 +1479,7 @@ namec(char *aname, int amode, int omode, int perm)
*/
e.nelems++;
e.nerror++;
if(omode >=0) /* a negative omode means this is a message for the server */
if(walk(&c, e.elems+e.nelems-1, 1, nomount, nil) == 0)
error(Eexist);

View File

@ -15,12 +15,12 @@
* You should have received a copy of the GNU General Public License
* along with Jehanne. If not, see <http://www.gnu.org/licenses/>.
*/
#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "../port/error.h"
#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "../port/error.h"
#define QID(q) ((((uint32_t)(q).path)&0x0000001F)>>0)
#define STATSIZE (2*KNAMELEN+NUMSIZE+9*NUMSIZE + 1)
@ -33,6 +33,7 @@ typedef enum SelfNodes
Qdir,
/* Process control */
Qbrk,
Qpid,
Qppid,
Qpgrpid,
@ -63,6 +64,7 @@ typedef union PipeSet
static Dirtab selfdir[]={
".", {Qdir, 0, QTDIR}, 0, DMDIR|0777,
"brk", {Qbrk}, 0, 0,
"pid", {Qpid}, 0, 0,
"ppid", {Qppid}, 0, 0,
"pgrpid", {Qpgrpid}, 0, 0,
@ -117,6 +119,84 @@ selfattach(Chan *c, Chan *ac, char *spec, int flags)
return devattach('0', spec);
}
static uintptr_t
grow_bss(uintptr_t addr)
{
ProcSegment *s, *ns;
uintptr_t newtop;
long newsize;
int i;
s = up->seg[BSEG];
if(s == nil)
panic("grow_bss: no bss segment");
if(addr == 0)
return s->top;
qlock(&s->ql);
if(waserror()){
qunlock(&s->ql);
nexterror();
}
DBG("grow_bss addr %#p base %#p top %#p\n",
addr, s->base, s->top);
/* We may start with the bss overlapping the data */
if(addr < s->base) {
if(up->seg[DSEG] == 0 || addr < up->seg[DSEG]->base)
error(Enovmem);
addr = s->base;
}
newtop = ROUNDUP(addr, PGSZ);
newsize = (newtop - s->table->base)/PGSZ;
DBG("grow_bss addr %#p newtop %#p newsize %ld\n", addr, newtop, newsize);
if(newtop < s->top) {
/* for simplicity we only allow the bss to grow,
* memory will be freed on process exit
*/
panic("grow_bss: shrinking bss");
}
rlock(&up->seglock);
for(i = 0; i < NSEG; i++) {
ns = up->seg[i];
if(ns == 0 || ns == s)
continue;
if(newtop >= ns->base && newtop < ns->top){
runlock(&up->seglock);
error(Esoverlap);
}
}
runlock(&up->seglock);
if(!umem_available(newtop - s->top))
error(Enovmem);
if(!segment_grow(s, newtop))
error(Enovmem);
poperror();
qunlock(&s->ql);
return s->top;
}
static Chan*
selfcreate(Chan* c, char* name, unsigned long omode, unsigned long perm)
{
long e;
if(strcmp(name, "brk") == 0){
e = (long)grow_bss(perm);
errorl("brk set", ~e);
}
error(Eperm);
}
static Walkqid*
selfwalk(Chan *c, Chan *nc, char **name, int nname)
{
@ -483,7 +563,7 @@ Dev selfdevtab = {
selfwalk,
selfstat,
selfopen,
devcreate,
selfcreate,
selfclose,
selfread,
devbread,

View File

@ -73,7 +73,6 @@
"../port/syscallfmt.c",
"../port/sysfile.c",
"../port/sysproc.c",
"../port/sysseg.c",
"../port/tod.c",
"../port/uidgid.c",
"../port/usbehci.c"

View File

@ -214,7 +214,7 @@ int mregfmt(Fmt*);
uint64_t ms2fastticks(uint32_t);
void mul64fract(uint64_t*, uint64_t, uint64_t);
void muxclose(Mnt*);
Chan* namec(char*, int, int, int);
Chan* namec(char*, int, long, long);
void nameerror(char*, char*);
Chan* newchan(void);
int newfd(Chan*);

View File

@ -1025,12 +1025,13 @@ sysunmount(char* name, char* old)
}
int
syscreate(char* aname, uint32_t omode, uint32_t perm)
syscreate(char* aname, long omode, long perm)
{
int fd;
Chan *c;
openmode(omode); /* error check only; OEXCL okay here */
if(omode >= 0)
openmode(omode); /* error check only */
c = nil;
if(waserror()) {
if(c != nil)

View File

@ -1,104 +0,0 @@
/*
* This file is part of Jehanne.
*
* Copyright (C) 2015-2016 Giacomo Tesio <giacomo@tesio.it>
*
* Jehanne is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 2 of the License.
*
* Jehanne is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Jehanne. If not, see <http://www.gnu.org/licenses/>.
*/
#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "../port/error.h"
uintptr_t
grow_bss(uintptr_t addr)
{
ProcSegment *s, *ns;
uintptr_t newtop;
long newsize;
int i;
s = up->seg[BSEG];
if(s == nil)
panic("grow_bss: no bss segment");
if(addr == 0)
return s->top;
qlock(&s->ql);
if(waserror()){
qunlock(&s->ql);
nexterror();
}
DBG("grow_bss addr %#p base %#p top %#p\n",
addr, s->base, s->top);
/* We may start with the bss overlapping the data */
if(addr < s->base) {
if(up->seg[DSEG] == 0 || addr < up->seg[DSEG]->base)
error(Enovmem);
addr = s->base;
}
newtop = ROUNDUP(addr, PGSZ);
newsize = (newtop - s->table->base)/PGSZ;
DBG("grow_bss addr %#p newtop %#p newsize %ld\n", addr, newtop, newsize);
if(newtop < s->top) {
/* for simplicity we only allow the bss to grow,
* memory will be freed on process exit
*/
panic("grow_bss: shrinking bss");
}
rlock(&up->seglock);
for(i = 0; i < NSEG; i++) {
ns = up->seg[i];
if(ns == 0 || ns == s)
continue;
if(newtop >= ns->base && newtop < ns->top){
runlock(&up->seglock);
error(Esoverlap);
}
}
runlock(&up->seglock);
if(!umem_available(newtop - s->top))
error(Enovmem);
if(!segment_grow(s, newtop))
error(Enovmem);
poperror();
qunlock(&s->ql);
return s->top;
}
uintptr_t
sysbrk_(void* addrp)
{
uintptr_t addr;
addr = PTR2UINT(addrp);
/* NOTE: this assumes that a bss segment ALWAYS exists.
* Thus we always add one on sysexec (see sysproc.c).
*/
grow_bss(addr);
return 0;
}

View File

@ -18,13 +18,15 @@ enum
Round = 7
};
#define brk_(p) ((uintptr_t)~create("#0/brk", -1, p))
int
brk(void *p)
{
uintptr_t bl;
bl = ((uintptr_t)p + Round) & ~Round;
if(brk_((void*)bl) < 0)
if(brk_(bl) < 0)
return -1;
bloc = (char*)bl;
return 0;
@ -36,7 +38,7 @@ sbrk(uint32_t n)
uintptr_t bl;
bl = ((uintptr_t)bloc + Round) & ~Round;
if(brk_((void*)(bl+n)) < 0)
if(brk_(bl+n) < 0)
return (void*)-1;
bloc = (char*)bl + n;
return (void*)bl;

View File

@ -53,21 +53,11 @@
"int"
]
},
{
"Args": [
"const void*"
],
"Id": 3,
"Name": "brk_",
"Ret": [
"uintptr_t"
]
},
{
"Args": [
"int"
],
"Id": 4,
"Id": 3,
"Name": "close",
"Ret": [
"long"
@ -76,10 +66,10 @@
{
"Args": [
"const char*",
"uint32_t",
"uint32_t"
"long",
"long"
],
"Id": 5,
"Id": 4,
"Name": "create",
"Ret": [
"long"
@ -90,7 +80,7 @@
"int32_t",
"int32_t"
],
"Id": 6,
"Id": 5,
"Name": "dup",
"Ret": [
"int32_t"
@ -101,7 +91,7 @@
"char*",
"int"
],
"Id": 7,
"Id": 6,
"Name": "errstr",
"Ret": [
"int"
@ -112,7 +102,7 @@
"const char*",
"const char**"
],
"Id": 8,
"Id": 7,
"Name": "exec",
"Ret": [
"uintptr_t"
@ -122,7 +112,7 @@
"Args": [
"const char*"
],
"Id": 9,
"Id": 8,
"Name": "_exits",
"Ret": [
"int"
@ -133,7 +123,7 @@
"int",
"const char*"
],
"Id": 10,
"Id": 9,
"Name": "fauth",
"Ret": [
"int"
@ -145,7 +135,7 @@
"const char*",
"uint32_t"
],
"Id": 11,
"Id": 10,
"Name": "fd2path",
"Ret": [
"int32_t"
@ -157,7 +147,7 @@
"uint8_t*",
"int"
],
"Id": 12,
"Id": 11,
"Name": "fstat",
"Ret": [
"long"
@ -170,7 +160,7 @@
"const char*",
"int"
],
"Id": 13,
"Id": 12,
"Name": "fversion",
"Ret": [
"int"
@ -182,7 +172,7 @@
"const uint8_t*",
"uint32_t"
],
"Id": 14,
"Id": 13,
"Name": "fwstat",
"Ret": [
"long"
@ -197,7 +187,7 @@
"const char*",
"int"
],
"Id": 15,
"Id": 14,
"Name": "mount",
"Ret": [
"int"
@ -207,7 +197,7 @@
"Args": [
"int"
],
"Id": 16,
"Id": 15,
"Name": "noted",
"Ret": [
"int"
@ -217,14 +207,14 @@
"Args": [
"const void*"
],
"Id": 17,
"Id": 16,
"Name": "notify",
"Ret": [
"int"
]
},
{
"Id": 18,
"Id": 17,
"Name": "nsec",
"Ret": [
"long"
@ -235,7 +225,7 @@
"const char*",
"uint32_t"
],
"Id": 19,
"Id": 18,
"Name": "open",
"Ret": [
"long"
@ -248,7 +238,7 @@
"long",
"long"
],
"Id": 20,
"Id": 19,
"Name": "pread",
"Ret": [
"long"
@ -261,7 +251,7 @@
"long",
"long"
],
"Id": 21,
"Id": 20,
"Name": "pwrite",
"Ret": [
"long"
@ -271,7 +261,7 @@
"Args": [
"const char*"
],
"Id": 22,
"Id": 21,
"Name": "remove",
"Ret": [
"long"
@ -282,7 +272,7 @@
"const void*",
"void*"
],
"Id": 23,
"Id": 22,
"Name": "rendezvous",
"Ret": [
"void*"
@ -292,7 +282,7 @@
"Args": [
"uint32_t"
],
"Id": 24,
"Id": 23,
"Name": "rfork",
"Ret": [
"int"
@ -304,7 +294,7 @@
"long",
"int"
],
"Id": 25,
"Id": 24,
"Name": "seek",
"Ret": [
"long"
@ -315,7 +305,7 @@
"int*",
"int"
],
"Id": 26,
"Id": 25,
"Name": "semacquire",
"Ret": [
"int"
@ -326,7 +316,7 @@
"int*",
"int"
],
"Id": 27,
"Id": 26,
"Name": "semrelease",
"Ret": [
"int"
@ -337,7 +327,7 @@
"int*",
"uint64_t"
],
"Id": 28,
"Id": 27,
"Name": "tsemacquire",
"Ret": [
"int"
@ -348,7 +338,7 @@
"const char*",
"const char*"
],
"Id": 29,
"Id": 28,
"Name": "unmount",
"Ret": [
"int"
@ -358,7 +348,7 @@
"Args": [
"unsigned long"
],
"Id": 30,
"Id": 29,
"Name": "alarm",
"Ret": [
"long"