What is a runtime, and does C have one?
This piece began from the above question, my initial belief that “no, C obviously does not have a runtime”, confrontation with various sources online which claimed the contrary, and a subsequent desire to figure out whether
- they are abusing the word runtime
- or I am wrong and C does have a runtime
- or this just a semantic quibble and it really doesn’t matter
I don’t attempt here to provide a rigorous definition of “runtime” nor an exhaustive history of the usage of this term.
Part of my hope in sharing this piece is that, by the grace of Cunninghams’ Law someone will show me a neat, tidy, and comprehensive definition of “runtime” that provides necessary and sufficient conditions for determining whether a given system fits that designation or not. Or, at least, that they will share some valuable piece of computing history I missed in my endeavour.
What is a language runtime?
(I am using the term “language” haphazardly here to also cover language implementations, e.g. the python language has multiple implementations, each with different runtimes. Often these implementations are themselves just called “runtimes”, e.g. Bun is a fast all-in-one JavaScript runtime, but I am leaving that sense aside here.)
Let’s begin with a general and hand-wavy definition and see if we can refine it from there.
A runtime is the set of things that have to happen behind the scenes so that your program can run.
There is no formal definition of what constitutes a runtime that I am aware of, but here’s a list of things that probably everyone would agree “if your language has X, it has a runtime”:
- An interpreter or virtual machine. If your language isn’t compiled to native code, it definitely has some kind of layer “underneath” the code you write that is translating your code into machine instructions.
- Garbage collection. If your programming language isn’t doing manual memory management, it likely has a garbage collector doing that work for you, running periodically in the background (unless your computer is designed to explode before it runs out of memory).
- JIT. Some languages will compile some of your code to machine code to be run faster while the program is running.
- Concurrency. If you can schedule a set of operations to happen later, or concurrently with some other set of operations, there’s a good chance that your language’s runtime is involved in determining when to run those operations, how long to let them run, and so on. (Or maybe you are just using OS threads.)
- Stack unwinding and exception handling. Some minimal runtime is, as far as I am aware, required for generating stack traces. Otherwise you may just get, a la C, a crash with a core dump.
- Profiling and debugging. Your language may have built-in facilities to provide performance information (how many times a class of objects were allocated, how long it took to run certain methods, etc).
- Reflection. The ability to inspect the execution environment while your code is running, e.g. to determine the type of of a given value, or dynamically inspect the name of the method currently being executed, may depend on data and functionality provided by the runtime. (Though static reflection is apparently possible.)
Then there are things that are debatably part of a runtime, and if they do deserve that designation, it would be in a “thin” or “minimal” sense:
- The “machinery” to actually begin executing your code. Even C requires some instructions that you don’t actually write that must be run to invoke your code, i.e. crt0. In what follows I’ll sometimes use “crt0” as a metonym for all such similar systems (C++ has an init system that does a bit more work related to exceptions, for example; Java also has an init system that calls your
main
function, which is unsurprising given that it runs on a VM; and so on). - Statically allocated variables. Something must write these into the data segment. Personally I don’t see how this would be considered part of a runtime, since it happens at compile time, but let’s take an expansive view for now. I encountered a couple spots on the web where someone took this position.
- The standard library, as in a set of methods that let you accomplish common tasks or interface with the operating system.
- The “runtime environment” in the sense of the “outside world”, including the environment variables, that are available to your program. These may be accessed via standard library functionality.
Things that I think no one considers to be part of a runtime, but it takes all sorts to make a world, so who knows:
- (I initially had several things on this list, like mutexes and spinlocks and syscalls, but after reconsideration am no longer sure that they are obviously not part part of a runtime, by some broad but fairly well-accepted definition.)
Can we classify these disparate elements?
One way to do so would be to consider these putative elements of a runtime along a sort of “spooky action at a distance” spectrum: what is the relation between the code I write as a programmer and the actual machine code that is executed?
- If there is a perfect isomorphism, there is no runtime. This would be the case if I’m writing assembly. Granted, things like out of order execution, speculative execution and so on mean that even in this case the instructions I write may not translate directly to the behaviour of the chip circuitry, but I think that is clearly irrelevant to the discussion of a language runtime.
- If there are parts of the generated machine code that do not map onto anything that I wrote, but are necessary for the execution of the program, that would constitute the most “heavy weight” form of a runtime.
runtime element | intuitive sense | by isomorphism criterion | checks out? |
---|---|---|---|
garbage collection | heavyweight | heavyweight | yes |
JIT | heavyweight | heavyweight | yes |
bounds checking | midweight | midweight | yes |
crt0 | lightweight | lightweight | yes |
standard library | lightweight? | lightweight? | unclear |
The classification of crt0
as being “highly isomorphic” with source code is perhaps controversial, but I would argue that the presence of a main
function, in the cases where there is a crt0
-style system, should be understood as indicating a straightforward translation to the relevant machine code (or bytecode in the case of VM-based language). This mapping is predictable and regular, even if it isn’t immediately obvious to someone without knowledge of the language, unlike GC, for example, the operation of which is typically unpredictable and irregular.
What about the standard library? I used a question mark above because with all the other elements we are clearly discussing something that is happening at runtime, but the existence of library functions that may or may not be called is a different beast. Whether that code is statically or dynamically linked, calling it part of the runtime seems mistaken. Certainly the code may be called at runtime, and we may wonder about the isomorphism between our invocation of a standard library routine and the code generated by a compiler or interpreter, but the bare “ability to call other procedures provided by a language/implementation” does not seem to merit any special consideration beyond “ability for procedure A to call other procedures at all”.
So we can plausibly classify these runtime elements along a spectrum with a fairly clear criterion for doing so. But merely being able to do this doesn’t indicate that “runtime” is itself a particularly useful concept. We could define a concept “poodlesize” meaning “size of full grown standard poodle” and could classify mammals along a spectrum of “much smaller than poodlesize” to “much larger than a poodlesize”, and seeing that all mammals had a place on that scale could declare it to be a wonderful concept perfectly capable of carving nature at its joints, but probably no biologist or veterinarian or breeder would consider that to be a very useful concept.
Moreover, there is an open question of whether this meager formalization adequately captures how the phrase “runtime” is used in practice. Can we shed any light on this question by examining historical uses of the term?
Historical references
Putting the cart before the horse, just for expository purposes, I’ll sketch out some different notions of runtime that I came across in “the literature”, without yet claiming that there is a hard (or even important) distinction between these:
- Runtime1: just something your program does while it is running. Used in a very general sense just to contrast with things done at compile time.
- Runtime2: code generated at compile time to achieve some functionality deemed important to the correctness of the program. Maybe you didn’t write it explicitly, but there is a clear isomorphism between what you wrote and what was generated (e.g.
array[3]
is expected, in your language, to generate bounds-checking code, or a recursive subroutine call is expected to create a new stack frame). - Runtime3: some functionality your program relies on that you did not write, and which may not be strictly speaking part of the language (in a spec), but which you explicitly invoke, e.g. you import C’s
stdio.h
header and callprintf
. - Runtime4: a program you did not explicitly write, running alongside your program, no clear isomorphism between your source code and generated code.
See the appendix below for a summary of the more interesting and salient discussions I encountered. Doing this reading was the most enjoyable part of this project, so I do recommend at least skimming it for anything that stands out, especially (imo) the 1978 Steelman document.
Some observations:
- Beginning in the early 60s, we see “runtime” used simply in the Runtime1 sense, in opposition to “compile time”, signifying something done while the program is running. “Dynamic” is frequently used as a synonym, in implicit or explicit contrast to “static”, as in the case of allocating memory for arrays dynamically during the execution of an ALGOL program (1960) as opposed to statically up front, or in the case of recursive subroutines (also ALGOL, 1961). In both of these particular cases, as far as I can tell, the compiler would generate code that would e.g. perform the dynamic allocation based clearly on the programmer’s source code. Thus there would be a perfect isomorphism between the source code and generated code, so I consider these to also be examples of Runtime2.
- In McCarthy’s LISP paper of 1960, the “reclamation” system (garbage collection) is a canonical example of a Runtime4 system, though the terminology we would use today to characterize it (“dynamic”, “runtime”) is largely absent, other than it being described as “automatic”.
- Subsequent work on ALGOL runtime type checking (through the 60s and beyond) continues to fall squarely into the Runtime2 camp: code is generated at compile time to perform the necessary runtime checks, without explicit instruction to do so by the programmer. I think the first explicit use of “runtime” in a sense beyond that of Runtime1 is in the 1968 “Type checking at run-time” article.
- The SNOBOL work from 1970 uses runtime in the 2, 3, and 4 senses. This was the first use I found of Runtime3, referring to a standard library of functions as part of the runtime.
- The articles on Pascal from the 70s all use “runtime” in the 1 and 2 senses.
- With the article on the Fortran VAX compiler from the 80s we get another explicit use of Runtime3 when discussing the porting of C libraries.
- The Ada task system described in 1980 is the second (after LISP’s garbage collection) clear description I found of a Runtime4 system, though the “Formal Model of the Tasking Concept” paper also does not explicitly use the term in that sense. The 1985 “Runtime detection and description of deadness errors in Ada tasking” paper does use the term “runtime” to characterize this system, and is the first instance of explicitly using the term in that way, as far as I found. This is also the year of Rovner’s XEROX PARC paper which uses “runtime” in various ways, including Runtime4.
- The first reference I found to C’s crt0 being a “runtime” (Runtime2 in my opinion) was from Usenet in 1983.
Based on this I find that, contrary to my initial belief, the Runtime2 and Runtime3 meanings of “runtime” are both robust (in terms of having distinct uses) and also historically prior to the Runtime4 sense that I previously considered to be a canonical example of what is meant by “runtime”.
Does a Venn diagram help?
I think the answer is “sort of”. It at least clearly conveys that “Runtime environment” has basically nothing to do with the other concepts, despite sharing the term.
Some potential issues with this:
- What about actor-style messaging system? Is there a clear enough isomorphism that this should actually be called Runtime2? Or, as I suspect, does it require enough of a “separate system” (code running “alongside” your code) that it constitutes Runtime4?
- I put
crt0
in Runtime2 but does it really fit there? Is it more like Runtime3? - Are garbage collection systems always clearly in the Runtime4 bucket? Including ref counting GC? Or are they better thought of as straddling 2 and 4?
Is the concept of a runtime useful?
What good does it do us to know whether a given language “has a runtime”? If we thought it didn’t have a runtime (in one of the sense we’ve enumerated), but it did, how significant or impactful would that error be?
- In the context of Runtime1, the question is basically nonsensical. Of course your program “does things” when it runs.
- In the context of Runtime2, this is important to know: if your language is or is not adding runtime type checks or array bounds checks, that will have an impact on safety and performance.
- In the context of Runtime3, it is hard to see how this matters much. Static vs dynamic linking are of course consequential for developing and using/releasing your program, but these are more credibly parts of the compilation of your program than its behaviour when it runs. On the other hand, the question is arguably nonsensical in that it isn’t clear what it would mean to both a) include a header/library and call a function from it, but b) also think that that was NOT part of the language’s “runtime”.
- In the context of Runtime4, knowing whether your language is compiled to native code, or executing via a VM, using a JIT, is garbage collected, are some of the most important things to understand about one’s language.
For this reason, if I were going to suggest modifications to use of the term “runtime” I would suggest that we stop calling the standard library part of a language’s “runtime”, i.e. drop Runtime3 and just refer to these as libraries, which is already common parlance.
But what about the fact that there is precedent for this use going back to the 70s, predating the use of the term in the Runtime4 sense? For that reason alone (along with the fact that whatever confusion this causes seems largely harmless, unless you consider the time I spent working on this to be harmful to society, which I supposed it could be especially if other folks are nerd-sniped in this way), I don’t think it’s worth suggesting modifications to usage of this term. When discussing implementing C or any other language on a given platform, it makes sense to talk about a) the compiler, and b) the “other stuff” which we historically have designated as “runtime”.
And since it seems to hardly matter whether one is mistaken or not about one’s language having a runtime in the Runtime3 sense, even if we were to achieve greater clarity by removing that term from common usage, it doesn’t seem that it would gain us much.
In conclusion
- The concept of runtime is more expansive than I initially thought. I feel confident now in agreeing that yes, C does have a runtime.
- I think the four senses of runtime I elaborated do a pretty decent job of a) capturing the bulk of common usage, b) highlighting some relevant distinctions.
- For the most part, common usage is sensible enough, and the things that people tend to call “runtime” do merit that label.
Appendix
The following is a by no means an exhaustive or particularly rigorous summary of the survey reading I did when looking into this question. It was done by trawling through:
- Google scholar
- Usenet archives
- Some from Usenet Archives which could be a wonderful resource if it were not so brutally slow.
- Google’s usenet archives
- The ACM Digital Library, a truly incredible resource.
The notes that follow summarize or excerpt relevant discussion of runtime-related concept sand terms. In cases where there I found several articles with similar usage from roughly the same time period (and especially regarding the same language), I tried to choose the best representative, just to cut down on repetition.
In reverse chronological order, bolded runtime emphasis added by me.
- Syntactic and Semantic Augments to ALGOL, JW Smith - Communications of the ACM, 1960
- The paper proposes some “syntactic and semantic augments” to ALGOL to facilitate string manipulation. In the context of how substrings of already-allocated strings may be referenced, Smith notes that “if strings are stored as contiguous sets of characters in contiguous memory cells, such an extension would lead to a dynamic (runtime) generation or storage-allocation problem.”
- Here the use of “runtime” seems to refer less to ALGOL’s runtime than the programmer’s need to allocate memory appropriately in the course of the program to support such references. According to Memory Management Reference in 1960 ALGOL had “limited dynamic arrays, but no general heap allocation” so it is possible that the allocation Smith is referring to here would not actually have been possible in ALGOL as it existed at the time.
- Recursive Functions of Symbolic Expressions and their Computation by Machine John McCarthy, 1960, CACM
- This paper introduces LISP and also describes its approach to automatic memory management. The phrase “garbage collection” does not appear here, though another version of the paper mentions that McCarthy and co had already been using that phrase to refer to this system. The reclamation algorithm that is roughly outlined is described as being “automatic” but little else is said about it, nor is any indication given of anything else of this “automatic” nature in LISP at the time. The word “automatic” appears only twice in the paper, both times in reference to the memory reclamation system. The words “dynamic” and “run-time” do not appear anywhere in the paper at all.
- A Computer for Direct Execution of Algorithmic Languages James P Anderson, Eastern Joint Computer Conference, 1961
- I have a hard time understanding what this paper is really about. It seems to be based on the recognition that computers could be better designed to support programming, e.g. by providing “index registers” or “built-in floating point operations” (the latter of which we now generally take for granted) and proceeds to propose a novel computer design which would make computers easier to program, so that “programmers can begin to view problems again, rather than details of machine organization and operation”. The goal of the proposed computer seems to be that it would essentially implement (a subset of) ALGOL assignment and control flow statements directly in hardware.
- The only mention of “runtime” in this article is in a discussion of how ALGOL permits recursive subroutines, and how this “implies a mechanism for assigning storage at runtime” which would presumably have to be implemented in the hardware of the proposed computer.
- Current Developments in Commercial Automatic Programming A. d’Agapeyeff, The Computer Journal, Volume 5, Issue 2, 1962
- Several mentions of manipulating data and handling errors at run time (implicitly as opposed to compile time).
- Programming languages for non-numeric processing—2: An extended ALGOL based language G E Haynam, ACM ‘65: Proceedings of the 1965 20th national conference, 1965
- Framing ALGOL as a “problem oriented language (POL)” this paper discusses extensions to ALGOL that make it more suited to solving certain types of problems, particularly those that COBOL is suited to (data processing). The various mentions of “run-time” refer just to raising errors and dynamically allocating memory.
- Record Handling CAR Hoare, 1966
- I believe the first paper in which Hoare describes the use of null references was from 1965, but this paper does contain a historically interesting discussion of null references.
- On p 13, Hoare discusses dynamic allocation of storage for “record” objects, and also mentions a “garbage collection” system, inspired by LISP. The process described here clearly falls into Runtime4.
- The only explicit mention of “runtime” in this paper is on p35 where he compares the system he is describe with PL/I which “does not attempt to protect a programmer from the results of his own mistakes. There is therefore no checking of the validity of field designators, either at compiler time or at run time”–clearly meant in the Runtime1 sense.
- Type checking at run-time by Scowen, ALGOL Bulletin, Issue 27, 1968
- The paper seems to describe a situation in Algol 60 (and PL/I) where certain type checks and “transfers” (which today I think we would call “coercions” or “casts”, this is mentioned specifically in the context of Algol in The Principles of Programming Languages ch 3 p120) must be performed at runtime, e.g. when the actual parameter to a procedure is different from (but presumably compatible with, otherwise how could the program have typechecked?) the formal parameter. The author gives the example of
if 3 < X then
in which 3 may be either an integer or a real. This is a bit confusing since presumably the compiler knows at this point whetherX
is an int or a real, and no runtime check or transfer should be necessary. The de facto spec on Algol 60, Revised Report on the Algorithmic Language Algol 60, doesn’t seem to make any explicit mention of this issue. It states that, e.g., in a numeric comparison expression, if one operand is a real, both must be a real, but doesn’t indicate whether this is a compile-time or run-time concern. In The Design of the Gier ALGOL Compiler by Naur (1963) we read that the “running system is rather simple-minded about arithmetic expressions. All arithmetic variables are represented as floating point numbers within the machine. The difference between integer and real types only makes itself felt in round-off operations.” Naur’s 1965 follow-up, Checking of operand types in algol compilers describes in some depth an approach to type checking and error handling in which expressions go through a “pseudo-evaluation” phase involving transformation to reverse polish notation form. It also does not explicitly deal with the question of how these runtime type checks (and “transfers”) are applied. - The report A comparison between the ALGOL 60 implementations on the Electrologica X1 and the Electrologica X8 goes into a bit more detail on this, stating that “ALGOL 60 does not have separate expressions of type integer and of type real, and in arithmetic expressions operands of both types may occur… In assigning a real result to a variable declared to be of type integer that result is rounded to an integral value”. Later it notes that due to the mixed-mode arithmetic, “all (dyadic) arithmetic operations must inspect whether both operands have the same type. If not, the operand with integer type is converted to real representation first.” This suggests that such comparison is done at runtime, even in the absence of literals (e.g.
a > b
must involve runtime type checks). This seems to differ from (e.g.) integer promotion in C, where the promotion is done at runtime, but the code to do that is generated at compile time (since the types are known); it appears that, for some reason that remains unclear to me, ALGOL 60 was unable to implement a solution like this.
- The paper seems to describe a situation in Algol 60 (and PL/I) where certain type checks and “transfers” (which today I think we would call “coercions” or “casts”, this is mentioned specifically in the context of Algol in The Principles of Programming Languages ch 3 p120) must be performed at runtime, e.g. when the actual parameter to a procedure is different from (but presumably compatible with, otherwise how could the program have typechecked?) the formal parameter. The author gives the example of
- Compilation of a subset of SNOBOL4 by Santos and Maurer, ACM SIGPLAN Notices, Volume 5, Issue 12, 1970
- Describes SUBBOL, a subset of SNOBOL, and contains various uses of “runtime”, possibly in different senses.
- “SUBBOL is compiled into assembly code and is executed with a small runtime of library subroutines.” The runtime referred to here possibly involves code responsible for calling and managing said assembly code, or it could be just subroutines that are called by the assembly code.
- Later we read that the “compiler itself suffers from several deficiencies, due mostly to the fact that the objective was to produce fast-running object programs and so corners were cut on the compilation phase to allow more time to solve runtime problems”. Here is clearly meant just a contrast to compile time.
- An efficient, incremental, automatic garbage collector By L Peter Deutsch and Daniel G Bobrow, Communications of the ACM, Volume 19, Issue 9, 1976
- An early and seemingly influential paper in GC research, no explicit use of the phrase “runtime” but I am including it here anyway partly because it seems so historically significant, and describes a hybrid system achieving incremental GC via a (traditional?) garbage collector running alongside a system of reference counting.
- Restricted data types, specification and enforcement of invariant properties of variables Normand Buckle, ACM SIGPLAN Notices, Volume 12, Issue 3, 1977.
- Discusses restricted data types, along the lines of Pascal’s subrange types. The various mentions of “runtime” in the paper are all to distinguish the time at which certain checks may be performed from “compile time”, e.g. “In this section, we establish a distinction between the operations executed at runtime to ascertain that the values of specific variables are compatible with their assumed properties (in the following pages, we will simply refer to operations of this kind as verifications) and other conditional operations that are part of the algorithm itself.”
- “Generally, these verifications are not mentioned in the description of the algorithm, but they are included in the program to prevent incorrect execution”, examples include array bounds checking.
- Department Of Defense Requirements for High Order Computer Programming Languages: Steelman 1978, DoD
- This is a fairly fascinating bit of computing history I was completely unaware of. I am not going to go into it other than to note that section 9’s discussion of “Parallel Processing” states that a language meeting the requirements must support a built-in scheduling system capable of orchestrating the running of various “parallel processes”. Today, following Rob Pike’s talk on parallelism and concurrency, we’d probably call these processes concurrent rather than parallel, since the Steelman document stipulates that their semantics shall remain the same even if we’re only talking about “interleaved execution on a single processor”, i.e. there is only one instruction being executed at a time.
- My read of this is that any solution meeting this requirement is going to have to have a Runtime4 type of system for managing the parallel processes. That may be the only Runtime4-ish aspect of Ada: I am not very familiar with Ada, but have read that it does not generally have a GC system (though GC is not prohibited by Ada’s specs). It is possible that its exception management system (another requirement of the Steelman doc) relies on some a sort of Runtime4 system.
- On a formal model of the tasking concept in Ada Hans Henrik Løvengreen and Dines Bjørner, Sigplan 1980.
- “A simple method for describing concurrent aspects of a language is to introduce some very simple concurrency concepts in the meta-language used for the semantics definition of the sequential parts of the language, and use these concepts to model the more complex parallelism concepts of the language”, based on Hoare’s CSP paper.
- The paper describes, at a high level, approaches to suspending processes and synchronizing communicating processes, as well as non-deterministically choosing which ones are ready to communicate. Various “meta-process” types are described with names like
SYSTEM
andMONITOR
that dynamically manage the user-defined processes. - The word “runtime” appears only in discussion of compilation stripping from source code anything that “does not influence the Dynamic (run-time) Semantics (DS)”.
- “Questions about nil-pointer dereferences (the ‘plague’)” from Usenet net.unix-wizards 1/4/1983
- The commenter writes about the C compiler on Unix V7: “As it so happens, the bit being checked is in the correct state because of the particular instructions in crt0.o. However, we changed the runtime startoff routines, the bit changed, and a syntax error was generated where none in fact existed.” This was the first reference I found to crt0 in terms of “runtime”.
- On Adding Garbage Collection and Runtime Types to a Strongly-Typed, Statically-Checked, Concurrent Language by Paul Rovner, XEROX PARC publication, 1985
- I love the abstract here: “Enough is known now about garbage collection, runtime types, strong-typing, static-checking and concurrency that it is possible to explore what happens when they are combined in a real programming system.” What a cool time to be a programmer or computer scientist this must have been. Much discussion of aspects falling under all 4 of the sense of runtime outlined above.
- Fortran-77 compiler for VAX UNIX from net.lang.fortran, 09/01/1985
- The author of this post expresses their desire to be able to compile a DBMS system called RIM (Relational Information Manager), written for VMS Fortran, so that it can run with a UNIX Fortran compiler which was “written in C and uses D. M. Ritchie’s Standard C I/O package as the main part of the runtime I/O library.”
- “Runtime” is clearly used here in the sense of some library methods one can call out to explicitly from one’s program.
- Runtime detection and description of deadness errors in Ada tasking by Helmbold and Luckham, ACM SIGAda Ada Letters, Volume IV, Issue 6, 1985.
- This seems to describe an Ada monitoring system, compiled and run separately from Ada’s own runtime task supervisor. “Our monitor system has two parts : (1) a separately compiled run-time monitor written in Ada, and (2) a preprocessor that transforms Ada source text so that necessary descriptive data is communicated to the monitor at run-time. The result of applying the preprocessor to any legal Ada program is a modified program which is again a legal Ada program and contains the monitor . When this modified program is run, sufficient information about tasking activities in the original program will be passed to the monitor, enabling it to detect imminent dead states and provide descriptive information.”
- This paper is interesting also for its use of the term “deadness errors” which today I think we would call “deadlocks”.
- A runtime supervisor to support Ada tasking: rendezvous and delays Riccardi and Baker, ACM SIGAda Ada Letters, Volume V, Issue 2, 1985
- Describes the implementation of an Ada runtime supervisor which manages the execution of tasks, which are (apparently) how Ada manages concurrency. These seem to correspond roughly to what are now called “green threads” i.e. do not necessarily correspond 1-1 to operating system threads.
- “In order for the Ada programming language to be useful for implementing real time systems on microcmputers, the tasking operations must be implemented efficiently. This paper presents a run-time supervisor to support the rendezvous and delays of Ada tasks, which has been designed to be both simple to implement and efficient to execute.”
- Converting DG Nova FORTRAN-66 to F77 under Unix from Usenet net.lang.f77, 29/03/1986
- “I am preparing to port a rather large FORTRAN-66 program running under Xebec’s xdos on a Data General Nova over to f77 under U??X. I was wondering if anyone has any experience in Xebec’s xdos and/or porting software from it??? The differences in i/o are giving us the hardest time (i.e. xdos can open the same file for sequential access and direct access, etc.). Are there any tools available to help in the conversion?? We have a lex script that makes most syntax changes. Our approach to the conversion to touch as little of the existing code, but to write a layer of software underneath the application that emulates all the xdos system calls. This is especially tricky when it comes to i/o because it means writing your own runtime library.”
- It is not perfectly clear in what sense the author means with “runtime” here. Do they mean “simply” writing library methods that would translate xdos calls to UNIX style syscalls? Or would the combination of direct and sequential file access necessitate some kind of bookkeeping and temp/virtual file system to run alongside the program?
- explicit runtime condition code checking, particularly overflow comp.lang.c, 2/12/2987
- This thread is one of the earliest uses of the phrase “runtime” in the comp.lang.c group, a particularly relevant discussion in which the poster wonders whether “there’s ANY way of doing runtime condition code checking in C. In particular, I’d like to know if there’s any way to write a line of C code which essentially translates into a Branch On Overflow” (the answer is basically “no”).
- operating system for the hp-41 calculators from comp.sys.hp, 22/03/1988
- “For a few years now, I have been working on and off in my spare time (of which there is not much) on an “operating system” for the hp41 line. Since I do not belong to any user groups, I don’t really know if anything like it is already out there somewhere. I would like to briefly describe my system, so that you may tell me if it sounds good, sounds bad, if I am developing something worthwhile, or if I’m wasting my time. This “system” consists of an executive and runtime library that remain in low memory, and a bunch of utility routines found on most operating systems. The optimal system to run on would be an hp-41cx with maximum extended memory. The executive treats x-mem as a ram-disk, and stores all commands and utilities there. Most applications can run under the system, if those applications follow some simple conventions. The system basically manages memory and resources for you, the way an operating system should. The system features a runtime library which applications may use for doing standard system things, like writing into the system log, etc.”
- Runtime is clearly meant in the sense of “here are some functions you can call to get the OS to do things for you.”
- Automatic Garbage Collection (was Re: Object Suicide) from comp.programming 4/5/1992
- This was the first explicit reference I found describing garbage collection as part of a “runtime system”. It seems clear however that there must have been other explicit associations of these terms prior to this since, e.g. in another discussion of GC from this year in the same new group (Automatic Garbage Collection Taken Too Far!), the Common LISP (CL) runtime system/environment comes up several times.
- APL runtime optimizations? from comp.lang.apl, 06/03/1992
- “I have heard that some APL compiler (around 1974 at PARC?) made the following sort of dynamic optimization hack on procedures: when a procedure is called on a set of arguments, the procedure is compiled wrt the argument types given. The next time the procedure is called, if the arguments’ types match the previous call then the compiled version is used… I am looking for literature on this specific APL runtime hack.”
- The reference to “runtime” here is to a system running alongside one’s program dynamically memoizing a function.
I bounded my investigations at this point in the early 90s simply because
- I didn’t want to continue this research forever, and the further we progress through time, more seemingly relevant literature there is.
- I was more interested in older “precedent-setting” usage.
- I don’t believe there was much novel usage to be discovered beyond that point.
Thanks to Dan Gorman for providing feedback on an earlier draft of this. Any errors or boring parts are his fault.