Skip to content

Commit d02a72a

Browse files
authored
temporary pntrString (#72)
* describe a stack for temporaries * document outOfMemory * improve description of outOfMemory * doxy for db, cmdInput1 * doxy tempAllocStack * file description of mmvstr.c * doxy let, more tweaks * more preconditions * move the desription db1 to the right place * screen width * fix description of NDEBUG * fix NDEBUG explanation * doxy left * describe pushTempAlloc Co-authored-by: Wolf Lammen <[email protected]>
1 parent 2c1c806 commit d02a72a

File tree

6 files changed

+327
-27
lines changed

6 files changed

+327
-27
lines changed

src/mmdata.c

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,28 @@ vstring g_qsortKey; /* Used by qsortStringCmp; pointer only, do not deallocate *
156156
* - the **used block array** pointed to by \a memUsedPool.
157157
*/
158158

159+
/*! \page stack Temporary Allocated Memory
160+
* Very often a routine needs some memory, that must live only as long as the
161+
* routine is active. Such memory is called **temporary**, or short **local**.
162+
* Once a routine finishes, on return to its caller, it deallocates all its
163+
* __local__ memory again. Since routines frequently call subroutines, the
164+
* same may hold for nested code, and so on. In fact, this concept is so
165+
* ubiquitous and frequent, that the processor, and all relevant program
166+
* languages provide simple mechanisms for de/allocation of such __local__
167+
* data. Metamath is no exception to this.
168+
* While the C compiler silently cares about __local__ variables, it must not
169+
* interfere with data managed by a \ref suballocation "Suballocator". Instead
170+
* of tracking all __locally__ created memory individually for later
171+
* deallocation, a stack like \ref Pool "pool" allows a command like
172+
* `free all memory` that has been created after a certain point. This greatly
173+
* automatizes handling of these data.
174+
*
175+
* A stack is not the same as a \ref block "block", though similar. Like a
176+
* block it is defined as an array of elements, but it comes with no hidden
177+
* header. Instead openly accessible stack pointer (actually indices) directly
178+
* support stack semantics.
179+
*/
180+
159181
/* Memory pools are used to reduce the number of malloc and alloc calls that
160182
allocate arrays (strings or nmbr/pntrStrings typically). The "free" pool
161183
contains previously allocated arrays that are no longer used but that we
@@ -722,7 +744,13 @@ void bug(int bugNum)
722744
exit(1); /* Use 1 instead of 0 to flag abnormal termination to scripts */
723745
}
724746

725-
747+
/*!
748+
* \def M_MAX_ALLOC_STACK
749+
*
750+
* The number of pointers in a \ref stack "stack" available for data reference.
751+
* Since a stack has a terminal null element, the usable count is one less than
752+
* the number given here.
753+
*/
726754
#define M_MAX_ALLOC_STACK 100
727755

728756
/* This function returns a 1 if any entry in a comma-separated list
@@ -2384,6 +2412,14 @@ long g_pntrTempAllocStackTop = 0; /* Top of stack for pntrTempAlloc function
23842412
long g_pntrStartTempAllocStack = 0; /* Where to start freeing temporary allocation
23852413
when pntrLet() is called (normally 0, except in
23862414
special nested vstring functions) */
2415+
/*!
2416+
* \var pntrTempAllocStack
2417+
* \brief a \ref stack "stack" of \a temp_pntrString.
2418+
*
2419+
* Holds pointers to temporarily allocated data of type \a pntrString. Such a
2420+
* \ref stack "stack" contains strictly __local__ data of a function, not
2421+
* accessed from outer levels.
2422+
*/
23872423
pntrString *pntrTempAllocStack[M_MAX_ALLOC_STACK];
23882424

23892425

src/mmdata.h

Lines changed: 80 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,42 @@
1414
#include "mmvstr.h"
1515

1616
/* debugging flags & variables */
17-
/*E*/extern long db,db0,db1,db2;
1817
/*!
18+
* \var db
19+
* \brief bytes held by vstring instances outside of the stack of temporaries
20+
*
21+
* monitors the number of bytes (including the terminal NUL) currently used in
22+
* all \a vstring pointer variables OUTSIDE of the \a tempAllocStack. Note:
23+
* This is NOT the number of bytes allocated, but the portion actually used! A
24+
* few memory allocations are also included:
25+
* - command line buffers used to hold user input from a console;
26+
* - buffers used to read file contents in.
27+
*
28+
* If the user has turned MEMORY_STATUS on, metamath will print out this value
29+
* after each command in a message like "Memory: string < db >".
30+
*/
31+
/*E*/extern long db;
32+
/*E*/extern long db0;
33+
/*!
34+
* \var db1
35+
* \brief bytes held by vstring instances inside of the stack of temporaries
36+
*
37+
* monitors the number of bytes currently pointed to by \a vstring pointers
38+
* INSIDE the \a tempAllocStack. Note: This is NOT their capacity, but the
39+
* portion actually used!
40+
*
41+
* Not updated if NDEBUG (usually deactivates asserts in C code) is defined.
42+
*
43+
* \bug Seems never be displayed.
44+
*/
45+
/*E*/extern long db1;
46+
/*E*/extern long db2;
47+
/*!
48+
* \var db3
1949
* \brief monitors the de/allocations of nmbrString and pntrString outside of
2050
* temporary arrays.
2151
*
22-
* The number of bytes held in blocks dedicated to global data. There exists
52+
* The number of bytes held in blocks dedicated to global data. There exist
2353
* also temporary stacks, but they are not considered here. Useful to see
2454
* whether a process looses memory due to imbalanced calls to allocation/free
2555
* functions.
@@ -30,6 +60,7 @@
3060
/*E*/extern long db3;
3161
/*E*/extern long db4,db5,db6,db7,db8;
3262
/*!
63+
* \var db9
3364
* \brief log memory pool usage for debugging purpose.
3465
*
3566
* If set to a non-zero value, the state of the memory pool is
@@ -54,8 +85,8 @@
5485
typedef char flag;
5586

5687
/*!
88+
* \var g_listMode
5789
* \deprecated
58-
* \var flag g_listMode.
5990
* Obsolete. Now fixed to 0. Historically the metamath sources were also used
6091
* for other purposes than maintaining Metamath files. One such application, a
6192
* standalone text processor, was LIST.EXE. The sources still query this
@@ -64,7 +95,7 @@ typedef char flag;
6495
*/
6596
extern flag g_listMode; /* 0 = metamath, 1 = list utility */
6697
/*!
67-
* \var flag g_toolsMode.
98+
* \var g_toolsMode
6899
* Metamath has two modes of operation: In its primary mode it handles
69100
* mathematical contents like proofs. In this mode \a g_toolsMode is set to
70101
* 0. This is the value assigned on startup. A second mode is enabled after
@@ -76,7 +107,7 @@ extern flag g_toolsMode; /* In metamath mode: 0 = metamath, 1 = tools */
76107
typedef long nmbrString; /* String of numbers */
77108
/*!
78109
* \typedef pntrString
79-
* \brief an array of untyped pointers (void*)
110+
* \brief an array (maybe of size 1) of untyped pointers (void*)
80111
*
81112
* In general this array is organized like a stack: the number of elements in
82113
* the pntrString grows and shrinks during program flow, values are pushed and
@@ -90,9 +121,8 @@ typedef long nmbrString; /* String of numbers */
90121
*
91122
* To summarize the usages of this type:
92123
* - If you want to resize the array/stack you need a pointer to element 0.
93-
* - Given an arbitrary pointer from the array allows you to iterate to the
94-
* end.
95-
*
124+
* - You can iterate from an arbitrary pointer to the end.
125+
* - Sometimes it denotes an isolated element, not embedded in a greater array.
96126
*/
97127
typedef void* pntrString; /* String of pointers */
98128

@@ -104,6 +134,15 @@ typedef nmbrString temp_nmbrString;
104134
/* A pntrString allocated in temporary storage. These strings will be deallocated
105135
after the next call to `pntrLet`.
106136
See also `temp_vstring` for information on how temporaries are handled. */
137+
138+
/*!
139+
* \typedef temp_pntrString
140+
* \brief a single \a pntrString element for use in a \ref stack "stack".
141+
*
142+
* These elements are pushed onto and popped off a \ref stack
143+
* "stack of temporary data". Special commands can free all pointers on and
144+
* after a particular one in such a stack.
145+
*/
107146
typedef pntrString temp_pntrString;
108147

109148
enum mTokenType { var_, con_ };
@@ -260,6 +299,7 @@ void addToUsedPool(void *ptr);
260299
void memFreePoolPurge(flag untilOK);
261300
/* Statistics */
262301
/*!
302+
* \fn getPoolStats
263303
* \brief Provide information about memory in pools at the instant of call.
264304
*
265305
* Return the overall statistics about the pools \ref memFreePool
@@ -292,9 +332,27 @@ void initBigArrays(void);
292332
long getFreeSpace(long max);
293333

294334
/* Fatal memory allocation error */
335+
/*!
336+
* \fn outOfMemory
337+
* \brief fatal memory allocation error.
338+
*
339+
* called when memory cannot be allocated, either because memory/address space
340+
* is physically exhausted, or because administrative structures would overflow.
341+
* Stops execution and wait for the user to confirm having read the message,
342+
* before exiting the program raising an error condition.
343+
*
344+
* \param msg error message displayed to the user.
345+
* \returns never, but exits the program instead.
346+
* \bug calls functions like print2, that in turn may call outOfMemory again
347+
* under restricted memory conditions, so finally memory error messages are
348+
* stacked up endlessly.
349+
*/
295350
void outOfMemory(const char *msg);
296351

297352
/* Bug check error */
353+
/*!
354+
* \fn bug
355+
*/
298356
void bug(int bugNum);
299357

300358

@@ -312,8 +370,8 @@ extern struct nullNmbrStruct g_NmbrNull;
312370
/*!
313371
* \struct nullPntrStruct
314372
* describing a \ref block of \a pntrString containing only the null
315-
* pointer. Besides this pointer it is accompanied with a header matching
316-
* the hidden administrative values of a usual pntrString managed as a stack.
373+
* pointer. Besides this pointer it is accompanied with a header containing
374+
* the hidden administrative values of such \ref block "block".
317375
*
318376
* The values in this administrative header are such that it is never subject to
319377
* memory allocation or deallocation.
@@ -348,7 +406,8 @@ struct nullPntrStruct {
348406
*/
349407
pntrString nullElement; };
350408
/*!
351-
* \var g_PntrNull. Global instance of a memory block structured like a
409+
* \var g_PntrNull
410+
* Global instance of a memory block structured like a
352411
* \a pntrString, fixed in size and containing always exactly one null pointer
353412
* element, the terminating NULL. This setup is recognized as an empty
354413
* \a pntrString.
@@ -530,6 +589,14 @@ long compressedProofSize(const nmbrString *proof, long statemNum);
530589
/******* Special purpose routines for better
531590
memory allocation (use with caution) *******/
532591

592+
/*!
593+
* \var g_pntrTempAllocStackTop
594+
*
595+
* Index of the current top af the \ref stack "stack" \a pntrTempAlloc.
596+
* New data is pushed from this location on if space available.
597+
*
598+
* \invariant always refers the null pointer element behind the valid data.
599+
*/
533600
extern long g_pntrTempAllocStackTop; /* Top of stack for pntrTempAlloc function */
534601
extern long g_pntrStartTempAllocStack; /* Where to start freeing temporary
535602
allocation when pntrLet() is called (normally 0, except for nested
@@ -569,6 +636,7 @@ temp_pntrString *pntrNSpace(long n);
569636
temp_pntrString *pntrPSpace(long n);
570637

571638
/*!
639+
* \fn pntrLen
572640
* \brief Determine the length of a pntrString held in a \ref block "block"
573641
* dedicated to it.
574642
*
@@ -582,6 +650,7 @@ temp_pntrString *pntrPSpace(long n);
582650
*/
583651
long pntrLen(const pntrString *s);
584652
/*!
653+
* \fn pntrAllocLen
585654
* \brief Determine the capacity of a pntrString embedded in a dedicated block
586655
*
587656
* returns the capacity of pointers in the array pointed to by \p s,

src/mminou.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,16 @@ flag g_quitPrint = 0; /* Flag that user quit the output */
6363
flag localScrollMode = 1; /* 0 = Scroll continuously only till next prompt */
6464

6565
/* Buffer for B (back) command at end-of-page prompt - for future use */
66+
/*! \var backBuffer
67+
* Buffer for B (back) command at end-of-page prompt.
68+
*/
6669
pntrString_def(backBuffer);
6770
/*!
6871
* \var backBufferPos
72+
*
73+
* A position within the \a backBuffer.
74+
*
75+
* \invariant The value 0 requires an empty \a backBuffer.
6976
*/
7077
long backBufferPos = 0;
7178
flag backFromCmdInput = 0; /* User typed "B" at main prompt */

src/mminou.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,20 @@ extern vstring g_input_fn, g_output_fn; /* File names */
4747
/* print2 returns 0 if the user has quit the printout. */
4848
flag print2(const char* fmt,...);
4949
extern long g_screenHeight; /* Height of screen */
50+
/*!
51+
* \var g_screenWidth
52+
* The minimum width of the display, measured in fixed width characters.
53+
*/
5054
extern long g_screenWidth; /* Width of screen */
55+
/*!
56+
* \def MAX_LEN
57+
* \brief Default width of screen
58+
*
59+
* Number of characters that can always be displayed in a single line. This
60+
* notion is reminiscent of CRT tubes with a fixed width character set.
61+
* Graphical Displays on a notebook for example can display much more, but on
62+
* some mobile devices this may be reduced to 30-40 characters.
63+
*/
5164
#define MAX_LEN 79 /* Default width of screen */
5265
#define SCREEN_HEIGHT 23 /* Lines on screen, minus 1 to account for prompt */
5366
extern flag g_scrollMode; /* Flag for continuous or prompted scroll */
@@ -56,6 +69,14 @@ extern flag g_quitPrint; /* Flag that user typed 'q' to last scrolling prompt */
5669
/* printLongLine automatically puts a newline \n in the output line. */
5770
void printLongLine(const char *line, const char *startNextLine, const char *breakMatch);
5871
vstring cmdInput(FILE *stream, const char *ask);
72+
/*!
73+
* gets a line from either the terminal or the command file stream depending on
74+
* g_commandFileNestingLevel > 0. It calls cmdInput().
75+
* \param ask text displayed before input prompt. This can be located in
76+
* \a tempAllocStack.
77+
* \returns the entered input.
78+
* \warning the calling program must deallocate the returned string.
79+
*/
5980
vstring cmdInput1(const char *ask);
6081
flag cmdInputIsY(const char *ask);
6182

0 commit comments

Comments
 (0)