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