proc.c 23 KB

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