merge
This commit is contained in:
commit
35d19fc6fb
4 changed files with 142 additions and 156 deletions
|
@ -1133,3 +1133,62 @@ timerset(Tval x)
|
|||
if(doi8253set)
|
||||
(*arch->timerset)(x);
|
||||
}
|
||||
|
||||
/*
|
||||
* put the processor in the halt state if we've no processes to run.
|
||||
* an interrupt will get us going again.
|
||||
*
|
||||
* halting in an smp system can result in a startup latency for
|
||||
* processes that become ready.
|
||||
* if idle_spin is zero, we care more about saving energy
|
||||
* than reducing this latency.
|
||||
*
|
||||
* the performance loss with idle_spin == 0 seems to be slight
|
||||
* and it reduces lock contention (thus system time and real time)
|
||||
* on many-core systems with large values of NPROC.
|
||||
*/
|
||||
void
|
||||
idlehands(void)
|
||||
{
|
||||
extern int nrdy, idle_spin;
|
||||
|
||||
if(conf.nmach == 1)
|
||||
halt();
|
||||
else if(m->cpuidcx & Monitor)
|
||||
mwait(&nrdy);
|
||||
else if(idle_spin == 0)
|
||||
halt();
|
||||
}
|
||||
|
||||
int
|
||||
isaconfig(char *class, int ctlrno, ISAConf *isa)
|
||||
{
|
||||
char cc[32], *p;
|
||||
int i;
|
||||
|
||||
snprint(cc, sizeof cc, "%s%d", class, ctlrno);
|
||||
p = getconf(cc);
|
||||
if(p == nil)
|
||||
return 0;
|
||||
|
||||
isa->type = "";
|
||||
isa->nopt = tokenize(p, isa->opt, NISAOPT);
|
||||
for(i = 0; i < isa->nopt; i++){
|
||||
p = isa->opt[i];
|
||||
if(cistrncmp(p, "type=", 5) == 0)
|
||||
isa->type = p + 5;
|
||||
else if(cistrncmp(p, "port=", 5) == 0)
|
||||
isa->port = strtoul(p+5, &p, 0);
|
||||
else if(cistrncmp(p, "irq=", 4) == 0)
|
||||
isa->irq = strtoul(p+4, &p, 0);
|
||||
else if(cistrncmp(p, "dma=", 4) == 0)
|
||||
isa->dma = strtoul(p+4, &p, 0);
|
||||
else if(cistrncmp(p, "mem=", 4) == 0)
|
||||
isa->mem = strtoul(p+4, &p, 0);
|
||||
else if(cistrncmp(p, "size=", 5) == 0)
|
||||
isa->size = strtoul(p+5, &p, 0);
|
||||
else if(cistrncmp(p, "freq=", 5) == 0)
|
||||
isa->freq = strtoul(p+5, &p, 0);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -1000,109 +1000,3 @@ exit(int ispanic)
|
|||
shutdown(ispanic);
|
||||
arch->reset();
|
||||
}
|
||||
|
||||
int
|
||||
isaconfig(char *class, int ctlrno, ISAConf *isa)
|
||||
{
|
||||
char cc[32], *p;
|
||||
int i;
|
||||
|
||||
snprint(cc, sizeof cc, "%s%d", class, ctlrno);
|
||||
p = getconf(cc);
|
||||
if(p == nil)
|
||||
return 0;
|
||||
|
||||
isa->type = "";
|
||||
isa->nopt = tokenize(p, isa->opt, NISAOPT);
|
||||
for(i = 0; i < isa->nopt; i++){
|
||||
p = isa->opt[i];
|
||||
if(cistrncmp(p, "type=", 5) == 0)
|
||||
isa->type = p + 5;
|
||||
else if(cistrncmp(p, "port=", 5) == 0)
|
||||
isa->port = strtoul(p+5, &p, 0);
|
||||
else if(cistrncmp(p, "irq=", 4) == 0)
|
||||
isa->irq = strtoul(p+4, &p, 0);
|
||||
else if(cistrncmp(p, "dma=", 4) == 0)
|
||||
isa->dma = strtoul(p+4, &p, 0);
|
||||
else if(cistrncmp(p, "mem=", 4) == 0)
|
||||
isa->mem = strtoul(p+4, &p, 0);
|
||||
else if(cistrncmp(p, "size=", 5) == 0)
|
||||
isa->size = strtoul(p+5, &p, 0);
|
||||
else if(cistrncmp(p, "freq=", 5) == 0)
|
||||
isa->freq = strtoul(p+5, &p, 0);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
cistrcmp(char *a, char *b)
|
||||
{
|
||||
int ac, bc;
|
||||
|
||||
for(;;){
|
||||
ac = *a++;
|
||||
bc = *b++;
|
||||
|
||||
if(ac >= 'A' && ac <= 'Z')
|
||||
ac = 'a' + (ac - 'A');
|
||||
if(bc >= 'A' && bc <= 'Z')
|
||||
bc = 'a' + (bc - 'A');
|
||||
ac -= bc;
|
||||
if(ac)
|
||||
return ac;
|
||||
if(bc == 0)
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
cistrncmp(char *a, char *b, int n)
|
||||
{
|
||||
unsigned ac, bc;
|
||||
|
||||
while(n > 0){
|
||||
ac = *a++;
|
||||
bc = *b++;
|
||||
n--;
|
||||
|
||||
if(ac >= 'A' && ac <= 'Z')
|
||||
ac = 'a' + (ac - 'A');
|
||||
if(bc >= 'A' && bc <= 'Z')
|
||||
bc = 'a' + (bc - 'A');
|
||||
|
||||
ac -= bc;
|
||||
if(ac)
|
||||
return ac;
|
||||
if(bc == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* put the processor in the halt state if we've no processes to run.
|
||||
* an interrupt will get us going again.
|
||||
*
|
||||
* halting in an smp system can result in a startup latency for
|
||||
* processes that become ready.
|
||||
* if idle_spin is zero, we care more about saving energy
|
||||
* than reducing this latency.
|
||||
*
|
||||
* the performance loss with idle_spin == 0 seems to be slight
|
||||
* and it reduces lock contention (thus system time and real time)
|
||||
* on many-core systems with large values of NPROC.
|
||||
*/
|
||||
void
|
||||
idlehands(void)
|
||||
{
|
||||
extern int nrdy;
|
||||
|
||||
if(conf.nmach == 1)
|
||||
halt();
|
||||
else if(m->cpuidcx & Monitor)
|
||||
mwait(&nrdy);
|
||||
else if(idle_spin == 0)
|
||||
halt();
|
||||
}
|
||||
|
|
|
@ -331,10 +331,20 @@ TEXT mb586(SB), 1, $-4
|
|||
CPUID
|
||||
RET
|
||||
|
||||
/*
|
||||
* Park a processor. Should never fall through a return from main to here,
|
||||
* should only be called by application processors when shutting down.
|
||||
*/
|
||||
TEXT idle(SB), 1, $-4
|
||||
_idle:
|
||||
STI
|
||||
HLT
|
||||
JMP _idle
|
||||
|
||||
/*
|
||||
* BIOS32.
|
||||
*/
|
||||
TEXT bios32call(SB), 1, $-1
|
||||
TEXT bios32call(SB), 1, $-4
|
||||
XORL AX, AX
|
||||
INCL AX
|
||||
RET
|
||||
|
@ -526,14 +536,30 @@ TEXT setlabel(SB), 1, $-4
|
|||
MOVL $0, AX /* return 0 */
|
||||
RET
|
||||
|
||||
TEXT idle(SB), $0
|
||||
_idle:
|
||||
TEXT halt(SB), 1, $-4
|
||||
CLI
|
||||
CMPL nrdy(SB), $0
|
||||
JEQ _nothingready
|
||||
STI
|
||||
RET
|
||||
_nothingready:
|
||||
STI
|
||||
HLT
|
||||
JMP _idle
|
||||
RET
|
||||
|
||||
TEXT halt(SB), 1, $-4
|
||||
HLT
|
||||
TEXT mwait(SB), 1, $-4
|
||||
MOVQ RARG, AX
|
||||
MOVL (AX), CX
|
||||
ORL CX, CX
|
||||
JNZ _mwaitdone
|
||||
XORL DX, DX
|
||||
BYTE $0x0f; BYTE $0x01; BYTE $0xc8 /* MONITOR */
|
||||
MOVL (AX), CX
|
||||
ORL CX, CX
|
||||
JNZ _mwaitdone
|
||||
XORL AX, AX
|
||||
BYTE $0x0f; BYTE $0x01; BYTE $0xc9 /* MWAIT */
|
||||
_mwaitdone:
|
||||
RET
|
||||
|
||||
/*
|
||||
|
|
|
@ -26,6 +26,8 @@ char *confname[MAXCONF];
|
|||
char *confval[MAXCONF];
|
||||
int nconf;
|
||||
int delaylink;
|
||||
int idle_spin;
|
||||
|
||||
uchar *sp; /* user stack of init proc */
|
||||
|
||||
extern void (*i8237alloc)(void);
|
||||
|
@ -419,12 +421,56 @@ main()
|
|||
schedinit();
|
||||
}
|
||||
|
||||
void
|
||||
exit(int)
|
||||
static void
|
||||
shutdown(int ispanic)
|
||||
{
|
||||
print("exit\n");
|
||||
splhi();
|
||||
for(;;);
|
||||
int ms, once;
|
||||
|
||||
lock(&active);
|
||||
if(ispanic)
|
||||
active.ispanic = ispanic;
|
||||
else if(m->machno == 0 && (active.machs & (1<<m->machno)) == 0)
|
||||
active.ispanic = 0;
|
||||
once = active.machs & (1<<m->machno);
|
||||
/*
|
||||
* setting exiting will make hzclock() on each processor call exit(0),
|
||||
* which calls shutdown(0) and arch->reset(), which on mp systems is
|
||||
* mpshutdown, from which there is no return: the processor is idled
|
||||
* or initiates a reboot. clearing our bit in machs avoids calling
|
||||
* exit(0) from hzclock() on this processor.
|
||||
*/
|
||||
active.machs &= ~(1<<m->machno);
|
||||
active.exiting = 1;
|
||||
unlock(&active);
|
||||
|
||||
if(once)
|
||||
iprint("cpu%d: exiting\n", m->machno);
|
||||
|
||||
/* wait for any other processors to shutdown */
|
||||
spllo();
|
||||
for(ms = 5*1000; ms > 0; ms -= TK2MS(2)){
|
||||
delay(TK2MS(2));
|
||||
if(active.machs == 0 && consactive() == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if(active.ispanic){
|
||||
if(!cpuserver)
|
||||
for(;;)
|
||||
halt();
|
||||
if(getconf("*debug"))
|
||||
delay(5*60*1000);
|
||||
else
|
||||
delay(10000);
|
||||
}else
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
void
|
||||
exit(int ispanic)
|
||||
{
|
||||
shutdown(ispanic);
|
||||
arch->reset();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -433,12 +479,6 @@ reboot(void*, void*, ulong)
|
|||
exit(0);
|
||||
}
|
||||
|
||||
void
|
||||
idlehands(void)
|
||||
{
|
||||
halt();
|
||||
}
|
||||
|
||||
/*
|
||||
* SIMD Floating Point.
|
||||
* Assembler support to get at the individual instructions
|
||||
|
@ -707,36 +747,3 @@ procsave(Proc *p)
|
|||
*/
|
||||
mmuflushtlb();
|
||||
}
|
||||
|
||||
int
|
||||
isaconfig(char *class, int ctlrno, ISAConf *isa)
|
||||
{
|
||||
char cc[32], *p;
|
||||
int i;
|
||||
|
||||
snprint(cc, sizeof cc, "%s%d", class, ctlrno);
|
||||
p = getconf(cc);
|
||||
if(p == nil)
|
||||
return 0;
|
||||
|
||||
isa->type = "";
|
||||
isa->nopt = tokenize(p, isa->opt, NISAOPT);
|
||||
for(i = 0; i < isa->nopt; i++){
|
||||
p = isa->opt[i];
|
||||
if(cistrncmp(p, "type=", 5) == 0)
|
||||
isa->type = p + 5;
|
||||
else if(cistrncmp(p, "port=", 5) == 0)
|
||||
isa->port = strtoul(p+5, &p, 0);
|
||||
else if(cistrncmp(p, "irq=", 4) == 0)
|
||||
isa->irq = strtoul(p+4, &p, 0);
|
||||
else if(cistrncmp(p, "dma=", 4) == 0)
|
||||
isa->dma = strtoul(p+4, &p, 0);
|
||||
else if(cistrncmp(p, "mem=", 4) == 0)
|
||||
isa->mem = strtoul(p+4, &p, 0);
|
||||
else if(cistrncmp(p, "size=", 5) == 0)
|
||||
isa->size = strtoul(p+5, &p, 0);
|
||||
else if(cistrncmp(p, "freq=", 5) == 0)
|
||||
isa->freq = strtoul(p+5, &p, 0);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue