Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support interrupt calling conventions #1275

Closed
wants to merge 2 commits into from
Closed
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Minor typographic, stylistic edits.
  • Loading branch information
tari committed Sep 8, 2015
commit e25a260680059ffb0183281292ec29a729069c3a
24 changes: 13 additions & 11 deletions text/0000-interrupt-cc.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 9,7 @@ Add compiler support for hardware interrupt calling conventions.

# Motivation

Low-level systems software must often interrupt interrupt service routines
Low-level systems software must often include interrupt service routines
(ISRs) to implement certain functionality. In some cases this is a way to
improve the system's efficiency, while in others it is required for correct
operation.
Expand All @@ -21,9 21,10 @@ providing fast interrupt entry and exit in software is an important goal.

In Rust today, the only option for implementation of such an ISR is to build the
ISR entry point as assembly which may call into Rust code. For example,
[RustOS][https://github.com/ryanra/RustOS], a simple x86 OS kernel implemented
in Rust, currently implements ISRs as callbacks to a single "master" interrupt
handler:
[RustOS][rustos], a simple x86 OS kernel implemented in Rust, currently
implements ISRs as callbacks to a single "master" interrupt handler:

[rustos]: https://github.com/ryanra/RustOS

```
.macro make_callback num
Expand All @@ -47,19 48,14 @@ make_all_callbacks
```

This pair of assembler macros generate 50 different ISRs each of which simply
call the master handler with the interrupt vector number, which in turn
dispatches to code to actually handle the interrupt. This kind of double
call the master handler with the interrupt vector number as a parameter, which
in turn dispatches to code to actually handle the interrupt. This kind of double
dispatch, while functional, is extremely inefficient in all of code size (even
unused ISRs must be generated), runtime memory usage (the double dispatch for
every interrupt requires a minimum of 12 additional bytes on the stack), and
speed (many ISRs are relatively simple, and the overhead of double dispatch may
have a significant effect on performance).

Assembly is required for this task because typically hardware interrupts require
that the ISR preserve the values of all registers. Failure to do so will lead to
unpredictable (inconsistent, even) behavior of the interrupted code. On some
architectures, interrupt exit requires a special instruction like `iret` on x86.

This kind of pattern is common in current bare-metal Rust programs: because the
language provides no satisfactory way to approach the need for ISRs, programmers
resort to inefficient ad-hoc solutions, which are usable but unlikely to be
Expand All @@ -68,6 64,12 @@ this information to the compiler both eliminates these inefficiencies and
exposes more information to the compiler's optimizer for even greater potential
gains.

Assembly is required for this task because typically hardware interrupts require
that the ISR preserve the values of all registers. Failure to do so will lead to
unpredictable (inconsistent, even) behavior of the interrupted code. On some
architectures, interrupt exit also requires a special instruction, such as
`iret` on x86.

# Detailed design

Add a family of `interrupt` calling conventions to Rust, one for each
Expand Down