/Teaching/System Level Programming/Assignments/A4

Task: Inter-process Communication (IPC)

This assignment aims to teach you the basics of inter-process communication (IPC), its use and how you can realize it.

Main Idea

Everybody of us has used inter-process communication already. Mostly unintentionally at this point in your studies. This is why we wanted to take this specific topic into this semester’s course.

To understand the concept of IPC, some major concepts must be learned and understood beforehand.

  • Virtual Memory
  • Process vs. Thread
  • Shared Resources
  • Locking

Some of those terms are already familiar to you, others not. We will not entirely go into details for this assignment, but it’s always useful looking up information based on those keywords.

Implementation details: Memory Game

For this assignment you will have to implement a simple memory game, which consists of one Player process and one Board process communicating with each other using shared memory.

The Player process is the initial process. It sets up shared memory and synchronization before spawning the Board process. For initializing the shared memory, CAREFULLY take a look at the defines in util.h. It contains the expected shared memory object names, flags for permissions, the pre-defined structs, and the shmlocks struct where you must put your shared locks.

This assignment focuses on your understanding of shared memory, shared synchronization, processes, request/response communication, and cleaning up everything properly again. The helper functions for shuffling, revealing and checking the board are provided. You must implement the command handling and connect the two processes.

You MUST NOT change predefined function signatures, sequences of checks or similar. Keep the existing check calls in their original positions.

Feel free to add assertions within the TODO blocks where necessary. Please note that assertions will stop your program if a check fails, which can help you find an incorrect state before it causes further errors.

Game Structure

The game has two participants:

  • Player: Reads commands from standard input, sends them to the Board, waits for a response, and displays the response and current game state.
  • Board: Receives commands, updates the game, and returns the appropriate response from the supplied messages array.

The board has 3 rows and 4 columns, containing six pairs. Hidden fields are stored as *, and solved fields as .. The provided output displays them as [] and ...

The processes communicate through four shared objects: shmrequest, shmresponse, shmgamestate and shmlocks. Use the names SHM_NAME_REQUEST, SHM_NAME_RESPONSE, SHM_NAME_GAME_STATE and SHM_NAME_LOCKS, and the supplied fds, mmaps and process_id variables.

Your Tasks (in no particular order)

  • Set up shared synchronization primitives
    • Add the necessary mutexes, semaphores and/or condition variables to shmlocks in util.h.
    • Initialize them in initLocks() in Player.c, before the Board is started. Make sure they can be used between processes.
  • Set up shared memory in Player.c and Board.c
    • Open and size the shared objects in initSharedMemoriesPlayer() and initSharedMemoriesBoard(). Use the supplied names and MODERW, and give each process only the access it needs.
    • Map the shared objects in initMmapingsPlayer() and initMmapingsBoard(). These functions should only perform the mappings.
  • Spawn the Board process in initProcess()
    • Start the provided Board executable and store its process ID in process_id.
  • Implement communication and synchronization
    • Complete the loops in startPlayer() and startBoard(). Use getCommand() to read commands.
    • Ensure that a request is ready before the Board handles it, and that the corresponding response and game state are ready before the Player reads them.
    • Handle exit game in the Board as well as the Player, and handle end-of-file without leaving the Board waiting indefinitely.
  • Implement the command handler
    • Complete cmdHandler() using the provided command checks and board helpers. Return the appropriate predefined response for each outcome.
    • Keep the shared game_active flag and board contents consistent with the commands.
  • Implement clean up
    • Complete closeMmapingsPlayer() and closeMmapingsBoard(). Ensure the Board has terminated, release mappings and file descriptors, and remove shared objects and synchronization resources when they are no longer in use.

Communication Protocol Reference

This section lists the commands accepted by the game. The command names and newline-terminated strings are defined in util.h; the command checks, board helpers and response strings are provided in Board.c.

Starting a Game

start game prepares and shuffles a new board, hides all fields, and activates the game.

Player -> Board: start game
Board -> Player: I prepared a new game for you, reveal your first field!

Revealing and Checking Fields

reveal N reveals a hidden field with an index from 1 to 12. check checks the revealed fields: a matching pair is marked as solved, while a non-matching pair is hidden again. Check how many fields are revealed before calling foundPair(); that helper alone does not enforce the game rules. Detect when all pairs have been solved and return the winning response. Handle commands before a game starts, fields that cannot be revealed, checks with no revealed fields, illegal moves and unknown commands using the supplied responses.

Player -> Board: reveal 1
Board -> Player: Reveal a second field or check the revealed fields.
Player -> Board: reveal 2
Player -> Board: check
Board -> Player: You found a pair 🙂  /  Thats not a pair 🙁

The Player waits for a response after each command; the example shows the two possible pair-check outcomes.

Ending a Game

exit game ends the interaction. The Board must handle this request before the processes clean up.

Player -> Board: exit game
Board -> Player: Bye!

Some further hints

What to do before you start?

  • Pull from upstream!
  • Try to understand the program structure.
  • Carefully read the man pages and/or the POSIX standard on the needed functions.
  • Only begin, if you understand the basic concept of processes, virtual memory, shared resources as well as mapping them. Brute forcing will lead to a severe amount of wasted time.
  • Keep Player.h, Board.h and the Makefile unchanged. Implement the marked TODO blocks in Player.c, Board.c and util.h.
  • Follow the comments on permitted extensions in util.h. You may extend the checks and local testing output in util.c, but do not move the existing check calls in the Player and Board routines.
  • If you add global variables, do not use the same names in Player and Board.
  • Do not push binary files or any other junk files.
  • Carefully read the TODOs and header doc-strings. Some contain crucial information!

Build and run your game with the provided Makefile on your local machine with make all (compiles Player and Board) and make run (starts Player, which must start Board). Solely relying on the test system will not get you far.

Test different command sequences, including repeated games, matching and non-matching pairs, invalid commands, exit and end-of-file. Check that both processes terminate and that no shared memory objects remain after normal cleanup.

What happens to shared resources when a process exits?

A process exiting is not a substitute for orderly shutdown. Make sure neither process is still using a shared resource when it is destroyed, wait for the Board, and release all mappings, descriptors and shared objects.

Submission

Modify the files in your git repository. You can find this assignment’s files in the A4 directory.

Tag the submission with A4 and push it to the server. You may remove and re-push the A4 tag at any time throughout the semester.

Support

If you have any questions regarding this assignment, go to Discord and read through the SLP channels. The probability that your question was already answered or some discussions will lead you in the right direction is quite high. If not so, just create a new thread with the A4 flair applied.