kernel: add #0/brk and move brk_() to libc
This commit is contained in:
parent
0bbd79e0a5
commit
37541724d0
|
@ -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");
|
||||
}
|
|
@ -11,6 +11,7 @@
|
|||
"alarm.c",
|
||||
"args.c",
|
||||
"awake.c",
|
||||
"brk.c",
|
||||
"execl.c",
|
||||
"float.c",
|
||||
"fork.c",
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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*);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue