Graduate Introduction to Operating Systems (GIOS) Retrospective

May 2, 2019 15:40 · 517 words · 3 minute read

I’m in for a treat if the rest of the courses offered in the OMSCS (online master of science in computer science) program at Georgia Tech hold the same bar quality as graduate introduction to operating systems (read my full review here1). And now that I’m officially done with the course (as of three days ago), I have some breathing room and want to reflect on this past semester.

On preparation

Thankfully, I was well prepared for the course. Before applying to OMSCS, I took a handful of undergraduate computer science courses — discrete mathematics, computer organization, data structures, linear algebra — which built a solid foundation that OS built upon. In addition, I read a decent chunk of up the book Computer System’s from a Programmer’s perspective2, the book used for Carnegie Mellon’s famous course (CS:APP3e3, and worked on several exercises including reverse engineering a C program and writing a primitive shell.

Most memorable learnings

As I mentioned in my omscentral review1, I learned a lot. Instead of listing each and everything I learned, I’ve picked out a few that sparked joy.

Socket Programming

Through the programming assignments (i.e. projects), I worked intimately with the sockets API, building a tcp client and tcp server that implemented a fictious protocol (called GETFILE) that’s basically a watered down version of http. If there’s one thing I’ll never forget about socket programming, it is this: calling send(nbytes) does not guarantee you will send all the bytes sitting in the buffer and calling recv(nbyes) does not guarantee you will receive all the bytes. You must call send (or recv) repeatedly until all the bytes stored in the buffer have been processed.

Threads and processes


First, I learned about threading: How threads share the same virtual

  • How threads share the same virtual address space
  • The difference between threads living in user space (versus kernel space)
  • Why a deadlock might occur (and how to prevent them)
  • How threads coordinate access to a shared resource by using mutexes (i.e. mutual exclusion)
  • How to influence the scheduler by using counters (in combinations with mutexes) or semaphores (which make the code much more clear in comparison to mutexes)


Prior to the course, I can recall two times in which I heard the word semaphore and sort of just shrugging my shoulders, not fully understanding what they were used for. But after taking this course, semaphores are no longer a mystery.

Inter process communication

I learned how processes, which have different virtual address spaces (thanks to the operating system), can cross their boundaries and speak to other processes by using any one of the following interprocess communication techniques:

  • Sockets
  • Message queues (posix or SystemV)
  • Pipes
  • Shared memory (posix or SystemV)

Because I had already programmed in sockets (in project 1), I wanted to learn something new so when I tackled the third project, I tore up the Linux Programming Interface book and learned how to use message queues and shared memory, for building my control plane and dataplane, respectively.