Retaining your sanity while working on SWEB

Posted on Fri 14 August 2015 in university

  • This post was updated 2 times.

I'll openly admit, I'm mostly complaining. This is part of who I am. Mostly I don't see things for how great they are, I just see what could be improved. While that is a nice skill to have, it often gives people the impression that I'm not noticing all the good stuff and only ever talk about negative impressions. That's wrong. I try to make things better by improving them for everyone.

Sometimes that involves a bit of ranting or advice which may sound useless or like minuscule improvements to others. This post will contain a lot of that. I'll mention small things that can make your work with your group easier.

Qemu

Avoid the "Matrix combo"

You are working in a university setting, and probably don't spend your time in a dark cellar at night staring into one tiny terminal window coding in the console. Don't live like that - unless you really enjoy it.

Set your qemu console color scheme to some sensible default, like white on black or black on white instead of the Matrix-styled green on black.

In common/source/kernel/main.cpp:

-term_0->initTerminalColors(Console::GREEN, Console::BLACK);
+term_0->initTerminalColors(Console::WHITE, Console::BLACK);

Prevent automatic rebooting

Update: I've submitted a PR for this issue: #55 has been merged.

When you want to try and find a specific problem which causes your SWEB to crash, you don't want qemu to automatically reboot and cause your terminal or log to become full with junk. Fortunately you can disable automatic rebooting.

In arch/YOUR_ARCHITECTURE/CMakeLists.include (e.g. x86/32):

- COMMAND qemu-system-i386 -m 8M -cpu qemu32 -hda SWEB-flat.vmdk -debugcon stdio
+ COMMAND qemu-system-i386 -m 8M -cpu qemu32 -hda SWEB-flat.vmdk -debugcon stdio -no-reboot

- COMMAND qemu-system-i386 -no-kvm -s -S -m 8M -hda SWEB-flat.vmdk -debugcon stdio
+ COMMAND qemu-system-i386 -no-kvm -s -S -m 8M -hda SWEB-flat.vmdk -debugcon stdio -no-reboot

Automatically boot the first grub entry

If you are going for rapid iteration, you'll grow impatient always hitting Enter to select the first entry in the boot menu. Lucky you! You can skip that and boot directly to the first option. Optionally delete all other entries.

In utils/images/menu.lst:

default=0
timeout=0 

title = Sweb
root (hd0,0)
kernel = /boot/kernel.x

Code

Use Debug color flags different from black and white

The most popular color schemes for Terminal use one of two background colors - black and white. Don't ever use those for highlighting important information unless you want your information to be completely unreadable in one of the most common setups. You can change them to any other color you like.

In common/include/console/debug.h:

-const size_t LOADER             = Ansi_White;
+const size_t LOADER             = Ansi_WHATEVER_YOU_LIKE;

-const size_t RAMFS              = Ansi_White;
+const size_t RAMFS              = Ansi_NOT_WHITE_OR_BLACK;

Use C++11 style foreach loops

You may use C++11 standard code, which brings many features of which I found the easier syntax for writing foreach loops most beneficial. This way of writing foreach loops is shorter and improves the readability of your code a lot.

This is the old style for iterating over a container:

typedef ustl::map<example, example>::iterator it_type;
for(it_type iterator = data_structure.begin();
  iterator != data_structure.end(); iterator++)
{
  iterator->doSomething();
  printf("This isn't really intuitive unless you've more experience with C++.\n");
}

This is the newer method I strongly suggest:

for(auto example: data_structure)
{
  example.doSomething();
  printf("This is much more readable.\n");
}

Have your code compile without warnings

Truth be told, this should go without saying. If your code compiles with warnings it is likely it does not do exactly what you want. We saw that a lot during the practicals. Parts that only looked like they did what you wanted but on a second glance turned out to be wrong were already hinted at by compiler warnings.

If you don't know how to fix a compiler warning, look it up or throw another compiler at it. Since you are compiling with gcc and linting with clang you already have a good chance of being provided with at least one set of instructions on how to fix your code. Or, you know, ask your team members. You're in this together.

Besides, this is about sanity. Here, it's also about code hygiene.

Your code should be clean enough to eat off of. So take the time to leave your [...] files better than how you found them. ~Mattt Thompson

Git

I assume you know the git basics. I am a naturally curious person when it comes to tech (and a slew of other topics) and know a lot of things that don't have any relation to my previous work but I've been told that a lot of people don't know the workflow around github which has become popular with open source. I'll try to be brief. The same workflow can be applied to the gitlab software (an open source solution similar to github).

Let's assume you want to make a change to an open source project of mine, homebrew-sweb. You'd go through the following steps:

  1. Click "fork" on my repository site.
  2. Create a new branch in your clone of the project.
  3. Make changes and commit them.
  4. Push your new branch to your remote.
  5. Click the "submit pull request" button.

This means you don't have write access to their repository but they can still accept and merge your changes quickly as part of their regular workflow. Now, some projects may have differing requirements, e.g. you need to send your PRs to the develop branch instead of master.

A simpler version of this workflow can and should be used when working as a group. Basically use the existing steps without forking the repository.

Have feature branches

You don't want people to work in master, you want to have one known good branch and others which are in development. By working in branches, you can try and experiment without breaking your existing achievements.

Working with branches that contain single features instead of "all changes by Alex" works better because you can merge single features more easily depending on their stability and how well you tested them. This goes hand in hand with the next point.

When working with Pull Requests this has another upside: A Pull Request is always directly linked to a branch. If the branch gets updated server-side, the PR is automatically updated too, helping you to always merge the latest changes. When a PR is merged, the corresponding branch can be safely deleted since all code up to the merge is in master. This helps you avoid having many stale branches. Please don't push to branches with a PR again after merging.

Have a prefix in your branch names

Having a prefix in your branch name before its features signals to others who is responsible for a feature or branch. I used alx (e.g. alx-fork) to identify the branches I started and was the main contributor of.

Always commit into a feature branch

Committing directly into master is equal to not believing in code review. You don't want to commit into master directly, ever. The only exception for this rule in the Operating Systems course is to pull from upstream.

Since you probably set up the IAIK repository as upstream, you would do the following to update your repository with fixed provided by the course staff:

git checkout master
git pull upstream master
git push origin master

When it comes to team discipline I will be the one enforcing the rules. If we agreed on never committing into master I will revert your commits in master even if they look perfectly fine.

Have your reviewers merge Pull Requests

Now, you might wonder why you wouldn't just merge a PR someone found to be fine into master yourself. That is very simple. By having the reviewer click the Merge button, you can track who reviewed the PR afterwards.

Also, it doesn't leave the bitter taste of "I'm so great that I can merge without review" in your mouth. :)

Make sure your pull requests can be automatically merged

Nobody likes merge conflicts. You don't and your group members certainly don't. Make sure your branch can be merged automatically without conflicts into master. That means that before opening a Pull Request, you rebase your branch from master.

git checkout master
git pull
git checkout your-feature-branch
git rebase master

Repeat this process if master was updated after you submitted your PR to make sure it still can be merged without conflicts.

I want to make one thing very clear: As the person sending the Pull Request, it is your responsibility to make sure it merges clean, not the maintainer's nor the project leader's.

The reasoning behind this is taken from open source projects: Whenever you submit a patch but do not intend to keep on working on the software, you are leaving the burden of maintaining your code on the main developer. The least you can do is make sure it fits into their existing code base without additional pain.

Conclusion

There is quite a lot you and your partners can do to make the term with Operating Systems go a lot smoother. Some of it has to do with tech others with communication and team discipline. In case you're about to enroll in the course or already have, I wish you the best of luck!


I'll talk to Daniel about some of those issues and which might be okay to change. He's quite thoughtful about what to include and what not to accept for the project as it's delivered to the students. I'll see which suggestions can be sent upstream and update this post accordingly.


Retaining your sanity while working on SWEB is part 4 of Working on SWEB for the Operating Systems course:

  1. SWEB, qemu and a Macbook Air
  2. How to SWEB on your Mac with OS X
  3. Tools and their experiences with SWEB
  4. Retaining your sanity while working on SWEB