Serverless, ReactPHP, and Expanding Frontiers, May 2019

(singke) #1
http://www.phparch.com \ May 2019 \ 37

Memory Abstractions


Internal Apparatus



  1. Make the update (deduct 100 points from Alice; add 100
    points to Bob)

  2. Release the lock (commit transaction)
    Even operating system programmers—as we are about
    to see—get this wrong. Here is the correct “critical region”
    sequence:

  3. Lock out other processes (begin transaction)

  4. Check/verify the prerequisite conditions

  5. Make the update

  6. Release the lock (commit transaction)
    So what is the possible bug? Another process, running
    simultaneously, could have changed the pool size after we
    checked the pool size and before we locked out interrupts. In
    modern terms, we’ve just hit the concept of thread safety^9.
    Do we care about thread safety with PHP? Yes, we do!
    Check the PHP downloads for Windows^10 page, for example.
    Each version contains both “Non Thread Safe” and “Thread
    Safe” versions. The Obtaining PHP^11 page has a list of exten-
    sions, noting “those marked with a * are to the best of our
    knowledge not thread safe; they are not recommended for
    use in a multi-threaded environment.”
    A multi-threaded environment is where we have several
    threads of execution, all sharing the same memory, variables,
    and data structures. It’s easy to picture several PHP requests
    all sharing the same database table, but it’s more difficult to
    picture several PHP requests sharing the same in-memory
    objects and variables.
    PHP is typically deployed (as the “LAMP” stack of Linux,
    Apache, MySQL, PHP) in an isolated-process environment.
    Each PHP request cycle is its own process. It does not share
    memory or state with any other PHP request’s processing.
    However, we now have tools such as ReactPHP which let
    us run a PHP-based server. We need to allow for sharing
    memory and other resources across individual requests.
    In our operating system example, we have several (unseen)
    operating system threads all able to interrupt each other
    between one line of code and the next. One thread needs to
    lock out all other threads while it updates the shared data
    structure.
    Let’s get back to our story. I was busily transferring into
    the software training group to teach the operating system
    internals. I sat through the whole sequence since I’d be
    teaching part of it. That’s great, but we actually had two oper-
    ating systems to learn. There was the mainframe operating
    system—a two-week class that I’d be teaching—and the I/O
    Subsystem, a mini-supercomputer in its own right, with its
    real-time operating system written in its unique assembler
    language. And another two weeks of class. It was nuts.


9 thread safety: https://en.wikipedia.org/wiki/Thread_safety
10 PHP downloads for Windows: https://windows.php.net/download


11 Obtaining PHP: https://php.net/faq.obtaining


The I/O Subsystem (IOS) processors contained only 128KB
of memory, the same as the Apple IIe and IIc personal
computers available at the time—but it was awfully fast.
The operating system, data structures, I/O buffers, channel
drivers, everything, had to share that 128KB. The IOS soft-
ware was built around two concepts: speed (a given), and
memory management.
The IOS class included a class project. We each needed
to write an “overlay” that does something, much like “hello
world.” That sounds trivial, but it isn’t. It’s something like
writing an extension to the Linux kernel. The student overlay
needs to get registered with the rest of the operating system
software. We need to then boot the multi-million-dollar
mainframe with the modified IOS software. When something
doesn’t work as expected, the instructor may or may not be
able to help.
Rebuilding the software might mean waiting until the next
day for another try, and we’re already at the last couple of class
days. Most students completed the assignment as 20-30 lines
of code: Display something on the operator console and exit.
I, on the other hand, asked around. Had anyone ever created
a game program as their assignment? Nope. It’s never been
done. With limited class time and minimal test time, there’s
a good reason that new students never made the attempt in a
new just-learned assembly language.
So I wrote an adventure game, inspired by Colossal Cave
Adventure. It’s a tour of Switzerland (above ground), with
a maze of twisty passages nearly all alike (mid-game), and
a final puzzle involving Arabic words (brutal end game).
We had just moved back to Minnesota after living in Saudi
Arabia; thus a challenge in Arabic seemed like the right thing
to do.
The program did have a problem, which I considered a
feature at the time. You could not exit the program except by
winning (completing) it. One had to solve the whole thing or
reboot the Cray mainframe. Oops! It took over the operator
console by design, blocking any other sysadmin activity from
happening on that particular console.
So what good does this bit of time travel do us today? Then,
as now, memory management is a central consideration of
running software. The details don’t matter, but the concepts
do.
With Adventure-style games, the back story is crucial. If you
lose the flyer that came with the game, the game won’t make
any sense. Now we have the back story for Swiss Adventure
(1986), an obscure game hidden inside an obscure operating
system.
Swiss Adventure will be one of our learning tools, beginning
next month. The original was constrained in that the entire
operating system ran on hardware with only 131,072 (128K)
bytes of memory, and Swiss Adventure was hidden inside that
operating system. It was an adventure in memory manage-
ment more than anything else; just what we need!
Let’s see some of these memory concepts in action.
Free download pdf