M gnot/trap.c => gnot/trap.c +1 -1
@@ 341,7 341,7 @@ syscall(Ureg *aur)
if(r0 == NOTED) /* ugly hack */
noted(aur, *(ulong*)(sp+BY2WD)); /* doesn't return */
splhi();
- if(r0!=FORK && (u->p->procctl || u->nnote)){
+ if(r0!=RFORK && (u->p->procctl || u->nnote)){
ur->r0 = ret;
notify(ur);
}
M pc/trap.c => pc/trap.c +1 -1
@@ 348,7 348,7 @@ syscall(Ureg *ur)
noted(ur, *(ulong*)(sp+BY2WD));
splhi(); /* avoid interrupts during the iret */
- if(ax!=FORK && (u->p->procctl || u->nnote))
+ if(ax!=RFORK && (u->p->procctl || u->nnote))
notify(ur);
return ret;
}
M pc/vga.c => pc/vga.c +27 -4
@@ 22,8 22,8 @@ struct{
/*
* screen dimensions
*/
-#define MAXX 640
-#define MAXY 480
+#define MAXX 800
+#define MAXY 600
#define SCREENMEM (0xA0000 | KZERO)
@@ 67,7 67,7 @@ struct VGAmode
};
/*
- * 640x480 display, 16 bit color - attempt at SVGA version...ches
+ * 640x480 display, 16 bit color.
*/
VGAmode mode12 =
{
@@ 89,6 89,29 @@ VGAmode mode12 =
0x01, 0x10, 0x0f, 0x00, 0x00,
};
+/*
+ * 800x600 display, 16 bit color
+ */
+VGAmode mode41 =
+{
+ /* general */
+ 0xe7, 0x00, /* 0x70, 0x04, these are read-only */
+ /* sequence */
+ 0x03, 0x01, 0x0f, 0x00, 0x06,
+ /* crt */
+ 0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
+ 0x00, 0x40, 0x0d, 0x0e, 0x00, 0x00, 0x07, 0x80,
+ 0x9c, 0x8e, 0x8f, 0x28, 0x1f, 0x96, 0xb9, 0xa3,
+ 0xff,
+ /* graphics */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f,
+ 0xff,
+ /* attribute */
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x3f,
+ 0x01, 0x10, 0x0f, 0x00, 0x00,
+};
+
void
genout(int reg, int val)
{
@@ 225,7 248,7 @@ screeninit(void)
int c;
ulong *l;
- setmode(&mode12);
+ setmode(&mode41);
/*
* swizzle the font longs.
M port/devproc.c => port/devproc.c +1 -1
@@ 34,7 34,7 @@ Dirtab procdir[]={
};
/* Segment type from portdat.h */
-char *sname[]={ "Text", "Data", "Bss", "Stack", "Shared", "Phys" };
+char *sname[]={ "Text", "Data", "Bss", "Stack", "Shared", "Phys", "Shdata" };
/*
* Qids are, in path:
M port/fault.c => port/fault.c +6 -5
@@ 69,21 69,21 @@ fixfault(Segment *s, ulong addr, int read, int doputmmu)
break;
case SG_TEXT:
- if(pagedout(*pg)) /* Demand load */
+ if(pagedout(*pg)) /* Demand load */
pio(s, addr, soff, pg);
mmuphys = PPN((*pg)->pa) | PTERONLY|PTEVALID;
(*pg)->modref = PG_REF;
break;
- case SG_SHDATA: /* Shared data */
+ case SG_SHDATA: /* Shared data */
if(pagedout(*pg))
pio(s, addr, soff, pg);
goto done;
- case SG_SHARED: /* Zero fill on demand */
case SG_BSS:
+ case SG_SHARED: /* Zero fill on demand */
case SG_STACK:
if(*pg == 0) {
if(new == 0)
@@ 96,14 96,15 @@ fixfault(Segment *s, ulong addr, int read, int doputmmu)
}
/* NO break */
- case SG_DATA: /* Demand load/pagein/copy on write */
+ case SG_DATA: /* Demand load/pagein/copy on write */
if(pagedout(*pg))
pio(s, addr, soff, pg);
if(type == SG_SHARED)
goto done;
- if(read && conf.copymode == 0) {
+ if(read)
+ if(conf.copymode == 0) {
mmuphys = PPN((*pg)->pa) | PTERONLY|PTEVALID;
(*pg)->modref |= PG_REF;
break;
M port/portdat.h => port/portdat.h +1 -9
@@ 447,15 447,6 @@ struct Waitq
Waitq *next;
};
-enum /* Argument to forkpgrp call */
-{
- FPall = 0, /* Concession to back portablility */
- FPnote = 1,
- FPnamespc = 2,
- FPenv = 4,
- FPclear = 8,
-};
-
enum
{
FORKNSG = (1<<0),
@@ 464,6 455,7 @@ enum
FORKNTG = (1<<3),
FORKPCS = (1<<4),
FORKMEM = (1<<5),
+ FORKNOW = (1<<6),
FORKCNSG = (1<<10),
FORKCEVG = (1<<11),
FORKCFDG = (1<<12)
M port/portfns.h => port/portfns.h +1 -1
@@ 52,7 52,7 @@ void dumpregs(Ureg*);
void dumpstack(void);
Fgrp* dupfgrp(Fgrp*);
void duppage(Page*);
-Segment* dupseg(Segment*);
+Segment* dupseg(Segment*, int);
void dupswap(Page*);
int encrypt(void*, void*, int);
void envcpy(Egrp*, Egrp*);
M port/segment.c => port/segment.c +18 -2
@@ 140,7 140,7 @@ relocateseg(Segment *s, ulong offset)
}
Segment*
-dupseg(Segment *s)
+dupseg(Segment *s, int share)
{
Pte *pte;
Segment *n;
@@ 154,14 154,30 @@ dupseg(Segment *s)
incref(s);
return s;
- case SG_BSS: /* Just copy on write */
case SG_STACK:
qlock(&s->lk);
n = newseg(s->type, s->base, s->size);
goto copypte;
+ case SG_BSS: /* Just copy on write */
+ qlock(&s->lk);
+ if(share && s->ref == 1) {
+ s->type = (s->type&~SG_TYPE)|SG_SHARED;
+ incref(s);
+ qunlock(&s->lk);
+ return s;
+ }
+ n = newseg(s->type, s->base, s->size);
+ goto copypte;
+
case SG_DATA: /* Copy on write plus demand load info */
qlock(&s->lk);
+ if(share && s->ref == 1) {
+ s->type = (s->type&~SG_TYPE)|SG_SHDATA;
+ incref(s);
+ qunlock(&s->lk);
+ return s;
+ }
n = newseg(s->type, s->base, s->size);
incref(s->image);
M port/sysproc.c => port/sysproc.c +47 -32
@@ 17,8 17,17 @@ sysr1(ulong *arg)
return 0;
}
+enum /* Argument to forkpgrp call */
+{
+ FPall = 0, /* Concession to back portablility */
+ FPnote = 1,
+ FPnamespc = 2,
+ FPenv = 4,
+ FPclear = 8,
+};
+
long
-sysfork(ulong *arg)
+sys__fork__(ulong *arg)
{
USED(arg);
return rfork(FORKFDG|FORKPCS);
@@ 40,7 49,7 @@ sysrfork(ulong *arg)
long
rfork(ulong flag)
{
- Proc *p;
+ Proc *p, *parent;
Segment *s;
ulong usp, upa, pid;
int n, on, i;
@@ 63,6 72,8 @@ rfork(ulong flag)
p->pgrp = newpgrp();
if(flag & FORKNSG)
pgrpcpy(p->pgrp, opg);
+ else
+ *p->pgrp->crypt = *opg->crypt;
closepgrp(opg);
}
if(flag & (FORKEVG|FORKCEVG)) {
@@ 83,12 94,20 @@ rfork(ulong flag)
}
if(flag & FORKNTG)
p->noteid = incref(¬eidalloc);
- if(flag & FORKMEM)
+ if(flag & (FORKMEM|FORKNOW))
error(Ebadarg);
return 0;
}
+ /* Check flags before we commit */
+ if((flag & (FORKFDG|FORKCFDG)) == (FORKFDG|FORKCFDG))
+ error(Ebadarg);
+ if((flag & (FORKNSG|FORKCNSG)) == (FORKNSG|FORKCNSG))
+ error(Ebadarg);
+ if((flag & (FORKEVG|FORKCEVG)) == (FORKEVG|FORKCEVG))
+ error(Ebadarg);
p = newproc();
+ parent = u->p;
/* Page va of upage used as check in mapstack */
p->upage = newpage(0, 0, USERADDR|(p->pid&0xFFFF));
@@ 104,67 123,61 @@ rfork(ulong flag)
kunmap(k);
/* Make a new set of memory segments */
+ n = flag & FORKMEM;
for(i = 0; i < NSEG; i++)
- if(u->p->seg[i])
- p->seg[i] = dupseg(u->p->seg[i]);
+ if(parent->seg[i])
+ p->seg[i] = dupseg(parent->seg[i], n);
/* Refs */
incref(u->dot);
- if(flag & FORKMEM)
- error(Egreg);
-
/* File descriptors */
if(flag & (FORKFDG|FORKCFDG)) {
- if((flag & (FORKFDG|FORKCFDG)) == (FORKFDG|FORKCFDG))
- error(Ebadarg);
if(flag & FORKFDG)
- p->fgrp = dupfgrp(u->p->fgrp);
+ p->fgrp = dupfgrp(parent->fgrp);
else
if(flag & FORKCFDG)
p->fgrp = newfgrp();
}
else {
- p->fgrp = u->p->fgrp;
+ p->fgrp = parent->fgrp;
incref(p->fgrp);
}
/* Process groups */
if(flag & (FORKNSG|FORKCNSG)) {
- if((flag & (FORKNSG|FORKCNSG)) == (FORKNSG|FORKCNSG))
- error(Ebadarg);
if(flag & FORKNSG) {
p->pgrp = newpgrp();
- pgrpcpy(p->pgrp, u->p->pgrp);
+ pgrpcpy(p->pgrp, parent->pgrp);
}
else
- if(flag & FORKCNSG)
+ if(flag & FORKCNSG) {
p->pgrp = newpgrp();
+ *p->pgrp->crypt = *parent->pgrp->crypt;
+ }
}
else {
- p->pgrp = u->p->pgrp;
+ p->pgrp = parent->pgrp;
incref(p->pgrp);
}
/* Environment group */
if(flag & (FORKEVG|FORKCEVG)) {
- if((flag & (FORKEVG|FORKCEVG)) == (FORKEVG|FORKCEVG))
- error(Ebadarg);
if(flag & FORKEVG) {
p->egrp = newegrp();
- envcpy(p->egrp, u->p->egrp);
+ envcpy(p->egrp, parent->egrp);
}
else
if(flag & FORKCEVG)
p->egrp = newegrp();
}
else {
- p->egrp = u->p->egrp;
+ p->egrp = parent->egrp;
incref(p->egrp);
}
- p->hang = u->p->hang;
- p->procmode = u->p->procmode;
+ p->hang = parent->hang;
+ p->procmode = parent->procmode;
if(setlabel(&p->sched)){
/*
@@ 179,20 192,22 @@ rfork(ulong flag)
return 0;
}
- p->parent = u->p;
- p->parentpid = u->p->pid;
+ p->parent = parent;
+ p->parentpid = parent->pid;
+ if(flag&FORKNOW)
+ p->parentpid = 1;
if((flag&FORKNTG) == 0)
- p->noteid = u->p->noteid;
+ p->noteid = parent->noteid;
- p->fpstate = u->p->fpstate;
- lock(&u->p->exl);
- u->p->nchild++;
- unlock(&u->p->exl);
+ p->fpstate = parent->fpstate;
+ lock(&parent->exl);
+ parent->nchild++;
+ unlock(&parent->exl);
pid = p->pid;
memset(p->time, 0, sizeof(p->time));
p->time[TReal] = MACHP(0)->ticks;
- memmove(p->text, u->p->text, NAMELEN);
- memmove(p->user, u->p->user, NAMELEN);
+ memmove(p->text, parent->text, NAMELEN);
+ memmove(p->user, parent->user, NAMELEN);
/*
* since the bss/data segments are now shareable,
* any mmu info about this process is now stale
M port/systab.h => port/systab.h +3 -3
@@ 12,7 12,7 @@ Syscall sysdup;
Syscall sysalarm;
Syscall sysexec;
Syscall sysexits;
-Syscall sysfork;
+Syscall sys__fork__;
Syscall sysforkpgrp;
Syscall sysfstat;
Syscall syssegbrk;
@@ 51,7 51,7 @@ Syscall *systab[]={
[ALARM] sysalarm,
[EXEC] sysexec,
[EXITS] sysexits,
- [FORK] sysfork,
+ [__FORK__] sys__fork__,
[FORKPGRP] sysforkpgrp,
[FSTAT] sysfstat,
[SEGBRK] syssegbrk,
@@ 91,7 91,7 @@ char *sysctab[]={
[ALARM] "Alarm",
[EXEC] "Exec",
[EXITS] "Exits",
- [FORK] "Fork",
+ [__FORK__] "__fork_",
[FORKPGRP] "Forkpgrp",
[FSTAT] "Fstat",
[SEGBRK] "Segbrk",
M power/trap.c => power/trap.c +1 -1
@@ 550,7 550,7 @@ syscall(Ureg *aur)
if(r1 == NOTED) /* ugly hack */
noted(&aur, *(ulong*)(sp+BY2WD)); /* doesn't return */
splhi();
- if(r1!=FORK && (u->nnote || p->procctl)){
+ if(r1!=RFORK && (p->procctl || u->nnote)){
ur->r1 = ret; /* load up for noted() */
if(notify(ur))
return ur->r1;
M ss/trap.c => ss/trap.c +1 -1
@@ 410,7 410,7 @@ syscall(Ureg *aur)
noted(&aur, *(ulong*)(sp+1*BY2WD)); /* doesn't return */
splhi();
- if(r7!=FORK && (u->p->procctl || u->nnote)){
+ if(r7!=RFORK && (u->p->procctl || u->nnote)){
ur->r7 = ret; /* load up for noted() */
if(notify(ur))
return ur->r7;