xref: /plan9-contrib/sys/src/9k/k10/arch.c (revision e364617b1a51ecd9aea3d1363ca48190e1d6c4a0)
1 /*
2  * EPISODE 12B
3  * How to recognise different types of trees from quite a long way away.
4  * NO. 1
5  * THE LARCH
6  */
7 #include "u.h"
8 #include "../port/lib.h"
9 #include "mem.h"
10 #include "dat.h"
11 #include "fns.h"
12 #include "../port/error.h"
13 
14 #ifndef incref
15 int
incref(Ref * r)16 incref(Ref *r)
17 {
18 	int x;
19 
20 	lock(r);
21 	x = ++r->ref;
22 	unlock(r);
23 	return x;
24 }
25 #endif /* incref */
26 
27 #ifndef decref
28 int
decref(Ref * r)29 decref(Ref *r)
30 {
31 	int x;
32 
33 	lock(r);
34 	x = --r->ref;
35 	unlock(r);
36 	if(x < 0)
37 		panic("decref pc=%#p", getcallerpc(&r));
38 
39 	return x;
40 }
41 #endif /* decref */
42 
43 void
procrestore(Proc * p)44 procrestore(Proc *p)
45 {
46 	uvlong t;
47 
48 	if(p->kp)
49 		return;
50 	cycles(&t);
51 	p->pcycles -= t;
52 
53 	fpuprocrestore(p);
54 }
55 
56 /*
57  *  Save the mach dependent part of the process state.
58  */
59 void
procsave(Proc * p)60 procsave(Proc *p)
61 {
62 	uvlong t;
63 
64 	cycles(&t);
65 	p->pcycles += t;
66 
67 	fpuprocsave(p);
68 
69 	/*
70 	 */
71 	mmuflushtlb(m->pml4->pa);
72 }
73 
74 static void
linkproc(void)75 linkproc(void)
76 {
77 	spllo();
78 	up->kpfun(up->kparg);
79 	pexit("kproc dying", 0);
80 }
81 
82 void
kprocchild(Proc * p,void (* func)(void *),void * arg)83 kprocchild(Proc* p, void (*func)(void*), void* arg)
84 {
85 	/*
86 	 * gotolabel() needs a word on the stack in
87 	 * which to place the return PC used to jump
88 	 * to linkproc().
89 	 */
90 	p->sched.pc = PTR2UINT(linkproc);
91 	p->sched.sp = PTR2UINT(p->kstack+KSTACK-BY2SE);
92 	p->sched.sp = STACKALIGN(p->sched.sp);
93 
94 	p->kpfun = func;
95 	p->kparg = arg;
96 }
97 
98 static int idle_spin;
99 
100 /*
101  *  put the processor in the halt state if we've no processes to run.
102  *  an interrupt will get us going again.
103  */
104 void
idlehands(void)105 idlehands(void)
106 {
107 	/*
108 	 * we used to halt only on single-core setups. halting in an smp system
109 	 * can result in a startup latency for processes that become ready.
110 	 * if idle_spin is zero, we care more about saving energy
111 	 * than reducing this latency.
112 	 *
113 	 * the performance loss with idle_spin == 0 seems to be slight
114 	 * and it reduces lock contention (thus system time and real time)
115 	 * on many-core systems with large values of NPROC.
116 	 */
117 	if(sys->nonline == 1 || idle_spin == 0)
118 		halt();
119 }
120