aboutsummaryrefslogtreecommitdiff
path: root/sys/nmemio/salloc.x
diff options
context:
space:
mode:
authorJoseph Hunkeler <jhunkeler@gmail.com>2015-07-08 20:46:52 -0400
committerJoseph Hunkeler <jhunkeler@gmail.com>2015-07-08 20:46:52 -0400
commitfa080de7afc95aa1c19a6e6fc0e0708ced2eadc4 (patch)
treebdda434976bc09c864f2e4fa6f16ba1952b1e555 /sys/nmemio/salloc.x
downloadiraf-linux-fa080de7afc95aa1c19a6e6fc0e0708ced2eadc4.tar.gz
Initial commit
Diffstat (limited to 'sys/nmemio/salloc.x')
-rw-r--r--sys/nmemio/salloc.x155
1 files changed, 155 insertions, 0 deletions
diff --git a/sys/nmemio/salloc.x b/sys/nmemio/salloc.x
new file mode 100644
index 00000000..34f06217
--- /dev/null
+++ b/sys/nmemio/salloc.x
@@ -0,0 +1,155 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <config.h>
+include <syserr.h>
+
+# SALLOC.X -- Stack management routines. Stack storage is allocated in
+# segments. Space for each segment is dynamically allocated on the heap.
+# Each segment contains a pointer to the previous segment to permit
+# reclamation of the space (see "Mem.hlp" for additional details).
+# This is a low level facility, hence any failure to allocate or deallocate
+# stack storage is fatal.
+
+
+# Segment header structure. The header size parameter SZ_STKHDR is defined
+# in <config.h> because it is potentially machine dependent. SZ_STKHDR
+# must be chosen such that the maximum alignment criteria is maintained.
+
+define SH_BASE Memi[$1] # char pointer to base of segment
+define SH_TOP Memi[$1+1] # char pointer to top of segment + 1
+define SH_OLDSEG Memi[$1+2] # struct pointer to header of prev.seg.
+
+
+# SALLOC -- Allocate space on the stack.
+
+procedure salloc (output_pointer, nelem, datatype)
+
+pointer output_pointer # buffer pointer (output)
+int nelem # number of elements of storage required
+int datatype # datatype of the storage elements
+
+int nchars, dtype
+include <szdtype.inc>
+pointer sp, cur_seg
+common /salcom/ sp, cur_seg
+
+begin
+ dtype = datatype
+ if (dtype < 1 || dtype > MAX_DTYPE)
+ call sys_panic (500, "salloc: bad datatype code")
+
+ # Align stack pointer for any data type. Compute amount of
+ # storage to be allocated. Always add space for at least one
+ # extra char for the EOS in case a string is stored in the buffer.
+
+ sp = (sp + SZ_MEMALIGN-1) / SZ_MEMALIGN * SZ_MEMALIGN + 1
+ if (dtype == TY_CHAR)
+ nchars = nelem + 1 # add space for EOS
+ else
+ nchars = nelem * ty_size[dtype] + 1
+
+ # Check for stack overflow, add new segment if out of room.
+ # Since SMARK must be called before SALLOC, cur_seg cannot be
+ # null, but we check anyhow.
+
+ if (cur_seg == NULL || sp + nchars >= SH_TOP(cur_seg))
+ call stk_mkseg (cur_seg, sp, nchars)
+
+ if (dtype == TY_CHAR)
+ output_pointer = sp
+ else
+ output_pointer = (sp-1) / ty_size[dtype] + 1
+
+ sp = sp + nchars # bump stack pointer
+end
+
+
+# SMARK -- Mark the position of the stack pointer, so that stack space
+# can be freed by a subsequent call to SFREE. This routine also performs
+# initialization of the stack, since it the very first routine called
+# during task startup.
+
+procedure smark (old_sp)
+
+pointer old_sp # value of the stack pointer (output)
+bool first_time
+pointer sp, cur_seg
+common /salcom/ sp, cur_seg
+data first_time /true/
+
+begin
+ if (first_time) {
+ sp = NULL
+ cur_seg = NULL
+ call stk_mkseg (cur_seg, sp, SZ_STACK)
+ first_time = false
+ }
+
+ old_sp = sp
+end
+
+
+# SFREE -- Free space on the stack. Return whole segments until segment
+# containing the old stack pointer is reached.
+
+procedure sfree (old_sp)
+
+pointer old_sp # previous value of the stack pointer
+
+pointer old_seg
+pointer sp, cur_seg
+common /salcom/ sp, cur_seg
+
+begin
+ # The following is needed to avoid recursion when SFREE is called
+ # by the IRAF main during processing of SYS_MSSTKUNFL.
+
+ if (cur_seg == NULL)
+ return
+
+ # If the stack underflows (probably because of an invalid pointer)
+ # it is a fatal error.
+
+ while (old_sp < SH_BASE(cur_seg) || old_sp > SH_TOP(cur_seg)) {
+ if (SH_OLDSEG(cur_seg) == NULL)
+ call sys_panic (SYS_MSSTKUNFL, "Salloc underflow")
+
+ old_seg = SH_OLDSEG(cur_seg) # discard segment
+ call mfree (cur_seg, TY_STRUCT)
+ cur_seg = old_seg
+ }
+
+ sp = old_sp # pop stack
+end
+
+
+# STK_MKSEG -- Create and add a new stack segment (link at head of the
+# segment list). Called during initialization, and upon stack overflow.
+
+procedure stk_mkseg (cur_seg, sp, segment_size)
+
+pointer cur_seg # current segment
+pointer sp # salloc stack pointer
+int segment_size # size of new stack segment
+
+int nchars, new_seg
+pointer coerce()
+int kmalloc()
+
+begin
+ # Compute size of new segment, allocate the buffer.
+ nchars = max (SZ_STACK, segment_size) + SZ_STKHDR
+ if (kmalloc (new_seg, nchars / SZ_STRUCT, TY_STRUCT) == ERR)
+ call sys_panic (SYS_MFULL, "Out of memory")
+
+ # Output new stack pointer.
+ sp = coerce (new_seg, TY_STRUCT, TY_CHAR) + SZ_STKHDR
+
+ # Set up the segment descriptor.
+ SH_BASE(new_seg) = sp
+ SH_TOP(new_seg) = sp - SZ_STKHDR + nchars
+ SH_OLDSEG(new_seg) = cur_seg
+
+ # Make new segment the current segment.
+ cur_seg = new_seg
+end