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