Google
 

Trailing-Edge - PDP-10 Archives - SRI_NIC_PERM_FS_1_19910112 - c/old/lib/sbrk.c
There are 9 other files named sbrk.c in the archive. Click here to see a list.
/*
** sbrk() and brk()
** low level memory allocation for KCC runtimes
*/

#include "c-env.h"

entry brk, sbrk;

static char *curbrk = 0;
extern char *end;
/*
** char *brk(addr)
** char *addr;
**
** Sets the current idea of the break to the given byte pointer
** (which is not checked particularly closely, so don't feed it garbage).
*/

#if (SYS_T20+SYS_10X+SYS_WAITS+SYS_ITS)==0
brk()
{
	return -1;
}
#else

static brk(); /* really not, but we don't want to produce an EXTERN */

#asm

BRK:	MOVE 6,-1(17)			/* Get arg char ptr */
#if SYS_T20
	JUMPL 6,.BRK0			/* OWGBP means extended addressing */
#endif
	HRRZ 1,END			/* Get hard start (assume wd align) */
	TLNN 6,77			/* Is pointer overflowed */
	 CAILE 1,(6)			/* Or are we going back too far? */
	 JRST $RETN			/* Either way, return lossage */

	/*
	** TENEX and TOPS20 assume the first reference will create
	** whatever new pages are necessary, but ITS must explicitly
	** create the pages; unexpected references are assumed to be
	** errors.  WAITS also requires explicit allocation, I think.
	*/

#if SYS_ITS

PG$BTS==12				/* log 2 of ITS page size */
PG$SIZ==2000				/* number of words in ITS page */
PG$MSK==<PG$SIZ-1>			/* mask for address within page */

	MOVEI 1,-1(6)			/* Find highest address we'll need */
	LSH 1,-PG$BTS			/* As page number */
	SKIPN 2,CURBRK			/* Get previously set break */
	 MOVE 2,END			/* Initialize if necessary */
	MOVEI 2,-1(2)			/* As word address */
	LSH 2,-PG$BTS			/* And as page address */
	SUBI 1,(2)			/* Find # of pages we need to gobble */
	JUMPLE 1,.BRK9			/* No new pages needed, go on */
	IMUL 1,[-1,,0]			/* Get (- # pages) in left half */
	HRRI 1,1(2)			/* And 1st new page in rt for AOBJN */
	.CALL [	SETZ
		SIXBIT /CORBLK/
		MOVEI %CBNDR+%CBNDW
		MOVEI %JSELF
		1
		SETZI %JSNEW]		/* Ask ITS for the memory */
	 JRST $RETN			/* Shouldn't fail but lose nicely */
.BRK9:
#endif /* ITS */
#if SYS_WAITS
	MOVEI 1,(6)			/* Get word address (1st free) */
	CORE 1,				/* ask for more core */
	 JRST $RETN			/* no space, tough */
#endif /* WAITS */

	MOVEM 6,CURBRK			/* Set up new break address */
	JRST $RETZ			/* Return 0 for success */
/*
** brk() for extended addressing.
** This needs to be made more efficient someday.
*/

#if SYS_T20
	SEARCH MONSYM			/* Get syms for SMAP% */
	EXTERN $SUBBP			/* And routine to compare bps */

.brk0:	MOVE 6,-1(17)			/* Get ptr to desired new break */
	MOVE 15,6			/* Copy BP here */
	MOVE 16,END			/* And other one here */
	PUSHJ 17,$SUBBP			/* Subtract this one from END */
	SKIPGE 15			/* Never drop below END */
	 JRST $RETN			/* Did, fail */
	HLRZ	5,6		;Get new break swapped
	TRZ	5,770000	;Isolate section number
	SKIPN	4,CURBRK	;Get current break pointer
	 MOVE	4,END		; Initialize if necessary
	HLRZS	4
	TRZ	4,770000	;Again, isolate section number
	CAMG	5,4		;Is new greater than old?
	 JRST	.brk1		;No, check less
	SETZ	1,		;Create new sections
	HRRZ	2,4		;Get current section
	ADDI	2,1		;Point to next available
	SUB	5,4		;Get number of sections to make
	MOVE	3,5		;In AC3
.brk01:	HRLI	2,.FHSLF	;For me, of course
	SMAP%			;Make them or remove them
	 ERJMP	$RETN		;Probably ran out
.brk02:	MOVEM	6,CURBRK	;Save new break
	JRST	$RETZ		;Return success

.brk1:	CAML	5,4		;Is new less than old
	 JRST	.brk02		;Still within same section
	SETO	1,		;Delete sections
	HRRZ	2,5		;Get new (lower) section
	ADDI	2,1		;Add one as starting section to return
	SUB	4,5		;Get number to return
	MOVE	3,4		;Put it where SMAP% can get it
	JRST	.brk01		;Join common code
#endif /* T20 */

#endasm
#endif
/*
** sbrk()
**
** Since the operating system does all the virtual address space
** management, we can allocate things a char at a time, so we don't
** need to take the time to round all our byte counts to words.
** This code should work on any machine as long as brk() works.
**
** Note the strange calling conventions:
**    brk() returns -1 on failure, 0 on success
**    we return -1 on failure, the old break on success
** luckily -1 is not a valid PDP-10 byte pointer.
**
** If nbytes is not positive, we simply return the current break
** without taking the extra effort of calling brk().
*/

char *sbrk (nbytes)
unsigned nbytes;
{
    char *obrk = (curbrk != 0? curbrk : end); /* save old break */
    return (nbytes > 0 && brk (obrk + nbytes)? (char *) -1 : obrk);
}