## Reference documentation on available primitives ### Data Structures For memory safety, the following data structures are opaque and only modified using functions described further down. I still find it useful to understand how they work under the hood. - Handles: addresses to objects allocated on the heap. They're augmented with book-keeping to guarantee memory-safety, and so cannot be stored in registers. See [mu.md](mu.md) for details, but in brief: - You need `addr` values to access data they point to. - You can't store `addr` values in other types. They're temporary. - You can store `handle` values in other types. - To convert `handle` to `addr`, use `lookup`. - Reclaiming memory (currently unimplemented) invalidates all `addr` values. - Kernel strings: null-terminated regions of memory. Unsafe and to be avoided, but needed for interacting with the kernel. - Arrays: size-prefixed regions of memory containing multiple elements of a single type. Contents are preceded by 4 bytes (32 bits) containing the `size` of the array in bytes. - Slices: a pair of 32-bit addresses denoting a [half-open](https://en.wikipedia.org/wiki/Interval_(mathematics)) \[`start`, `end`) interval to live memory with a consistent lifetime. Invariant: `start` <= `end` - Streams: strings prefixed by 32-bit `write` and `read` indexes that the next write or read goes to, respectively. - offset 0: write index - offset 4: read index - offset 8: size of array (in bytes) - offset 12: start of array data Invariant: 0 <= `read` <= `write` <= `size` - File descriptors (fd): Low-level 32-bit integers that the kernel uses to track files opened by the program. - File: 32-bit value containing either a fd or an address to a stream (fake file). - Buffered files (buffered-file): Contain a file descriptor and a stream for buffering reads/writes. Each `buffered-file` must exclusively perform either reads or writes. - Graphemes: 32-bit fragments of utf-8 that encode a single Unicode code-point. - Code-points: 32-bit integers representing a Unicode character. ### 'system calls' Low-level testable primitives for unsafe SubX code. - `write`: takes two arguments, a file `f` and an address to array `s`. Comparing this interface with the Unix `write()` syscall shows two benefits: 1. SubX can handle 'fake' file descriptors in tests. 1. `write()` accepts buffer and its size in separate arguments, which requires callers to manage the two separately and so can be error-prone. SubX's wrapper keeps the two together to increase the chances that we never accidentally go out of array bounds. - `read`: takes two arguments, a file `f` and an address to stream `s`. Reads as much data from `f` as can fit in (the free space of) `s`. Like with `write()`, this wrapper around the Unix `read()` syscall adds the ability to handle 'fake' file descriptors in tests, and reduces the chances of clobbering outside array bounds. One bit of weirdness here: in tests we do a redundant copy from one stream to another. See [the comments before the implementation](http://akkartik.github.io/mu/html/060read.subx.html) for a discussion of alternative interfaces. - `stop`: takes two arguments: - `ed` is an address to an _exit descriptor_. Exit descriptors allow us to `exit()` the program in production, but return to the test harness within tests. That allows tests to make assertions about when `exit()` is called. - `value` is the status code to `exit()` with. For more details on exit descriptors and how to create one, see [the comments before the implementation](http://akkartik.github.io/mu/html/059stop.subx.html). - `allocate`: takes two arguments, an address to allocation-descriptor `ad` and an integer `n` Allocates a contiguous range of memory that is guaranteed to be exclusively available to the caller. Returns the starting address to the range in `eax`. An allocation descriptor tracks allocated vs available addresses in some contiguous range of memory. The int specifies the number of bytes to allocate. Explicitly passing in an allocation descriptor allows for nested memory management, where a sub-system gets a chunk of memory and further parcels it out to individual allocations. Particularly helpful for (surprise) tests. ### Functions The most useful functions from 400.mu and later .mu files. Look for definitions (using `ctags`) to see type signatures. _(Compound arguments are usually passed in by reference. Where the results are c
dwm - dynamic window manager
============================
dwm is an extremely fast, small, and dynamic window manager for X.


Requirements
------------
In order to build dwm you need the Xlib header files.


Installation
------------
Edit config.mk to match your local setup (dwm is installed into
the /usr/local namespace by default).

Afterwards enter the following command to build and install dwm (if
necessary as root):

    make clean install

If you are going to use the default bluegray color scheme it is highly
recommended to also install the bluegray files shipped in the dextra package.


Running dwm
-----------
Add the following line to your .xinitrc to start dwm using startx:

    exec dwm

In order to connect dwm to a specific display, make sure that
the DISPLAY environment variable is set correctly, e.g.:

    DISPLAY=foo.bar:1 exec dwm

(This will start dwm on display :1 of the host foo.bar.)

In order to display status info in the bar, you can do something
like this in your .xinitrc:

    while true
    do
        echo `date` `uptime | sed 's/.*,//'`
        sleep 1
    done | dwm


Configuration
-------------
The configuration of dwm is done by creating a custom config.h
and (re)compiling the source code.
t-token`: stream, delimiter byte -> slice - `skip-chars-matching`: stream, delimiter byte - `skip-chars-not-matching`: stream, delimiter byte from a slice: - `next-token-from-slice`: start, end, delimiter byte -> slice - Given a slice and a delimiter byte, returns a new slice inside the input that ends at the delimiter byte. - `skip-chars-matching-in-slice`: curr, end, delimiter byte -> new-curr (in `eax`) - `skip-chars-not-matching-in-slice`: curr, end, delimiter byte -> new-curr (in `eax`) #### miscellaneous sensors and actuators - `open`: filename, write? -> buffered-file - `time`: returns the time in seconds since the epoch. - `ntime`: returns the number of nanoseconds since some arbitrary point. Saturates at 32 bits. Useful for fine-grained measurements over relatively short durations. - `sleep`: sleep for some number of whole seconds and some fraction of a second expressed in nanoseconds. Not having decimal literals can be awkward here.