V7 Unix had no stack size limit, and when Unix acquired one
utcc.utoronto.ca
utcc.utoronto.ca
If you're wondering why V7, it was the first portable UNIX and the last public Bell Labs distribution. It's free software now. V6 is the one for which the first BSD was a supplement for and that goes with Lion's commentary and was partially rewritten as xv6. PWB/UNIX, which eventually evolved into Syatem V, also derived from V6. So in a sense V6 is the first portable public common ancestor and V7 is the last.
But you weren't expected to understand them!
;)
Here's your own words now:
https://news.ycombinator.com/item?id=24853698
dmr himself on the subject:
V7's save()/restore() are more portable and easier to understand
So you could execute in parallel multiple processes even if each process used its entire 64 kB space.
Moreover, it was possible to have distinct 64 kB address spaces for code (the UNIX "text" segment) and for data (the unix "data" and "bss" segments + the heap + the stack).
Therefore you could have simultaneously in a 4 MB memory at least 32 processes using the maximum 64 kB code + 64 kB data. It is likely that typically around 100 processes could be resident in the main memory.
Because on PDP-11 each process was limited to a small fraction of the main memory it did not make sense to enforce any additional memory limits.
On other computers where a single process could access all the memory, e.g. on DEC VAX for which most BSD versions were developed, enforcing memory limits became necessary.
Late 70s we bought 1.5Mb of memory for our mainframe, we paid more than a million dollars. The phone in your pocket is 10,000 times faster, has 2000 times more memory, and is 10,000 times cheaper than that mainframe
No one practically worried about supporting 2Gb systems, people wrote small, tight code, spending time to make things fit
Stack growing downwards is enshrined in processor instructions; people like to point at how C has no string types but that right there is another trillion dollar security issue decision..
Not disagreeing with you. Just pointing out that not all microcontrollers are puny. Check your IC specs before deciding things.
prog 3<input_args
or by using a here-document
prog 3<<END args END
find $start [ criteria ] --exec cat {} \; >> ../data.txt
I'm reminded of the seemingly absurdly large limits of function arguments count in Common Lisp implementations. They're so large because you often write:
(apply #'some-function some-data)
which calls some-function with some-data becoming the argument list to the function.Trying to do everything with tail calls in Forth puts you in a position much like any other language: Okay, you can have a single overarching state machine with top-level routines, but you can't factor anything into subroutines because there's no way to 'return'.
Progress: Fifth
Eventually N!
But with lots of threads there aren't enough spaces for them to start from. At least on 32-bit. On 64-bit I think you could have effectively infinite stack, or at least very very large (like 1 GB) stacks. But as far as I know nobody has bothered to do it.
I guess an alternative solution would be to put the stacks in different address spaces somehow, but that could get very complicated (now you have two kinds of pointers). Are there any old systems that had separate heap and stack address spaces?
But that's only because stack space is currently limited. If stack space were as unlimited as heap space then there would be absolutely nothing wrong with using as much stack space as you wanted. It would be better even - stack space is much quicker to allocate and free than heap space.
On 16-bit x86, memory was divided into 64K segments and you could have separate ones for code, data and stack. Having effectively a different address space for code isn't a problem, but languages like C expect that you can pass around pointers to stack variables as well as global/heap ones. So now every data pointer needed to be a "far" one (32 bits, segment:offset), and to dereference it the segment portion would usually have to be loaded into the single "extra" segment register that isn't dedicated to code/data/stack.
With data and stack sharing the same segment, you could use 16 bit pointers for everything and the code was a lot more efficient.
I often want stack allocation without having to worry if it hits some arbitrary limit unrelated to actual memory available. Memory is fungible.
It's true that there are programmers with different values.
Also setrlimit and getrlimit let you query and set stack size which are settable via ulimit utility as well. I don’t want to roll my eyes here but this is some serious FUD.
Here’s my previous response
and the so-called 'inaccuracy' you point out in the previous thread was the entire point of the article for that thread - that programmers need to be aware of the stack size and manage it explicitly, and many do not.