mostly typed

Dynamic Code Loading on a MCU

This is cross-posted from the TockOS blog and written with Branden Ghena

One key feature of Tock is the ability to load and run multiple applications simultaneously. In a modern computer, the OS uses the Memory Management Unit (MMU) to provide a virtual address space for each process. The code for each process is written assuming that it is the only code in the world and that it can place memory at any address it pleases. The MMU handles translating these virtual addresses into a physical address in real memory, which is shared between all processes. Unfortunately, in the world of embedded systems MMUs are not available. Processors like the ARM Cortex-M series omit them since they are power and area-hungry.

Continue reading →


Lightweight Mailing Lists for GitHub (et al)

There ought to be a way of communicating with users of a library on GitHub. It seems particularly useful for people (like me) who maintain a number of open source libraries that have a significant, but not large, user base.

For example, memjs, postgresql-orm and simple all have fewer than 100 "stargazers". Moreover, these libraries are pretty low volume. However, occasionally there are significant changes and being able to announce, e.g., a breaking feature change or solicit feedback on a particular change would be incredibly useful.

Continue reading →


Experiences Building an OS in Rust

On Sunday, I'll be presenting a paper at Programming Languages and Operating Systems (PLOS) on our experiences building Tock in Rust.

While we (OS and language builders) often like to think of system and language design as separate problems, they are really not. Instead, language features or constraints often lead to very different system designs.

In other words, taking advantage of language features, like memory- and type-safety, is usually not as simple as rewriting your system in a language that offers those features.

We've been experiencing exactly this tension in the year we've spent so far designing and building Tock.

Continue reading →


The ALLOW System Call

It is common for drivers to share data with application via shared memory. For example, an application might need to pass a buffer to a network driver in order to read a packet.

The obvious way to do this is to essentially give drivers complete access to the app's memory. The application passes a pointer and size of the buffer via a system, the kernel interprets these as generic arguments, and the driver directly indexes into the app's memory to use the buffer:

fn subscribe(..., buf_ptr: usize, buf_len: usize) -> isize {
    ...
    let buffer = app.get_mem_slice(buf_ptr, buf_len);
    ...
}

However, providing drivers with full access to application memory forces a trust model in which drivers can completely control application memory. In Tock

Continue reading →


Cannot Declare Drop Types Statically

So far in Tock we have been allocating the chip and platform definitions statically by declaring them in static mutable Option variables. They are declared as None but on platform initialization, we replace their values with real values:

static mut CHIP : Option<sam4l::Sam4l> = None;
static mut FIRESTORM : Option<Firestorm> = None;

pub unsafe fn init() -> &'static Firestorm {
    CHIP = Some(sam4l::Sam4l::new());
    ...
    FIRESTORM = Some(Firestorm {
      ...
    });
    ...
    FIRESTORM.as_mut().unwrap()
}

This works fine as long as the data structures representing chip and platform adhere to the restrictions imposted on statically declared variables. Specifically, Rust forbids statics from containing types with destructors (e.g. types that implement the Drop

Continue reading →


Making GHC and cabal sandbox play nice

UPDATE: cabal exec is now integrated natively into cabal, so this guide is outdated

So you're building something in Haskell. You're most likely using GHC as your compiler, and almost certainly using cabal to manage package dependencies. If you're up on all the hippest new features of cabal, you're probably using sandboxes to make sure your project compiles reliably and can, e.g., depend on older or bleeding-edge versions of packages without affecting your global environment. Great!

However, if your project in anyway invokes GHC (e.g. using the hint package or invoking runghc to run some user generated script), all of a sudden you'll find yourself outside of the sandbox.

This is actually a familiar problem from other languages. For example, the Ruby community uses bundler

Continue reading →


What's taking so long?!

A recent stackoverflow question and related MemCachier support ticket led me to some useful analysis of why memcache requests take so long for large values.

As background, we'd been hearing from a few MemCachier customers that cache requests were often taking as long as 200ms to complete. We expect requests to be on the order of 1-5ms (dominated by EC2 network latency), so 200ms is two orders of magnitude slower than expected. We've always been able to at least determine that this only happens for large values.

Mostly not the network

Continue reading →


My Talk at the GoSF Meetup (January 2013)

I gave a talk at the San Francisco Go Meetup about how we fend off the big bad garbage collector for MemCachier.

With a naive implementation, our benchmarks were showing GC pauses on the order of seconds for heavy (but realistic) workloads. By using the unsafe package and a few simple tricks we were able to reduce worst case GC pauses to a couple dozen milliseconds. GC pauses are now also totally independent of the size of the cache!

I've posted my slides here.

Continue reading →