proc.c 24 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468
  1. #include <u.h>
  2. #include "../port/lib.h"
  3. #include "mem.h"
  4. #include "dat.h"
  5. #include "fns.h"
  6. #include "../port/error.h"
  7. #include "edf.h"
  8. #include <trace.h>
  9. int nrdy;
  10. Ref noteidalloc;
  11. long delayedscheds; /* statistics */
  12. static Ref pidalloc;
  13. static struct Procalloc
  14. {
  15. Lock;
  16. Proc* ht[128];
  17. Proc* arena;
  18. Proc* free;
  19. } procalloc;
  20. enum
  21. {
  22. Q=(HZ/20)*4,
  23. DQ=((HZ-Q)/40)*2,
  24. };
  25. Schedq runq[Nrq];
  26. ulong runvec;
  27. static int quanta[Npriq] =
  28. {
  29. Q+19*DQ, Q+18*DQ, Q+17*DQ, Q+16*DQ,
  30. Q+15*DQ, Q+14*DQ, Q+13*DQ, Q+12*DQ,
  31. Q+11*DQ, Q+10*DQ, Q+ 9*DQ, Q+ 8*DQ,
  32. Q+ 7*DQ, Q+ 6*DQ, Q+ 5*DQ, Q+ 4*DQ,
  33. Q+ 3*DQ, Q+ 2*DQ, Q+ 1*DQ, Q+ 0*DQ,
  34. };
  35. char *statename[] =
  36. { /* BUG: generate automatically */
  37. "Dead",
  38. "Moribund",
  39. "Ready",
  40. "Scheding",
  41. "Running",
  42. "Queueing",
  43. "QueueingR",
  44. "QueueingW",
  45. "Wakeme",
  46. "Broken",
  47. "Stopped",
  48. "Rendez",
  49. "Waitrelease",
  50. };
  51. static void pidhash(Proc*);
  52. static void pidunhash(Proc*);
  53. /*
  54. * Always splhi()'ed.
  55. */
  56. void
  57. schedinit(void) /* never returns */
  58. {
  59. Edf *e;
  60. setlabel(&m->sched);
  61. if(up) {
  62. if((e = up->edf) && (e->flags & Admitted))
  63. edfrecord(up);
  64. m->proc = 0;
  65. switch(up->state) {
  66. case Running:
  67. ready(up);
  68. break;
  69. case Moribund:
  70. up->state = Dead;
  71. edfstop(up);
  72. if (up->edf)
  73. free(up->edf);
  74. up->edf = nil;
  75. /*
  76. * Holding locks from pexit:
  77. * procalloc
  78. * palloc
  79. */
  80. mmurelease(up);
  81. up->qnext = procalloc.free;
  82. procalloc.free = up;
  83. unlock(&palloc);
  84. unlock(&procalloc);
  85. break;
  86. }
  87. up->mach = 0;
  88. up = nil;
  89. }
  90. sched();
  91. }
  92. /*
  93. * If changing this routine, look also at sleep(). It
  94. * contains a copy of the guts of sched().
  95. */
  96. void
  97. sched(void)
  98. {
  99. int x[1];
  100. if(m->ilockdepth)
  101. panic("ilockdepth %d, last lock 0x%p at 0x%lux, sched called from 0x%lux",
  102. m->ilockdepth, up?up->lastilock:nil,
  103. (up && up->lastilock)?up->lastilock->pc:0, getcallerpc(x+3));
  104. if(up){
  105. if(up->nlocks.ref && up->state != Moribund && up->delaysched < 20){
  106. up->delaysched++;
  107. delayedscheds++;
  108. return;
  109. }
  110. up->delaysched = 0;
  111. splhi();
  112. /* statistics */
  113. m->cs++;
  114. procsave(up);
  115. if(setlabel(&up->sched)){
  116. procrestore(up);
  117. spllo();
  118. return;
  119. }
  120. gotolabel(&m->sched);
  121. }
  122. up = runproc();
  123. up->state = Running;
  124. up->mach = MACHP(m->machno);
  125. m->proc = up;
  126. mmuswitch(up);
  127. gotolabel(&up->sched);
  128. }
  129. int
  130. anyready(void)
  131. {
  132. return runvec;
  133. }
  134. int
  135. anyhigher(void)
  136. {
  137. return runvec & ~((1<<(up->priority+1))-1);
  138. }
  139. /*
  140. * here once per clock tick to see if we should resched
  141. */
  142. void
  143. hzsched(void)
  144. {
  145. /* another cycle, another quantum */
  146. up->quanta--;
  147. /* don't bother unless someone is elegible */
  148. if(anyhigher() || (!up->fixedpri && anyready())){
  149. sched();
  150. splhi();
  151. }
  152. }
  153. /*
  154. * here at the end of non-clock interrupts to see if we should preempt the
  155. * current process. Returns 1 if preempted, 0 otherwise.
  156. */
  157. int
  158. preempted(void)
  159. {
  160. if(up && up->state == Running)
  161. if(up->preempted == 0)
  162. if(anyhigher())
  163. if(!active.exiting){
  164. up->preempted = 1;
  165. sched();
  166. splhi();
  167. up->preempted = 0;
  168. return 1;
  169. }
  170. return 0;
  171. }
  172. /*
  173. * ready(p) picks a new priority for a process and sticks it in the
  174. * runq for that priority.
  175. *
  176. * - fixed priority processes never move
  177. * - a process that uses all its quanta before blocking goes down a
  178. * priority level
  179. * - a process that uses less than half its quanta before blocking
  180. * goes up a priority level
  181. * - a process that blocks after using up half or more of it's quanta
  182. * stays at the same level
  183. *
  184. * new quanta are assigned each time a process blocks or changes level
  185. */
  186. void
  187. ready(Proc *p)
  188. {
  189. int s, pri;
  190. Schedq *rq;
  191. void (*pt)(Proc*, int, vlong);
  192. s = splhi();
  193. if(edfready(p)){
  194. splx(s);
  195. return;
  196. }
  197. pri = p->priority;
  198. if(p->fixedpri){
  199. pri = p->basepri;
  200. p->quanta = HZ;
  201. } else if(p->state == Running){
  202. if(p->quanta <= 0){
  203. /* degrade priority of anyone that used their whole quanta */
  204. if(pri > 0)
  205. pri--;
  206. p->quanta = quanta[pri];
  207. }
  208. } else {
  209. if(p->quanta > quanta[pri]/2){
  210. /* blocked before using half its quanta, go up */
  211. if(++pri > p->basepri)
  212. pri = p->basepri;
  213. }
  214. p->quanta = quanta[pri];
  215. }
  216. rq = &runq[pri];
  217. p->priority = pri;
  218. lock(runq);
  219. p->rnext = 0;
  220. if(rq->tail)
  221. rq->tail->rnext = p;
  222. else
  223. rq->head = p;
  224. rq->tail = p;
  225. rq->n++;
  226. nrdy++;
  227. runvec |= 1<<pri;
  228. p->readytime = m->ticks;
  229. p->state = Ready;
  230. pt = proctrace;
  231. if(pt)
  232. pt(p, SReady, 0);
  233. unlock(runq);
  234. splx(s);
  235. }
  236. /*
  237. * remove a process from a scheduling queue (called splhi)
  238. */
  239. Proc*
  240. dequeueproc(Schedq *rq, Proc *tp)
  241. {
  242. Proc *l, *p;
  243. if(!canlock(runq))
  244. return nil;
  245. /*
  246. * the queue may have changed before we locked runq,
  247. * refind the target process.
  248. */
  249. l = 0;
  250. for(p = rq->head; p; p = p->rnext){
  251. if(p == tp)
  252. break;
  253. l = p;
  254. }
  255. /*
  256. * p->mach==0 only when process state is saved
  257. */
  258. if(p == 0 || p->mach){
  259. unlock(runq);
  260. return nil;
  261. }
  262. if(p->rnext == 0)
  263. rq->tail = l;
  264. if(l)
  265. l->rnext = p->rnext;
  266. else
  267. rq->head = p->rnext;
  268. if(rq->head == nil)
  269. runvec &= ~(1<<(rq-runq));
  270. rq->n--;
  271. nrdy--;
  272. if(p->state != Ready)
  273. print("dequeueproc %s %lud %s\n", p->text, p->pid, statename[p->state]);
  274. unlock(runq);
  275. return p;
  276. }
  277. /*
  278. * yield the processor and drop our priority
  279. */
  280. void
  281. yield(void)
  282. {
  283. if(anyready()){
  284. up->quanta = 0; /* act like you used them all up */
  285. sched();
  286. }
  287. }
  288. /*
  289. * move up any process waiting more than its quanta
  290. */
  291. static void
  292. rebalance(void)
  293. {
  294. Schedq *rq;
  295. Proc *p;
  296. for(rq = runq; rq < &runq[Npriq]; rq++){
  297. p = rq->head;
  298. if(p == nil)
  299. continue;
  300. if(p->mp != MACHP(m->machno))
  301. continue;
  302. if(p->priority == p->basepri)
  303. continue;
  304. /* this comparison is too arbitrary - need a better one */
  305. /* presotto */
  306. if(m->ticks - p->readytime < quanta[p->priority]/4)
  307. continue;
  308. splhi();
  309. p = dequeueproc(rq, p);
  310. spllo();
  311. if(p == nil)
  312. continue;
  313. p->quanta = quanta[p->priority]; /* act like we used none */
  314. ready(p);
  315. }
  316. }
  317. /*
  318. * pick a process to run
  319. */
  320. Proc*
  321. runproc(void)
  322. {
  323. Schedq *rq;
  324. Proc *p;
  325. ulong start, now;
  326. int i;
  327. void (*pt)(Proc*, int, vlong);
  328. start = perfticks();
  329. /* 10 is completely arbitrary - it interacts with the comparison in rebalance */
  330. /* presotto */
  331. if(m->fairness++ == 10){
  332. m->fairness = 0;
  333. rebalance();
  334. }
  335. loop:
  336. /*
  337. * find a process that last ran on this processor (affinity),
  338. * or one that hasn't moved in a while (load balancing). Every
  339. * time around the loop affinity goes down.
  340. */
  341. spllo();
  342. for(i = 0;; i++){
  343. /*
  344. * find the highest priority target process that this
  345. * processor can run given affinity constraints.
  346. *
  347. */
  348. for(rq = &runq[Nrq-1]; rq >= runq; rq--){
  349. for(p = rq->head; p; p = p->rnext){
  350. if(p->mp == nil || p->mp == MACHP(m->machno)
  351. || (!p->wired && i > 0))
  352. goto found;
  353. }
  354. }
  355. /* waste time or halt the CPU */
  356. idlehands();
  357. /* remember how much time we're here */
  358. now = perfticks();
  359. m->perf.inidle += now-start;
  360. start = now;
  361. }
  362. found:
  363. splhi();
  364. p = dequeueproc(rq, p);
  365. if(p == nil)
  366. goto loop;
  367. p->state = Scheding;
  368. p->mp = MACHP(m->machno);
  369. if(p->edf && (p->edf->flags & Admitted)){
  370. edflock();
  371. edfrun(p, rq == &runq[PriEdf]); /* start deadline timer and do admin */
  372. edfunlock();
  373. }
  374. pt = proctrace;
  375. if(pt)
  376. pt(p, SRun, 0);
  377. return p;
  378. }
  379. int
  380. canpage(Proc *p)
  381. {
  382. int ok = 0;
  383. splhi();
  384. lock(runq);
  385. /* Only reliable way to see if we are Running */
  386. if(p->mach == 0) {
  387. p->newtlb = 1;
  388. ok = 1;
  389. }
  390. unlock(runq);
  391. spllo();
  392. return ok;
  393. }
  394. Proc*
  395. newproc(void)
  396. {
  397. Proc *p;
  398. lock(&procalloc);
  399. for(;;) {
  400. if(p = procalloc.free)
  401. break;
  402. unlock(&procalloc);
  403. resrcwait("no procs");
  404. lock(&procalloc);
  405. }
  406. procalloc.free = p->qnext;
  407. unlock(&procalloc);
  408. p->state = Scheding;
  409. p->psstate = "New";
  410. p->mach = 0;
  411. p->qnext = 0;
  412. p->nchild = 0;
  413. p->nwait = 0;
  414. p->waitq = 0;
  415. p->parent = 0;
  416. p->pgrp = 0;
  417. p->egrp = 0;
  418. p->fgrp = 0;
  419. p->rgrp = 0;
  420. p->pdbg = 0;
  421. p->fpstate = FPinit;
  422. p->kp = 0;
  423. p->procctl = 0;
  424. p->notepending = 0;
  425. p->ureg = 0;
  426. p->privatemem = 0;
  427. p->noswap = 0;
  428. p->errstr = p->errbuf0;
  429. p->syserrstr = p->errbuf1;
  430. p->errbuf0[0] = '\0';
  431. p->errbuf1[0] = '\0';
  432. p->nlocks.ref = 0;
  433. p->delaysched = 0;
  434. kstrdup(&p->user, "*nouser");
  435. kstrdup(&p->text, "*notext");
  436. kstrdup(&p->args, "");
  437. p->nargs = 0;
  438. p->setargs = 0;
  439. memset(p->seg, 0, sizeof p->seg);
  440. p->pid = incref(&pidalloc);
  441. pidhash(p);
  442. p->noteid = incref(&noteidalloc);
  443. if(p->pid==0 || p->noteid==0)
  444. panic("pidalloc");
  445. if(p->kstack == 0)
  446. p->kstack = smalloc(KSTACK);
  447. /* sched params */
  448. p->mp = 0;
  449. p->wired = 0;
  450. procpriority(p, PriNormal, 0);
  451. p->edf = nil;
  452. return p;
  453. }
  454. /*
  455. * wire this proc to a machine
  456. */
  457. void
  458. procwired(Proc *p, int bm)
  459. {
  460. Proc *pp;
  461. int i;
  462. char nwired[MAXMACH];
  463. Mach *wm;
  464. if(bm < 0){
  465. /* pick a machine to wire to */
  466. memset(nwired, 0, sizeof(nwired));
  467. p->wired = 0;
  468. pp = proctab(0);
  469. for(i=0; i<conf.nproc; i++, pp++){
  470. wm = pp->wired;
  471. if(wm && pp->pid)
  472. nwired[wm->machno]++;
  473. }
  474. bm = 0;
  475. for(i=0; i<conf.nmach; i++)
  476. if(nwired[i] < nwired[bm])
  477. bm = i;
  478. } else {
  479. /* use the virtual machine requested */
  480. bm = bm % conf.nmach;
  481. }
  482. p->wired = MACHP(bm);
  483. p->mp = p->wired;
  484. }
  485. void
  486. procpriority(Proc *p, int pri, int fixed)
  487. {
  488. if(pri >= Npriq)
  489. pri = Npriq - 1;
  490. else if(pri < 0)
  491. pri = 0;
  492. p->basepri = pri;
  493. p->priority = pri;
  494. if(fixed){
  495. p->quanta = 0xfffff;
  496. p->fixedpri = 1;
  497. } else {
  498. p->quanta = quanta[pri];
  499. p->fixedpri = 0;
  500. }
  501. }
  502. void
  503. procinit0(void) /* bad planning - clashes with devproc.c */
  504. {
  505. Proc *p;
  506. int i;
  507. procalloc.free = xalloc(conf.nproc*sizeof(Proc));
  508. if(procalloc.free == nil)
  509. panic("cannot allocate %lud procs\n", conf.nproc);
  510. procalloc.arena = procalloc.free;
  511. p = procalloc.free;
  512. for(i=0; i<conf.nproc-1; i++,p++)
  513. p->qnext = p+1;
  514. p->qnext = 0;
  515. }
  516. /*
  517. * sleep if a condition is not true. Another process will
  518. * awaken us after it sets the condition. When we awaken
  519. * the condition may no longer be true.
  520. *
  521. * we lock both the process and the rendezvous to keep r->p
  522. * and p->r synchronized.
  523. */
  524. void
  525. sleep(Rendez *r, int (*f)(void*), void *arg)
  526. {
  527. int s;
  528. void (*pt)(Proc*, int, vlong);
  529. s = splhi();
  530. if(up->nlocks.ref)
  531. print("process %lud sleeps with %lud locks held, last lock 0x%p locked at pc 0x%lux\n",
  532. up->pid, up->nlocks.ref, up->lastlock, up->lastlock->pc);
  533. lock(r);
  534. lock(&up->rlock);
  535. if(r->p){
  536. print("double sleep called from 0x%lux, %lud %lud\n", getcallerpc(&r), r->p->pid, up->pid);
  537. dumpstack();
  538. }
  539. /*
  540. * Wakeup only knows there may be something to do by testing
  541. * r->p in order to get something to lock on.
  542. * Flush that information out to memory in case the sleep is
  543. * committed.
  544. */
  545. r->p = up;
  546. if((*f)(arg) || up->notepending){
  547. /*
  548. * if condition happened or a note is pending
  549. * never mind
  550. */
  551. r->p = nil;
  552. unlock(&up->rlock);
  553. unlock(r);
  554. } else {
  555. /*
  556. * now we are committed to
  557. * change state and call scheduler
  558. */
  559. pt = proctrace;
  560. if(pt)
  561. pt(up, SSleep, 0);
  562. up->state = Wakeme;
  563. up->r = r;
  564. /* statistics */
  565. m->cs++;
  566. procsave(up);
  567. if(setlabel(&up->sched)) {
  568. /*
  569. * here when the process is awakened
  570. */
  571. procrestore(up);
  572. spllo();
  573. } else {
  574. /*
  575. * here to go to sleep (i.e. stop Running)
  576. */
  577. unlock(&up->rlock);
  578. unlock(r);
  579. gotolabel(&m->sched);
  580. }
  581. }
  582. if(up->notepending) {
  583. up->notepending = 0;
  584. splx(s);
  585. error(Eintr);
  586. }
  587. splx(s);
  588. }
  589. int
  590. tfn(void *arg)
  591. {
  592. return MACHP(0)->ticks >= up->twhen || up->tfn(arg);
  593. }
  594. void
  595. twakeup(Ureg*, Timer *t)
  596. {
  597. Proc *p;
  598. p = t->ta;
  599. if(p->trend){
  600. wakeup(p->trend);
  601. p->trend = 0;
  602. }
  603. }
  604. /* Sleep until todget() >= ns. NOTE: ns is not an interval */
  605. void
  606. tnsleep(Rendez *r, int (*fn)(void*), void *arg, vlong ns)
  607. {
  608. if (up->tt)
  609. timerdel(up);
  610. up->tns = ns;
  611. up->tf = twakeup;
  612. up->tmode = Tabsolute;
  613. up->ta = up;
  614. up->trend = r;
  615. up->tfn = fn;
  616. timeradd(up);
  617. if(waserror()){
  618. timerdel(up);
  619. nexterror();
  620. }
  621. sleep(r, tfn, arg);
  622. if (up->tt)
  623. timerdel(up);
  624. up->twhen = 0;
  625. poperror();
  626. }
  627. void
  628. tsleep(Rendez *r, int (*fn)(void*), void *arg, ulong ms)
  629. {
  630. if (up->tt)
  631. timerdel(up);
  632. up->tns = MS2NS(ms);
  633. up->tf = twakeup;
  634. up->tmode = Trelative;
  635. up->ta = up;
  636. up->trend = r;
  637. up->tfn = fn;
  638. timeradd(up);
  639. if(waserror()){
  640. timerdel(up);
  641. nexterror();
  642. }
  643. sleep(r, tfn, arg);
  644. if (up->tt)
  645. timerdel(up);
  646. up->twhen = 0;
  647. poperror();
  648. }
  649. /*
  650. * Expects that only one process can call wakeup for any given Rendez.
  651. * We hold both locks to ensure that r->p and p->r remain consistent.
  652. * Richard Miller has a better solution that doesn't require both to
  653. * be held simultaneously, but I'm a paranoid - presotto.
  654. */
  655. Proc*
  656. wakeup(Rendez *r)
  657. {
  658. Proc *p;
  659. int s;
  660. s = splhi();
  661. lock(r);
  662. p = r->p;
  663. if(p != nil){
  664. lock(&p->rlock);
  665. if(p->state != Wakeme || p->r != r)
  666. panic("wakeup: state");
  667. r->p = nil;
  668. p->r = nil;
  669. ready(p);
  670. unlock(&p->rlock);
  671. }
  672. unlock(r);
  673. splx(s);
  674. return p;
  675. }
  676. /*
  677. * if waking a sleeping process, this routine must hold both
  678. * p->rlock and r->lock. However, it can't know them in
  679. * the same order as wakeup causing a possible lock ordering
  680. * deadlock. We break the deadlock by giving up the p->rlock
  681. * lock if we can't get the r->lock and retrying.
  682. */
  683. int
  684. postnote(Proc *p, int dolock, char *n, int flag)
  685. {
  686. int s, ret;
  687. Rendez *r;
  688. Proc *d, **l;
  689. if(dolock)
  690. qlock(&p->debug);
  691. if(flag != NUser && (p->notify == 0 || p->notified))
  692. p->nnote = 0;
  693. ret = 0;
  694. if(p->nnote < NNOTE) {
  695. strcpy(p->note[p->nnote].msg, n);
  696. p->note[p->nnote++].flag = flag;
  697. ret = 1;
  698. }
  699. p->notepending = 1;
  700. if(dolock)
  701. qunlock(&p->debug);
  702. /* this loop is to avoid lock ordering problems. */
  703. for(;;){
  704. s = splhi();
  705. lock(&p->rlock);
  706. r = p->r;
  707. /* waiting for a wakeup? */
  708. if(r == nil)
  709. break; /* no */
  710. /* try for the second lock */
  711. if(canlock(r)){
  712. if(p->state != Wakeme || r->p != p)
  713. panic("postnote: state %d %d %d", r->p != p, p->r != r, p->state);
  714. p->r = nil;
  715. r->p = nil;
  716. ready(p);
  717. unlock(r);
  718. break;
  719. }
  720. /* give other process time to get out of critical section and try again */
  721. unlock(&p->rlock);
  722. splx(s);
  723. sched();
  724. }
  725. unlock(&p->rlock);
  726. splx(s);
  727. if(p->state != Rendezvous)
  728. return ret;
  729. /* Try and pull out of a rendezvous */
  730. lock(p->rgrp);
  731. if(p->state == Rendezvous) {
  732. p->rendval = ~0;
  733. l = &REND(p->rgrp, p->rendtag);
  734. for(d = *l; d; d = d->rendhash) {
  735. if(d == p) {
  736. *l = p->rendhash;
  737. break;
  738. }
  739. l = &d->rendhash;
  740. }
  741. ready(p);
  742. }
  743. unlock(p->rgrp);
  744. return ret;
  745. }
  746. /*
  747. * weird thing: keep at most NBROKEN around
  748. */
  749. #define NBROKEN 4
  750. struct
  751. {
  752. QLock;
  753. int n;
  754. Proc *p[NBROKEN];
  755. }broken;
  756. void
  757. addbroken(Proc *p)
  758. {
  759. qlock(&broken);
  760. if(broken.n == NBROKEN) {
  761. ready(broken.p[0]);
  762. memmove(&broken.p[0], &broken.p[1], sizeof(Proc*)*(NBROKEN-1));
  763. --broken.n;
  764. }
  765. broken.p[broken.n++] = p;
  766. qunlock(&broken);
  767. edfstop(up);
  768. p->state = Broken;
  769. p->psstate = 0;
  770. sched();
  771. }
  772. void
  773. unbreak(Proc *p)
  774. {
  775. int b;
  776. qlock(&broken);
  777. for(b=0; b < broken.n; b++)
  778. if(broken.p[b] == p) {
  779. broken.n--;
  780. memmove(&broken.p[b], &broken.p[b+1],
  781. sizeof(Proc*)*(NBROKEN-(b+1)));
  782. ready(p);
  783. break;
  784. }
  785. qunlock(&broken);
  786. }
  787. int
  788. freebroken(void)
  789. {
  790. int i, n;
  791. qlock(&broken);
  792. n = broken.n;
  793. for(i=0; i<n; i++) {
  794. ready(broken.p[i]);
  795. broken.p[i] = 0;
  796. }
  797. broken.n = 0;
  798. qunlock(&broken);
  799. return n;
  800. }
  801. void
  802. pexit(char *exitstr, int freemem)
  803. {
  804. Proc *p;
  805. Segment **s, **es;
  806. long utime, stime;
  807. Waitq *wq, *f, *next;
  808. Fgrp *fgrp;
  809. Egrp *egrp;
  810. Rgrp *rgrp;
  811. Pgrp *pgrp;
  812. Chan *dot;
  813. void (*pt)(Proc*, int, vlong);
  814. up->alarm = 0;
  815. if (up->tt)
  816. timerdel(up);
  817. pt = proctrace;
  818. if(pt)
  819. pt(up, SDead, 0);
  820. /* nil out all the resources under lock (free later) */
  821. qlock(&up->debug);
  822. fgrp = up->fgrp;
  823. up->fgrp = nil;
  824. egrp = up->egrp;
  825. up->egrp = nil;
  826. rgrp = up->rgrp;
  827. up->rgrp = nil;
  828. pgrp = up->pgrp;
  829. up->pgrp = nil;
  830. dot = up->dot;
  831. up->dot = nil;
  832. qunlock(&up->debug);
  833. if(fgrp)
  834. closefgrp(fgrp);
  835. if(egrp)
  836. closeegrp(egrp);
  837. if(rgrp)
  838. closergrp(rgrp);
  839. if(dot)
  840. cclose(dot);
  841. if(pgrp)
  842. closepgrp(pgrp);
  843. /*
  844. * if not a kernel process and have a parent,
  845. * do some housekeeping.
  846. */
  847. if(up->kp == 0) {
  848. p = up->parent;
  849. if(p == 0) {
  850. if(exitstr == 0)
  851. exitstr = "unknown";
  852. panic("boot process died: %s", exitstr);
  853. }
  854. while(waserror())
  855. ;
  856. wq = smalloc(sizeof(Waitq));
  857. poperror();
  858. wq->w.pid = up->pid;
  859. utime = up->time[TUser] + up->time[TCUser];
  860. stime = up->time[TSys] + up->time[TCSys];
  861. wq->w.time[TUser] = tk2ms(utime);
  862. wq->w.time[TSys] = tk2ms(stime);
  863. wq->w.time[TReal] = tk2ms(MACHP(0)->ticks - up->time[TReal]);
  864. if(exitstr && exitstr[0])
  865. snprint(wq->w.msg, sizeof(wq->w.msg), "%s %lud: %s", up->text, up->pid, exitstr);
  866. else
  867. wq->w.msg[0] = '\0';
  868. lock(&p->exl);
  869. /*
  870. * If my parent is no longer alive, or if there would be more
  871. * than 128 zombie child processes for my parent, then don't
  872. * leave a wait record behind. This helps prevent badly
  873. * written daemon processes from accumulating lots of wait
  874. * records.
  875. */
  876. if(p->pid == up->parentpid && p->state != Broken && p->nwait < 128) {
  877. p->nchild--;
  878. p->time[TCUser] += utime;
  879. p->time[TCSys] += stime;
  880. wq->next = p->waitq;
  881. p->waitq = wq;
  882. p->nwait++;
  883. wakeup(&p->waitr);
  884. unlock(&p->exl);
  885. }
  886. else {
  887. unlock(&p->exl);
  888. free(wq);
  889. }
  890. }
  891. if(!freemem)
  892. addbroken(up);
  893. qlock(&up->seglock);
  894. es = &up->seg[NSEG];
  895. for(s = up->seg; s < es; s++) {
  896. if(*s) {
  897. putseg(*s);
  898. *s = 0;
  899. }
  900. }
  901. qunlock(&up->seglock);
  902. lock(&up->exl); /* Prevent my children from leaving waits */
  903. pidunhash(up);
  904. up->pid = 0;
  905. wakeup(&up->waitr);
  906. unlock(&up->exl);
  907. for(f = up->waitq; f; f = next) {
  908. next = f->next;
  909. free(f);
  910. }
  911. /* release debuggers */
  912. qlock(&up->debug);
  913. if(up->pdbg) {
  914. wakeup(&up->pdbg->sleep);
  915. up->pdbg = 0;
  916. }
  917. qunlock(&up->debug);
  918. /* Sched must not loop for these locks */
  919. lock(&procalloc);
  920. lock(&palloc);
  921. edfstop(up);
  922. up->state = Moribund;
  923. sched();
  924. panic("pexit");
  925. }
  926. int
  927. haswaitq(void *x)
  928. {
  929. Proc *p;
  930. p = (Proc *)x;
  931. return p->waitq != 0;
  932. }
  933. ulong
  934. pwait(Waitmsg *w)
  935. {
  936. ulong cpid;
  937. Waitq *wq;
  938. if(!canqlock(&up->qwaitr))
  939. error(Einuse);
  940. if(waserror()) {
  941. qunlock(&up->qwaitr);
  942. nexterror();
  943. }
  944. lock(&up->exl);
  945. if(up->nchild == 0 && up->waitq == 0) {
  946. unlock(&up->exl);
  947. error(Enochild);
  948. }
  949. unlock(&up->exl);
  950. sleep(&up->waitr, haswaitq, up);
  951. lock(&up->exl);
  952. wq = up->waitq;
  953. up->waitq = wq->next;
  954. up->nwait--;
  955. unlock(&up->exl);
  956. qunlock(&up->qwaitr);
  957. poperror();
  958. if(w)
  959. memmove(w, &wq->w, sizeof(Waitmsg));
  960. cpid = wq->w.pid;
  961. free(wq);
  962. return cpid;
  963. }
  964. Proc*
  965. proctab(int i)
  966. {
  967. return &procalloc.arena[i];
  968. }
  969. void
  970. dumpaproc(Proc *p)
  971. {
  972. ulong bss;
  973. char *s;
  974. if(p == 0)
  975. return;
  976. bss = 0;
  977. if(p->seg[BSEG])
  978. bss = p->seg[BSEG]->top;
  979. s = p->psstate;
  980. if(s == 0)
  981. s = statename[p->state];
  982. print("%3lud:%10s pc %8lux dbgpc %8lux %8s (%s) ut %ld st %ld bss %lux qpc %lux nl %lud nd %lud lpc %lux pri %lud\n",
  983. p->pid, p->text, p->pc, dbgpc(p), s, statename[p->state],
  984. p->time[0], p->time[1], bss, p->qpc, p->nlocks.ref, p->delaysched, p->lastlock ? p->lastlock->pc : 0, p->priority);
  985. }
  986. void
  987. procdump(void)
  988. {
  989. int i;
  990. Proc *p;
  991. if(up)
  992. print("up %lud\n", up->pid);
  993. else
  994. print("no current process\n");
  995. for(i=0; i<conf.nproc; i++) {
  996. p = &procalloc.arena[i];
  997. if(p->state == Dead)
  998. continue;
  999. dumpaproc(p);
  1000. }
  1001. }
  1002. /*
  1003. * wait till all processes have flushed their mmu
  1004. * state about segement s
  1005. */
  1006. void
  1007. procflushseg(Segment *s)
  1008. {
  1009. int i, ns, nm, nwait;
  1010. Proc *p;
  1011. /*
  1012. * tell all processes with this
  1013. * segment to flush their mmu's
  1014. */
  1015. nwait = 0;
  1016. for(i=0; i<conf.nproc; i++) {
  1017. p = &procalloc.arena[i];
  1018. if(p->state == Dead)
  1019. continue;
  1020. for(ns = 0; ns < NSEG; ns++)
  1021. if(p->seg[ns] == s){
  1022. p->newtlb = 1;
  1023. for(nm = 0; nm < conf.nmach; nm++){
  1024. if(MACHP(nm)->proc == p){
  1025. MACHP(nm)->flushmmu = 1;
  1026. nwait++;
  1027. }
  1028. }
  1029. break;
  1030. }
  1031. }
  1032. if(nwait == 0)
  1033. return;
  1034. /*
  1035. * wait for all processors to take a clock interrupt
  1036. * and flush their mmu's
  1037. */
  1038. for(nm = 0; nm < conf.nmach; nm++)
  1039. if(MACHP(nm) != m)
  1040. while(MACHP(nm)->flushmmu)
  1041. sched();
  1042. }
  1043. void
  1044. scheddump(void)
  1045. {
  1046. Proc *p;
  1047. Schedq *rq;
  1048. for(rq = &runq[Nrq-1]; rq >= runq; rq--){
  1049. if(rq->head == 0)
  1050. continue;
  1051. print("rq%ld:", rq-runq);
  1052. for(p = rq->head; p; p = p->rnext)
  1053. print(" %lud(%lud)", p->pid, m->ticks - p->readytime);
  1054. print("\n");
  1055. delay(150);
  1056. }
  1057. print("nrdy %d\n", nrdy);
  1058. }
  1059. void
  1060. kproc(char *name, void (*func)(void *), void *arg)
  1061. {
  1062. Proc *p;
  1063. static Pgrp *kpgrp;
  1064. p = newproc();
  1065. p->psstate = 0;
  1066. p->procmode = 0640;
  1067. p->kp = 1;
  1068. p->noswap = 1;
  1069. p->fpsave = up->fpsave;
  1070. p->scallnr = up->scallnr;
  1071. p->s = up->s;
  1072. p->nerrlab = 0;
  1073. p->slash = up->slash;
  1074. p->dot = up->dot;
  1075. incref(p->dot);
  1076. memmove(p->note, up->note, sizeof(p->note));
  1077. p->nnote = up->nnote;
  1078. p->notified = 0;
  1079. p->lastnote = up->lastnote;
  1080. p->notify = up->notify;
  1081. p->ureg = 0;
  1082. p->dbgreg = 0;
  1083. procpriority(p, PriKproc, 0);
  1084. kprocchild(p, func, arg);
  1085. kstrdup(&p->user, eve);
  1086. kstrdup(&p->text, name);
  1087. if(kpgrp == 0)
  1088. kpgrp = newpgrp();
  1089. p->pgrp = kpgrp;
  1090. incref(kpgrp);
  1091. memset(p->time, 0, sizeof(p->time));
  1092. p->time[TReal] = MACHP(0)->ticks;
  1093. ready(p);
  1094. /*
  1095. * since the bss/data segments are now shareable,
  1096. * any mmu info about this process is now stale
  1097. * and has to be discarded.
  1098. */
  1099. p->newtlb = 1;
  1100. flushmmu();
  1101. }
  1102. /*
  1103. * called splhi() by notify(). See comment in notify for the
  1104. * reasoning.
  1105. */
  1106. void
  1107. procctl(Proc *p)
  1108. {
  1109. char *state;
  1110. ulong s;
  1111. switch(p->procctl) {
  1112. case Proc_exitbig:
  1113. spllo();
  1114. pexit("Killed: Insufficient physical memory", 1);
  1115. case Proc_exitme:
  1116. spllo(); /* pexit has locks in it */
  1117. pexit("Killed", 1);
  1118. case Proc_traceme:
  1119. if(p->nnote == 0)
  1120. return;
  1121. /* No break */
  1122. case Proc_stopme:
  1123. p->procctl = 0;
  1124. state = p->psstate;
  1125. p->psstate = "Stopped";
  1126. /* free a waiting debugger */
  1127. s = spllo();
  1128. qlock(&p->debug);
  1129. if(p->pdbg) {
  1130. wakeup(&p->pdbg->sleep);
  1131. p->pdbg = 0;
  1132. }
  1133. qunlock(&p->debug);
  1134. splhi();
  1135. p->state = Stopped;
  1136. sched();
  1137. p->psstate = state;
  1138. splx(s);
  1139. return;
  1140. }
  1141. }
  1142. #include "errstr.h"
  1143. void
  1144. error(char *err)
  1145. {
  1146. spllo();
  1147. assert(up->nerrlab < NERR);
  1148. kstrcpy(up->errstr, err, ERRMAX);
  1149. setlabel(&up->errlab[NERR-1]);
  1150. nexterror();
  1151. }
  1152. void
  1153. nexterror(void)
  1154. {
  1155. gotolabel(&up->errlab[--up->nerrlab]);
  1156. }
  1157. void
  1158. exhausted(char *resource)
  1159. {
  1160. char buf[ERRMAX];
  1161. sprint(buf, "no free %s", resource);
  1162. iprint("%s\n", buf);
  1163. error(buf);
  1164. }
  1165. void
  1166. killbig(void)
  1167. {
  1168. int i;
  1169. Segment *s;
  1170. ulong l, max;
  1171. Proc *p, *ep, *kp;
  1172. max = 0;
  1173. kp = 0;
  1174. ep = procalloc.arena+conf.nproc;
  1175. for(p = procalloc.arena; p < ep; p++) {
  1176. if(p->state == Dead || p->kp)
  1177. continue;
  1178. l = 0;
  1179. for(i=1; i<NSEG; i++) {
  1180. s = p->seg[i];
  1181. if(s != 0)
  1182. l += s->top - s->base;
  1183. }
  1184. if(l > max && strcmp(p->text, "kfs") != 0){
  1185. kp = p;
  1186. max = l;
  1187. }
  1188. }
  1189. kp->procctl = Proc_exitbig;
  1190. for(i = 0; i < NSEG; i++) {
  1191. s = kp->seg[i];
  1192. if(s != 0 && canqlock(&s->lk)) {
  1193. mfreeseg(s, s->base, (s->top - s->base)/BY2PG);
  1194. qunlock(&s->lk);
  1195. }
  1196. }
  1197. print("%lud: %s killed because no swap configured\n", kp->pid, kp->text);
  1198. }
  1199. /*
  1200. * change ownership to 'new' of all processes owned by 'old'. Used when
  1201. * eve changes.
  1202. */
  1203. void
  1204. renameuser(char *old, char *new)
  1205. {
  1206. Proc *p, *ep;
  1207. ep = procalloc.arena+conf.nproc;
  1208. for(p = procalloc.arena; p < ep; p++)
  1209. if(p->user!=nil && strcmp(old, p->user)==0)
  1210. kstrdup(&p->user, new);
  1211. }
  1212. /*
  1213. * time accounting called by clock() splhi'd
  1214. */
  1215. void
  1216. accounttime(void)
  1217. {
  1218. Proc *p;
  1219. ulong n, per;
  1220. static ulong nrun;
  1221. p = m->proc;
  1222. if(p) {
  1223. nrun++;
  1224. p->time[p->insyscall]++;
  1225. }
  1226. /* calculate decaying duty cycles */
  1227. n = perfticks();
  1228. per = n - m->perf.last;
  1229. m->perf.last = n;
  1230. per = (m->perf.period*(HZ-1) + per)/HZ;
  1231. if(per != 0)
  1232. m->perf.period = per;
  1233. m->perf.avg_inidle = (m->perf.avg_inidle*(HZ-1)+m->perf.inidle)/HZ;
  1234. m->perf.inidle = 0;
  1235. m->perf.avg_inintr = (m->perf.avg_inintr*(HZ-1)+m->perf.inintr)/HZ;
  1236. m->perf.inintr = 0;
  1237. /* only one processor gets to compute system load averages */
  1238. if(m->machno != 0)
  1239. return;
  1240. /* calculate decaying load average */
  1241. n = nrun;
  1242. nrun = 0;
  1243. n = (nrdy+n)*1000;
  1244. m->load = (m->load*19+n)/20;
  1245. }
  1246. static void
  1247. pidhash(Proc *p)
  1248. {
  1249. int h;
  1250. h = p->pid % nelem(procalloc.ht);
  1251. lock(&procalloc);
  1252. p->pidhash = procalloc.ht[h];
  1253. procalloc.ht[h] = p;
  1254. unlock(&procalloc);
  1255. }
  1256. static void
  1257. pidunhash(Proc *p)
  1258. {
  1259. int h;
  1260. Proc **l;
  1261. h = p->pid % nelem(procalloc.ht);
  1262. lock(&procalloc);
  1263. for(l = &procalloc.ht[h]; *l != nil; l = &(*l)->pidhash)
  1264. if(*l == p){
  1265. *l = p->pidhash;
  1266. break;
  1267. }
  1268. unlock(&procalloc);
  1269. }
  1270. int
  1271. procindex(ulong pid)
  1272. {
  1273. Proc *p;
  1274. int h;
  1275. int s;
  1276. s = -1;
  1277. h = pid % nelem(procalloc.ht);
  1278. lock(&procalloc);
  1279. for(p = procalloc.ht[h]; p != nil; p = p->pidhash)
  1280. if(p->pid == pid){
  1281. s = p - procalloc.arena;
  1282. break;
  1283. }
  1284. unlock(&procalloc);
  1285. return s;
  1286. }