⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sbm.c

📁 minix软件源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	 */}/* SBM_MMRG(sm) - Merge a memory area with the area following it. *	The node (and memory area) following the SM pointed to are *	merged in and the successor node freed up.  The flags *	and smuse of the current SM (which is not moved or anything) *	remain the same. */sbm_mmrg(smp)struct smblk *smp;{       register struct smblk *sm, *sm2;	sm = smp;	sm->smlen += (sm2 = sm->smforw)->smlen;	/* Add succ's len */	if(sm->smforw = sm2->smforw)            /* and fix linkages */		sm->smforw->smback = sm;	sbm_nfre(sm2);                          /* now can flush succ node */}/* SBM_SPLIT - Split up an area (gets a new smblk to point to split-off *	portion.) * Note returned value is ptr to 2nd smblk, since this is a new one. * Ptr to 1st remains valid since original smblk stays where it is. * NOTE: Beware of splitting up free mem (SM_USE == 0) since sbm_nget may * steal it out from under unless precautions are taken!  See comments * at sbm_mget related to this. */struct smblk *sbm_split(smp,coff)struct smblk *smp;SBMO coff;{       register struct smblk *sm, *smx;	register SBMO csiz;	if((sm = smp)->smlen <= (csiz = coff))		return(0);	if((smx = sbm_nget()) == 0)		return(0);	smx->smlen = sm->smlen - csiz;          /* Set 2nd size */	smx->smaddr = sm->smaddr + csiz;        /* Set 2nd addr */	sm->smlen = csiz;			/* Take from 1st size */	smx->smflags = sm->smflags;             /* Copy flags */	if(smx->smforw = sm->smforw)            /* Splice 2nd after 1 */		smx->smforw->smback = smx;	smx->smback = sm;	sm->smforw = smx;                       /* Put 2nd into chain */	return(smx);                            /* Return ptr to 2nd smblk */}#if 0	/* Replaced by "bcopy" for system-dep efficiency *//* SBM_SCPY - Copy string of bytes.  Somewhat machine-dependent; *	Tries to be clever about using word moves instead of byte moves. */sbm_scpy(from, to, count)       /* Copy count bytes from -> to */char *from, *to;unsigned count;{       register char *s1, *s2;	register unsigned cnt;	int tmp;	if((cnt = count) == 0)		return;	s1 = from;	s2 = to;	while(rndrem((int)s1))		/* Get 1st ptr aligned */	  {     *s2++ = *s1++;		if(--cnt == 0) return;	  }	if(rndrem((int)s2) == 0)	/* Do wd move if ptr 2 now aligned */	  {#ifdef DUMBPCC /* Code for dumber (Portable C type) compiler */		register WORD *ap, *bp;		tmp = cnt;		ap = (WORD *) s1;		bp = (WORD *) s2;		if(cnt = rnddiv(cnt))			do { *bp++ = *ap++; }			while(--cnt);		if ((cnt = rndrem(tmp)) ==0)			return;		s1 = (char *) ap;		s2 = (char *) bp;#else	/* Tight loop for efficient copying on 11s */		tmp = cnt;		if(cnt = rnddiv(cnt))			do { *((WORD *)s2)++ = *((WORD *)s1)++; }			while(--cnt);		if((cnt = rndrem(tmp)) == 0)			return;#endif /*-DUMBPCC*/	  }                             	do { *s2++ = *s1++; }	/* Finish up with byte loop */	while(--cnt);}#endif /*COMMENT*/struct smblk *		/* If it returns at all, this is most common type */sbm_err(val,str,a0,a1,a2,a3)char *str;struct smblk *val;{	int *sptr;	sptr = (int *) &sptr;	/* Point to self on stack */	sptr += 5;		/* Point to return addr */	if((int)sbm_debug==1)		abort();	if(sbm_debug)		(*sbm_debug)(0,*sptr,str,a0,a1,a2,a3);	return(val);}/* These routines correspond to the V7 LIBC routines as described * in the V7 UPM (3).  They should provide satisfactory emulation * if the documentation is correct.  Replacement is necessary since * the SBM routines are jealous and cannot tolerate competition for * calls of SBRK; i.e. the memory being managed must be contiguous. *//* Guaranteed to return word-aligned pointer to area of AT LEAST * requested size.  Area size is rounded up to word boundary. */char *malloc(size)unsigned size;{       register struct smblk *sm, **sma;	register SBMO siz;	siz = rndup(size + sizeof (struct smblk *));   /* Make room for ptr */	if((sm = sbm_mget(siz,siz)) == 0)		return(0);	*(sma = (struct smblk **)sm->smaddr) = sm; /* Store ptr in addr-1 */	return((char *)++sma);}char *alloc(size)     /* For V6 programs - note different failure value! */unsigned size;{       register char *addr;	return((addr = malloc(size)) ? addr : (char *) -1);}free(ptr)char *ptr;{       register struct smblk *sm, **smp;	smp = &((struct smblk **)ptr)[-1];	/* Point to addr-1 */	sm = *smp;				/* Pluck SM ptr therefrom */	if(((sm->smflags&0377) != SM_NID) || sm->smaddr != (SBMA)smp)		return((int)sbm_err(0,"free: bad arg %o", ptr));	sbm_mfree(sm);	return(1);}char *realloc(ptr,size)char *ptr;unsigned size;{       register struct smblk *sm, **smp;	smp = &((struct smblk **)ptr)[-1];	/* Point to addr-1 */	sm = *smp;				/* Pluck SM ptr therefrom */	if(((sm->smflags&0377) != SM_NID) || (sm->smaddr != (SBMA)smp))		return((char *)sbm_err(0,"realloc: bad arg %o",ptr));	if((sm = sbm_exp(sm, rndup(size+(sizeof(struct smblk *))))) == 0)		return(0);	*(smp = (struct smblk **)sm->smaddr) = sm;      /* Save smblk ptr */	return((char *)++smp);}char *calloc(nelem,elsize)unsigned nelem, elsize;{       register SBMO cmin;	register WORD *ip;                     /* Clear in units of words */	register char *addr;	if((cmin = nelem*elsize) == 0           /* Find # bytes to get */	  || (addr = malloc(cmin)) == 0)        /* Get it */		return(0);	ip = (WORD *) addr;			/* Set up ptr to area */	cmin = rnddiv(cmin+WDSIZE-1);		/* Find # words to clear */	do { *ip++ = 0; } while (--cmin);       /* Zap the area */	return(addr);}/* SBM_NGC() - Specific routine for GC'ing SMBLK nodes. * * SBM_XNGC(begp, elsize, type) - Compact nodes of specified type. *      Scans allocated mem from low to high to find chunks with nodes of *	the specified type. *      Flushes current freelist and rebuilds it as scan progresses, *      such that 1st thing on list is lowest-addr node.  When a node is *      seen that can be moved, new node is acquired from freelist if *      it exists, otherwise no move is made.  If a chunk has been scanned *      and no active nodes remain, it is flushed and freelist updated. *      NOTE: This has not yet been verified to work with nodes of any *		type other than SMBLK. */sbm_ngc(){	register struct smblk *sm;	if(!(sm = sbm_nxtra))		return((int)sbm_err(0,"Zero sbm_nxtra"));	sm->smflags |= SM_USE;		/* Ensure this one isn't GC'd */	sbm_xngc(&sbm_nfl, sizeof(struct smblk), SM_MNODS);	sm->smflags = 0;		/* Flush temporary crock */}sbm_xngc(begp, elsize, flag)struct smblk **begp;unsigned elsize, flag;{       register struct smblk *sm, *chk, *smf;	struct smblk *ftail, *savtail;	int cnt, inuse;	*begp = ftail = 0;		/* Flush node freelist */	for(chk = sbm_list; chk; chk = chk->smforw)	  if(chk->smflags&flag)	    {   sm = (struct smblk *) chk->smaddr;		cnt = (chk->smuse)/elsize;		savtail = ftail;		inuse = 0;		smf = *begp;					 /* Set up ptr to 1st freelist node */		while(--cnt >= 0)		  {     /* Here decide if movable */			if(sm->smflags && smf   /* Live and have copy place */			  && (				(sm->smflags&SM_USE) == 0       /* Free mem? */			    ||  (sm->smflags&(SM_MNODS|SM_DNODS))			     )			  && sm->smback)        /* has backptr (see ncpy) */			  {                             /* Move the node */				*begp = smf->smforw;	/* Get free node */				if(smf == ftail)					ftail = 0;				if(smf == savtail)					savtail = 0;				/* Move node.  Already checked for back ptr				 * of 0 since no obvious way to tell where				 * the ptr to list is kept.  Sigh.				 */				sbm_nmov(sm,smf,(struct smblk **)0,elsize);				/* Get ptr to new freelist node.  Note				 * check to ensure that it is not in this				 * same chunk (if it is, no point in moving				 * any nodes!)				 */				if((smf = *begp) >= chk)					smf = 0;        /* Zero if same chk */				sm->smflags = 0;        /* Make node free */			  }			/* At this point, not movable */			if(sm->smflags == 0)            /* Free node? */			  {     if(ftail)               /* Add to freelist */					ftail->smforw = sm;				ftail = sm;				if(*begp == 0)					*begp = sm;				sm->smforw = 0;			  }			else inuse++;			sm = (struct smblk *)((SBMA)sm + elsize);		  }		if(inuse == 0                           /* All free? */		  && (sm = chk->smback))		/* & not 1st? */		  {     if(savtail)                     /* Edit freelist */				(ftail = savtail)->smforw = 0;			else *begp = ftail = 0;			sbm_mfree(chk);			chk = sm;		  }	    }}/* *      Note that proc must return a zero value, or loop aborts and *      returns that selfsame value. */sbm_nfor(flag,nodsiz,proc,arg)int flag;int (*proc)();int nodsiz;struct sbfile *arg;{       register struct smblk *sm, *np;	register int cnt;	int res;	for(sm = sbm_list; sm; sm = sm->smforw)	  if(sm->smflags&flag)	    {   np = (struct smblk *) sm->smaddr;		cnt = sm->smuse/nodsiz;		do {			if(np->smflags)				if(res = (*proc)(np,arg))					return(res);			np = (struct smblk *)((SBMA)np + nodsiz);		  } while(--cnt);	    }	return(0);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -