Learn about 'threads' with Super Mario Brothers



Joshua explains the concept of ' threads ' in computer programs using Super Mario Bros. , a side-scrolling action game.

What Threads Are, Part 2 - by Joshua - Pretty Good Blog
https://prettygoodblog.com/p/what-threads-are-part-2

Joshua built a multi-threaded emulation using Super Mario Bros. as a thread, with three threads running (three different Super Mario Bros.), each running as a different instance.

The emulator periodically switches between threads, which is represented as switching between game instances. To show the difference between the threads, the Super Mario Bros. game screen is color coded with different colors (purple, blue, green), so the screen color constantly changes when playing the video.

Multithreaded emulation using Super Mario Brothers as threads Part 1 - YouTube


Once the video starts playing, multi-threading kicks in. Specifically, the script creates three save states, each representing the current state of the game, then creates three threads, giving each one a save state to persist.

Next, the thread scheduler starts. The job of the thread scheduler is simply to switch threads. However, thread switching is performed according to the following conditions:

◆ Switch to a new thread every 160 frames
- The next thread should ideally be in order (1, 2, 3, 1, 2, 3...).
- However, threads that are KILLED, BLOCKED (if they cannot be unblocked), or SLEEPING (if it is not time to wake up) will be skipped.

◆Conditions for switching to a new thread
1: Update the save state of the thread with the current game state
2: Load the saved state of the new thread
3: Update the game's color palette to reflect which thread you're in

This can be seen in the first part of the video, where each thread is started at the same time (loading screen of World 1-1 ) and each thread is switched periodically as seen by the 'color change' and 'scene change'. Basically, there are three Super Mario Bros. games being played at the same time, but only one is actually active.

Joshua explained that it is now possible to physically interact with thread boundaries by setting certain areas or functions to activate synchronization primitives . Specifically, he set the following three things:

- If Mario is standing on three blocks while a thread is active, the thread will not switch to another thread until Mario leaves. (Interrupts disabled)
- Only one Mario can enter the pipe at a time. ( Mutex )
When Mario touches the goal flag, the game pauses until all other Marios touch the goal flag. ( Condition variable )

In the case of World 1-1, the red shaded area is the area where 'disable interrupts' is applied, the yellow shaded area (the pipe that you can put inside) is the area where 'mutex' is applied, and the green shaded area is the area where 'condition variable' is applied.



When Mario defeats an enemy, the thread goes into a sleep state for 300 frames. It's hard to tell from the video, but a sleeping thread doesn't necessarily wake up on time, and it has to wait until the thread scheduler decides to run it again.

According to Joshua, the emulator adds threads in the same way that threads are added to a normal CPU: by '(A) saving the current state of the machine' and '(B) making clever use of mechanisms that allow it to load it in the future if needed.' The emulator itself was not designed for threads, and the concept of threads does not exist.



Joshua's multithreaded emulation doesn't provide for the conditions under which an actual deadlock (A holds X, B holds Y, A tries to get Y while B tries to get X) could occur, but these are handled by the thread scheduler if they do occur.

If there are no threads available to run (because of a deadlock, all threads are stopped, or all threads are sleeping, etc.), the thread scheduler will halt the game and display an error message.

An example of a deadlock situation occurring would be in a mutex (where all Marios are waiting to enter a pipe) and the Mario inside the pipe dies.

Below is a video of a pseudo-deadlock. Since Mario cannot die inside the pipe, the game speeds up and the game enters a deadlock when the time runs out.

Multithreaded emulation using Super Mario Brothers as threads Part 2 - YouTube


And here's what happens when the thread scheduler runs more frequently: Note: This video may cause epileptic seizures, so watch at your own risk.

[Caution: May cause epileptic seizures] Multi-threaded emulation using Super Mario Brothers as threads Part 3 - YouTube


Here's how Joshua achieved multi-threaded emulation using Super Mario Bros. as threads:

At first, Joshua was looking for an open source NES (family computer) emulator and was planning to add multi-threading emulation elements directly to the source code. That's when he discovered the NES emulator FCEUX . By adding a few hundred lines of Lua to FCEUX, he created a legitimate thread scheduler that supports mutexes, condition variables, interrupt masks, sleep, and more.

You can check out the script that Joshua created at the following link:

pastebin.com/raw/vrDVjqHb
https://pastebin.com/raw/vrDVjqHb



Joshua wrote about his homemade multithreading emulation, 'It's not a great thread scheduler because it doesn't support thread priorities, idle tasks, semaphores , fairness algorithms, dynamic thread creation, mutex waiting list tracking, or monetization. It's horribly inefficient and very tedious, but I like it.'

in Video,   Game, Posted by logu_ii