|
|
1.1 root 1: /* $Header: /newbits/286_KERNEL/USRSRC/coh/RCS/seg.c,v 1.1 92/01/09 13:29:05 bin Exp Locker: bin $ */
2: /* (lgl-
3: * The information contained herein is a trade secret of Mark Williams
4: * Company, and is confidential information. It is provided under a
5: * license agreement, and may be copied or disclosed only under the
6: * terms of that agreement. Any reproduction or disclosure of this
7: * material without the express written authorization of Mark Williams
8: * Company or persuant to the license agreement is unlawful.
9: *
10: * COHERENT Version 2.3.37
11: * Copyright (c) 1982, 1983, 1984.
12: * An unpublished work by Mark Williams Company, Chicago.
13: * All rights reserved.
14: -lgl) */
15: /*
16: * Coherent.
17: * Segment manipulation.
18: *
19: * $Log: seg.c,v $
20: * Revision 1.1 92/01/09 13:29:05 bin
21: * Initial revision
22: *
23: * Revision 1.1 88/03/24 16:14:20 src
24: * Initial revision
25: *
26: * 88/02/26 Allan Cornish /usr/src/sys/coh/seg.c
27: * swapio() now avoids 64 Kbyte page [dma] straddles.
28: *
29: * 88/01/22 Allan Cornish /usr/src/sys/coh/seg.c
30: * salloc() now invokes krunch(1000) if initial allocation fails.
31: * sfree() now invokes krunch(0).
32: *
33: * 88/01/21 Allan Cornish /usr/src/sys/coh/seg.c
34: * sfree() modified to eliminate critical race on ref cnts and segment gate.
35: * segfinm() now properly maintains segment reference counts.
36: *
37: * 87/11/13 Allan Cornish /usr/src/sys/coh/seg.c
38: * Support for protected mode segmentation added.
39: */
40: #include <sys/coherent.h>
41: #include <sys/buf.h>
42: #include <errno.h>
43: #include <sys/ino.h>
44: #include <sys/inode.h>
45: #include <sys/proc.h>
46: #include <sys/sched.h>
47: #include <sys/seg.h>
48: #include <sys/uproc.h>
49:
50: /*
51: * Initialisation code.
52: */
53: seginit()
54: {
55: /*
56: * Create empty circular-list of memory segments.
57: */
58: segmq.s_forw = &segmq;
59: segmq.s_back = &segmq;
60:
61: /*
62: * Create empty circular-list of disk segments.
63: */
64: segdq.s_forw = &segdq;
65: segdq.s_back = &segdq;
66:
67: if ( holebot != holetop ) {
68: /*
69: * Define the I/O mem hole between low memory and extended mem.
70: * NOTE: Setting lrefc to urefc+1 stopx segment from moving.
71: */
72: segiom.s_paddr = holebot;
73: segiom.s_size = holetop - holebot;
74: segiom.s_flags = SFCORE | SFSYST;
75: segiom.s_urefc = 1;
76: segiom.s_lrefc = 2;
77:
78: /*
79: * Insert I/O memory segment into memory list.
80: */
81: segiom.s_forw = &segmq;
82: segiom.s_back = &segmq;
83: segmq.s_forw = &segiom;
84: segmq.s_back = &segiom;
85: }
86: }
87:
88: /*
89: * Given an inode, `ip', and flags, `ff', describing a segment associated
90: * with the inode, see if the segment already exists and if so, return a
91: * copy. If the segment does not exists, allocate the segment having size
92: * `ss', and read the segment using the inode at seek offset `dq' with a
93: * size of `ds'.
94: */
95: SEG *
96: ssalloc(rp, ip, ff, ss, dq, ds)
97: int *rp;
98: register INODE *ip;
99: fsize_t ss;
100: fsize_t dq;
101: fsize_t ds;
102: {
103: register SEG *sp;
104: register int f;
105:
106: *rp = -1;
107: if (ss == 0) {
108: *rp = 1;
109: return (NULL);
110: }
111: lock(seglink);
112: f = ff & (SFSHRX|SFTEXT);
113:
114: /*
115: * Look for the segment in the memory queue.
116: */
117: for (sp=segmq.s_forw; sp!=&segmq; sp=sp->s_forw) {
118: if (sp->s_ip==ip && (sp->s_flags&(SFSHRX|SFTEXT))==f) {
119: unlock(seglink);
120: if ((sp = segdupl(sp)) != NULL) {
121: segfinm(sp);
122: *rp = 1;
123: }
124: return (sp);
125: }
126: }
127:
128: /*
129: * Look for the segment on the disk queue.
130: */
131: for (sp=segdq.s_forw; sp!=&segdq; sp=sp->s_forw) {
132: if (sp->s_ip==ip && (sp->s_flags&(SFSHRX|SFTEXT))==f) {
133: unlock(seglink);
134: if ((sp = segdupl(sp)) != NULL) {
135: segfinm(sp);
136: *rp = 1;
137: }
138: return (sp);
139: }
140: }
141: unlock(seglink);
142:
143: /*
144: * Allocate and create the segment.
145: */
146: if ((sp=salloc(ss, ff)) == NULL)
147: return (NULL);
148: if (exsread(sp, ip, ds, dq, (fsize_t)0) == 0) {
149: sfree(sp);
150: return (NULL);
151: }
152: if ((ff&SFSHRX) != 0) {
153: sp->s_ip = ip;
154: ip->i_refc++;
155: }
156: *rp = 0;
157: return (sp);
158: }
159:
160: /*
161: * Given a pointer to a newly created process, copy all of our segments
162: * into the given process.
163: */
164: segadup(cpp)
165: register PROC *cpp;
166: {
167: register SEG *sp;
168: register int n;
169: register PROC *pp;
170:
171: pp = SELF;
172: cpp->p_flags |= PFSWIO;
173: for (n=0; n<NUSEG; n++) {
174: if ((sp=pp->p_segp[n]) == NULL)
175: continue;
176: if ((sp=segdupl(sp)) == NULL)
177: break;
178: cpp->p_segp[n] = sp;
179: if ((sp->s_flags&SFCORE) == 0)
180: cpp->p_flags &= ~PFCORE;
181: }
182: if (n < NUSEG) {
183: while (n > 0) {
184: if ((sp=cpp->p_segp[--n]) != NULL) {
185: cpp->p_segp[n] = NULL;
186: sfree(sp);
187: }
188: }
189: }
190: cpp->p_flags &= ~PFSWIO;
191: return (n);
192: }
193:
194: /*
195: * Duplicate a segment.
196: */
197: SEG *
198: segdupl(sp)
199: register SEG *sp;
200: {
201: register SEG *sp1;
202:
203: if ((sp->s_flags&SFSHRX) != 0) {
204: sp->s_urefc++;
205: sp->s_lrefc++;
206: return (sp);
207: }
208: if ((sp->s_flags&SFCORE) == 0)
209: panic("Cannot duplicate non shared swapped segment");
210: if ((sp1=salloc(sp->s_size, sp->s_flags|SFNSWP|SFNCLR)) == NULL)
211: sp1 = segdupd(sp);
212: else {
213: sp1->s_flags = sp->s_flags;
214: plrcopy( sp->s_paddr, sp1->s_paddr, sp->s_size );
215: }
216: return (sp1);
217: }
218:
219: /*
220: * Allocate a segment `n' bytes long. `f' contains some pseudo flags.
221: */
222: SEG *
223: salloc(n, f)
224: fsize_t n;
225: {
226: register SEG *sp;
227: register int r;
228:
229: r = (f&(SFSYST|SFHIGH|SFTEXT|SFSHRX|SFDOWN)) | SFCORE;
230: n += (BSIZE-1);
231: n &= ~(BSIZE-1);
232:
233: lock(seglink);
234: sp = sxalloc(n, f);
235: unlock(seglink);
236:
237: if ( sp == NULL ) {
238: krunch(1000);
239: lock(seglink);
240: sp = sxalloc(n, f);
241: unlock(seglink);
242: }
243:
244: if (sp != NULL) {
245: sp->s_flags = r;
246: vremap( sp );
247: }
248: else {
249: if ((f&SFNSWP) != 0)
250: return (NULL);
251: if ((sp=kalloc(sizeof(SEG))) == NULL)
252: return (NULL);
253: sp->s_forw = sp;
254: sp->s_back = sp;
255: sp->s_flags = r;
256: sp->s_urefc = 1;
257: sp->s_lrefc = 1;
258: if (segsext(sp, n) == NULL) {
259: kfree(sp);
260: return (NULL);
261: }
262: }
263: if ((f&SFNCLR) == 0)
264: pclear( sp->s_paddr, n );
265: return (sp);
266: }
267:
268: /*
269: * Free the given segment pointer.
270: */
271: sfree(sp)
272: register SEG *sp;
273: {
274: register INODE *ip;
275:
276: if ( sp->s_urefc != 1 ) {
277: sp->s_urefc--;
278: sp->s_lrefc--;
279: return;
280: }
281:
282: lock(seglink);
283: --sp->s_lrefc;
284: if (--sp->s_urefc != 0) {
285: unlock(seglink);
286: return;
287: }
288:
289: sp->s_back->s_forw = sp->s_forw;
290: sp->s_forw->s_back = sp->s_back;
291: unlock(seglink);
292:
293: if (sp->s_lrefc != 0)
294: panic("Bad segment count");
295: if ((ip=sp->s_ip) != NULL)
296: ldetach(ip);
297: vrelse( sp->s_faddr );
298: kfree(sp);
299: krunch(0);
300: }
301:
302: /*
303: * Grow or shrink the segment `sp' so that it has size `n'.
304: */
305: seggrow(sp, n)
306: register SEG *sp;
307: fsize_t n;
308: {
309: register SEG *sp1;
310: register fsize_t d;
311: register paddr_t pb;
312: register paddr_t nb;
313: register int dowflag;
314:
315: dowflag = sp->s_flags&SFDOWN;
316:
317: /*
318: * Size of new segment is smaller or the same size as the old
319: * segment.
320: */
321: lock(seglink);
322: d = n - sp->s_size;
323: if (n <= sp->s_size) {
324: sp->s_size = n;
325: if (dowflag)
326: sp->s_paddr -= d;
327:
328: vremap( sp );
329: unlock(seglink);
330: return (1);
331: }
332:
333: if ((sp1=sp->s_back) == &segmq)
334: pb = corebot;
335: else
336: pb = sp1->s_paddr + sp1->s_size;
337:
338: if ((sp1=sp->s_forw) == &segmq)
339: nb = coretop;
340: else
341: nb = sp1->s_paddr;
342:
343: /*
344: * If the segment does not grow down, see if there is enough
345: * space after the segment.
346: */
347: if (dowflag==0 && nb-sp->s_paddr>=n) {
348: pclear(sp->s_paddr+sp->s_size, d);
349: sp->s_size = n;
350: vremap( sp );
351: unlock(seglink);
352: return (1);
353: }
354:
355: /*
356: * If the segment grows down, see if there is enough space
357: * before the segment.
358: */
359: if (dowflag!=0 && sp->s_paddr+sp->s_size-pb>=n) {
360: sp->s_paddr -= d;
361: sp->s_size = n;
362: pclear( sp->s_paddr, d );
363: vremap( sp );
364: unlock(seglink);
365: return (1);
366: }
367:
368: /*
369: * Is there enough space in total counting the gaps on either
370: * side of us?
371: */
372: if (nb-pb >= n) {
373: if (dowflag == 0) {
374: plrcopy(sp->s_paddr, pb, sp->s_size);
375: pclear(pb+sp->s_size, d);
376: sp->s_paddr = pb;
377: } else {
378: prlcopy( sp->s_paddr, nb-sp->s_size, sp->s_size );
379: pclear(nb-n, d);
380: sp->s_paddr = nb-n;
381: }
382: sp->s_size = n;
383: vremap( sp );
384: unlock(seglink);
385: return (1);
386: }
387:
388: /*
389: * Try to allocate a segment somewhere else on the segment queue
390: * and copy ourselves there.
391: */
392: unlock(seglink);
393: if ((sp1=salloc((fsize_t)n, sp->s_flags|SFNSWP|SFNCLR)) != NULL) {
394: if (dowflag == 0) {
395: plrcopy(sp->s_paddr, sp1->s_paddr, sp->s_size);
396: pclear(sp1->s_paddr+sp->s_size, d);
397: } else {
398: plrcopy(sp->s_paddr, sp1->s_paddr+d, sp->s_size);
399: pclear(sp1->s_paddr, d);
400: }
401: lock(seglink);
402: satcopy(sp, sp1);
403: unlock(seglink);
404: return (1);
405: }
406:
407: /*
408: * Last chance. Extend the segment by swapping it.
409: */
410: if (segsext(sp, n) != NULL) {
411: if (dowflag == 0)
412: pclear(sp->s_paddr+n-d, d);
413: else {
414: prlcopy(sp->s_paddr, sp->s_paddr+d, n-d);
415: pclear(sp->s_paddr, d);
416: }
417: return (1);
418: }
419:
420: /*
421: * At least we tried.
422: */
423: return (0);
424: }
425:
426: /*
427: * Given a segment pointer, `sp' and a segment size, grow the given segment
428: * to the given size.
429: */
430: segsize(sp, s2)
431: register SEG *sp;
432: vaddr_t s2;
433: {
434: register vaddr_t s1;
435:
436: s1 = (vaddr_t) sp->s_size;
437: if (seggrow(sp, (fsize_t)s2) == 0) {
438: u.u_error = ENOMEM;
439: return;
440: }
441: if (sproto() == 0)
442: if (seggrow(sp, (fsize_t)s1)==0 || sproto()==0)
443: sendsig(SIGSEGV, SELF);
444: segload();
445: }
446:
447: /*
448: * Grow the segment `sp1' to the size `s' in bytes by swapping it out
449: * and back in. The segment may not be locked.
450: */
451: SEG *
452: segsext(sp1, s)
453: register SEG *sp1;
454: register fsize_t s;
455: {
456: register SEG *sp2;
457:
458: #ifndef NOMONITOR
459: if (swmflag)
460: printf("Segsext(%p, %u)\n", SELF, SELF->p_pid);
461: #endif
462: if (sexflag == 0) {
463: u.u_error = ENOMEM;
464: return (NULL);
465: }
466: lock(seglink);
467: if ((sp2=sdalloc(s)) == NULL) {
468: unlock(seglink);
469: return (NULL);
470: }
471: unlock(seglink);
472: sp1->s_lrefc++;
473: if (sp1->s_size != 0)
474: swapio(1, sp1->s_paddr, sp2->s_daddr, sp1->s_size);
475: lock(seglink);
476: satcopy(sp1, sp2);
477: unlock(seglink);
478: sp1->s_flags &= ~SFCORE;
479: sp1->s_lrefc--;
480: vremap(sp1);
481: segfinm(sp1);
482: return (sp1);
483: }
484:
485: /*
486: * Force the given segment to be in memory. One can only force
487: * one segment to be in memory at a time.
488: */
489: segfinm(sp)
490: register SEG *sp;
491: {
492: register PROC *pp;
493: register int s;
494:
495: if ((sp->s_flags&SFCORE) != 0)
496: return;
497: pp = SELF;
498: sp->s_urefc++;
499: sp->s_lrefc++;
500: pp->p_segp[SIAUXIL] = sp;
501: pp->p_flags &= ~PFCORE;
502: #ifndef QWAKEUP
503: s = sphi();
504: #endif
505: setrun(pp);
506: dispatch();
507: #ifndef QWAKEUP
508: spl(s);
509: #endif
510: pp->p_segp[SIAUXIL] = NULL;
511: sfree(sp);
512: }
513:
514: /*
515: * Make a copy of the segment `sp1' which is in memory by writing
516: * it out to disk.
517: */
518: SEG *
519: segdupd(sp1)
520: register SEG *sp1;
521: {
522: register SEG *sp2;
523:
524: if (sexflag == 0)
525: return (NULL);
526: lock(seglink);
527: if ((sp2=sdalloc(sp1->s_size)) == NULL) {
528: unlock(seglink);
529: return (NULL);
530: }
531: sp1->s_lrefc++;
532: unlock(seglink);
533: swapio(1, sp1->s_paddr, sp2->s_daddr, sp1->s_size);
534: sp1->s_lrefc--;
535: sp2->s_flags = sp1->s_flags & ~SFCORE;
536: sp2->s_size = sp1->s_size;
537: vremap( sp2 );
538: return (sp2);
539: }
540:
541: /*
542: * Given a flag, a physical core address, a disk address and a count in
543: * bytes, perform an I/O operation between core and disk. If `flag' is
544: * set, the transfer is to the disk otherwise it is to memory. As you may
545: * have guessed, this is used by the swapper.
546: */
547: swapio(f, p, d, n)
548: paddr_t p;
549: daddr_t d;
550: fsize_t n;
551: {
552: register BUF * bp;
553: register SEG * sp;
554: register int s;
555: register int nb;
556: static SEG swapseg; /* NOTE: FP_SEL(swapseg.s_faddr) must stay */
557:
558: #ifndef NOMONITOR
559: if (swmflag > 1)
560: printf("swapio(%s,%x,%x,%x)\n",f?"out":"in",(int)p,(int)d,n);
561: #endif
562: if (d < swapbot || d+(n/BSIZE) > swaptop
563: || p < corebot || p+n > coretop)
564: panic("Swapio bad parameter");
565:
566: bp = &swapbuf;
567: sp = &swapseg;
568: lock(bp->b_gate);
569: SELF->p_flags |= PFSWIO;
570: sp->s_flags = SFCORE;
571: sp->s_paddr = p;
572: sp->s_size = n;
573: vremap( sp );
574: bp->b_faddr = sp->s_faddr;
575:
576: while (n != 0) {
577: nb = (n > SCHUNK) ? SCHUNK : n;
578: /*
579: * Prevent I/O transfer from crossing 64 Kbyte boundary.
580: */
581: if ( (p & 0xFFFF0000L) != ((p+nb) & 0xFFFF0000L) )
582: nb = 0x10000L - (p & 0x0000FFFFL);
583: bp->b_flag = BFNTP;
584: bp->b_req = f ? BWRITE : BREAD;
585: bp->b_dev = swapdev;
586: bp->b_bno = d;
587: bp->b_paddr = p;
588: bp->b_count = nb;
589: s = sphi();
590: dblock(swapdev, bp);
591: while ((bp->b_flag&BFNTP) != 0)
592: sleep((char *)bp, CVBLKIO, IVBLKIO, SVBLKIO);
593: spl(s);
594: if ((bp->b_flag&BFERR) != 0)
595: panic("Swapio error");
596: FP_OFF(bp->b_faddr) += nb;
597: p += nb;
598: d += nb / BSIZE;
599: n -= nb;
600: }
601: sp->s_flags = 0;
602: vremap( sp );
603: unlock(bp->b_gate);
604: SELF->p_flags &= ~PFSWIO;
605: }
606:
607: /*
608: * Make the segment descriptor pointed to by `sp1' have the attributes
609: * of `sp2' including it's position in the segment queue and release
610: * `sp2'. `seglink' must be locked when this routine is called.
611: */
612: satcopy(sp1, sp2)
613: register SEG *sp1;
614: register SEG *sp2;
615: {
616: if ( FP_SEL(sp2->s_faddr) != 0 )
617: vrelse( sp2->s_faddr );
618:
619: sp1->s_back->s_forw = sp1->s_forw;
620: sp1->s_forw->s_back = sp1->s_back;
621: sp2->s_back->s_forw = sp1;
622: sp1->s_back = sp2->s_back;
623: sp2->s_forw->s_back = sp1;
624: sp1->s_forw = sp2->s_forw;
625: sp1->s_size = sp2->s_size;
626: sp1->s_paddr = sp2->s_paddr;
627: sp1->s_daddr = sp2->s_daddr;
628: vremap(sp1);
629: kfree(sp2);
630: }
631:
632: /*
633: * Allocate a segment on disk that is `n' bytes long.
634: * The `seglink' gate should be locked before this routine is called.
635: */
636: SEG *
637: sdalloc( s )
638: fsize_t s;
639: {
640: register SEG *sp1;
641: register SEG *sp2;
642: register daddr_t d;
643: register daddr_t d1;
644: register daddr_t d2;
645:
646: d = s / BSIZE;
647: d1 = swapbot;
648: sp1 = &segdq;
649: do {
650: if (d1 >= swaptop)
651: return (NULL);
652: if ((sp1=sp1->s_forw) != &segdq)
653: d2 = sp1->s_daddr;
654: else
655: d2 = swaptop;
656: if (d2-d1 >= d) {
657: if ((sp2=kalloc(sizeof(SEG))) == NULL)
658: return (NULL);
659: sp1->s_back->s_forw = sp2;
660: sp2->s_back = sp1->s_back;
661: sp1->s_back = sp2;
662: sp2->s_forw = sp1;
663: sp2->s_urefc = 1;
664: sp2->s_lrefc = 1;
665: sp2->s_size = s;
666: sp2->s_daddr = d1;
667: return (sp2);
668: }
669: d1 = sp1->s_daddr + (sp1->s_size / BSIZE);
670: } while (sp1 != &segdq);
671: return (NULL);
672: }
673:
674: /*
675: * Allocate a segment in memory that is `n' bytes long.
676: * The `seglink' gate should be locked before this routine is called.
677: */
678: SEG *
679: smalloc(s)
680: fsize_t s;
681: {
682: register SEG *sp1;
683: register SEG *sp2;
684: paddr_t p1;
685: paddr_t p2;
686:
687: p1 = corebot;
688: sp1 = &segmq;
689: do {
690: if ((sp1=sp1->s_forw) != &segmq)
691: p2 = sp1->s_paddr;
692: else
693: p2 = coretop;
694:
695: if (p2-p1 >= s) {
696: if ((sp2=kalloc(sizeof (SEG))) == NULL)
697: return (NULL);
698: sp1->s_back->s_forw = sp2;
699: sp2->s_back = sp1->s_back;
700: sp1->s_back = sp2;
701: sp2->s_forw = sp1;
702: sp2->s_urefc = 1;
703: sp2->s_lrefc = 1;
704: sp2->s_size = s;
705: sp2->s_paddr = p1;
706: /* s_faddr = 0; */
707: /* s_flags = 0; */
708: vremap( sp2 );
709: return (sp2);
710: }
711: p1 = sp1->s_paddr + sp1->s_size;
712: } while (sp1 != &segmq);
713: return (NULL);
714: }
715:
716: /*
717: * Allocate a segment from the high end of memory that is `n' bytes long.
718: * The `seglink' gate should be locked before this routine is called.
719: */
720: SEG *
721: shalloc( s )
722: fsize_t s;
723: {
724: register SEG *sp1;
725: register SEG *sp2;
726: paddr_t p1;
727: paddr_t p2;
728:
729: sp1 = &segmq;
730: p2 = coretop;
731: do {
732: if ((sp1=sp1->s_back) != &segmq)
733: p1 = sp1->s_paddr + sp1->s_size;
734: else
735: p1 = corebot;
736:
737: if (p2-p1 >= s) {
738: if ((sp2=kalloc(sizeof (SEG))) == NULL)
739: return (NULL);
740: sp1->s_forw->s_back = sp2;
741: sp2->s_forw = sp1->s_forw;
742: sp1->s_forw = sp2;
743: sp2->s_back = sp1;
744: sp2->s_urefc = 1;
745: sp2->s_lrefc = 1;
746: sp2->s_size = s;
747: sp2->s_paddr = p2-s;
748: /* s_faddr = 0; */
749: /* s_flags = 0; */
750: vremap( sp2 );
751: return (sp2);
752: }
753: p2 = sp1->s_paddr;
754: } while (sp1 != &segmq);
755: return (NULL);
756: }
757:
758: /*
759: * Set up `SR' structure in user area from segments descriptors in
760: * process structure. Also set up the user segmentation registers.
761: */
762: sproto()
763: {
764: register int n;
765: register SEG *sp;
766:
767: kclear(u.u_segl, sizeof(u.u_segl));
768: for (n=0; n<NUSEG; n++) {
769: if ((sp=SELF->p_segp[n]) == NULL)
770: continue;
771: if (n == SIUSERP)
772: u.u_segl[n].sr_base = &u;
773: else
774: u.u_segl[n].sr_flag |= SRFPMAP;
775: if (n!=SISTEXT && n!=SISDATA)
776: u.u_segl[n].sr_flag |= SRFDUMP;
777: if (n!=SIUSERP && n!=SISTEXT && n!=SIPTEXT)
778: u.u_segl[n].sr_flag |= SRFDATA;
779: u.u_segl[n].sr_size = sp->s_size;
780: u.u_segl[n].sr_segp = sp;
781: }
782: return (mproto());
783: }
784:
785: /*
786: * Search for a busy text inode.
787: */
788: sbusy(ip)
789: register INODE *ip;
790: {
791: register SEG *sp;
792:
793: lock(seglink);
794: /*
795: * Look for the segment in the memory queue.
796: */
797: for (sp=segmq.s_forw; sp!=&segmq; sp=sp->s_forw) {
798: if (sp->s_ip==ip
799: && (sp->s_flags&(SFSHRX|SFTEXT))==(SFSHRX|SFTEXT)) {
800: unlock(seglink);
801: return (1);
802: }
803: }
804:
805: /*
806: * Look for the segment on the disk queue.
807: */
808: for (sp=segdq.s_forw; sp!=&segdq; sp=sp->s_forw) {
809: if (sp->s_ip==ip
810: && (sp->s_flags&(SFSHRX|SFTEXT))==(SFSHRX|SFTEXT)) {
811: unlock(seglink);
812: return (1);
813: }
814: }
815: unlock(seglink);
816: return (0);
817: }
818:
819: /*
820: * Segment consistency checks for the paranoid.
821: segchk()
822: {
823: register SEG *sp;
824: register int nbad;
825: fsize_t s;
826: daddr_t d;
827:
828: nbad = 0;
829: sp = &segmq;
830: s = corebot;
831: while ((sp=sp->s_forw) != &segmq) {
832: if (sp->s_paddr < s)
833: nbad += badseg("mem", sp->s_paddr, 0);
834: s = sp->s_paddr + sp->s_size;
835: }
836: if (coretop < s)
837: nbad += badseg("mem", sp->s_back->s_paddr, sp->s_back->s_size);
838: sp = &segdq;
839: d = swapbot;
840: while ((sp=sp->s_forw) != &segdq) {
841: if (sp->s_daddr < d)
842: nbad += badseg("disk", (int)sp->s_daddr, 0);
843: d = sp->s_daddr + (sp->s_size / BSIZE);
844: }
845: if (swaptop < d)
846: nbad += badseg("disk", sp->s_back->s_daddr, sp->s_back->s_size);
847: }
848:
849: badseg(t, b, s)
850: char *t;
851: daddr_t b;
852: fsize_t s;
853: {
854: printf( "Bad %s segment at %X of len %X\n", t, b, s );
855: return (1);
856: }
857: */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.