This is not the current version of the class.

# Example design document

Let this quick example design document serve as an inspiration for you. (Yours should be better, of course.)

## 1. Interface

struct proc { ...
flangestate* flange_;   // initially nullptr
};

struct flangestate {
spinlock lock_;
wait_queue wq_;
butt** butt_table_;
...

void bend();
...
};

struct butt {
spinlock lock_;
unsigned refct_;
int type_;
...

virtual ~butt();
void put_ref();

virtual ssize_t measure();
virtual void copy_shape(char* dest);
};


Each flangestate is pointed to by exactly one proc. Each butt is pointed to by one or more butt_table_ entries. A butt’s refct_ member is always greater than or equal to the number of references to the butt from system butt_table_s. We expect butt to be subclassed with specific kinds of butt, for instance, plumber_butt in problem set 4.

## 2. Functionality

flangestate::bend(): This method bends the flangestate, rearranging its butts in random order. That means…

butts are always dynamically allocated by kalloc/knew<butt>(). It is invalid to allocate a butt on the stack.

butt::put_ref(): Decrements butt::refct_ by one. If the resulting count is 0, frees the butt.

butt::measure(): Returns the size of the butt in micrometers.

butt::copy_shape(dest): Writes information about the butt’s shape to the dest pointer. Writes up to 128 bytes.

## 3. Synchronization and blocking

flangestate::lock_ protects flangestate::butt_table_.

flangestate::bend() must be called with flangestate::lock_ locked.

butt::lock_ protects butt::refct_ and …. In the lock ordering, flangestate::lock_ < butt::lock_ (so it’s OK to lock butt::lock_ while flangestate::lock_ is held).

butt::type_ is set when the butt is initialized and cannot be changed thereafter. A butt is only destroyed when its refct_ falls to zero.

butt::measure() can block.

## 4. Future directions

If we introduce threads, a flangestate might be shared between multiple struct procs.

If threads can free memory as well as allocate memory, we might need to change butt::copy_shape to validate the destination memory before writing to it.

128 bytes is enough for all butt shapes we can think of, but we might need to raise it if we add support for virtual machines.

## 5. Concerns

We’re worried that butt::copy_shape() will be wicked hard to write.

We’re not sure we understand the synchronization requirements of flangestate::bend().