LMU ☀️ CMSI 673
CONCURRENT AND DISTRIBUTED PROGRAMMING
HOMEWORK #3 PARTIAL ANSWERS
src/notepadkiller.c
notepadkiller.c
/*****************************************************************************
*
*  notepadkiller.c
*
*  This program kills a running instance of Notepad somewhere on the same
*  system.  If no instances of Notepad are running, nothing happens.
*  Technically it just sends a WM_QUIT message to some window that happens
*  to have the class "Notepad", so the message could go to someplace other
*  than the ubiquitous Notepad application.
*
*****************************************************************************/

#include <windows.h>

int main() {
    PostMessage(FindWindow("Notepad", 0), WM_QUIT, 0, 0);
}
src/butler.cpp
butler.cpp
/*****************************************************************************
*
*  butler.cpp
*
*  An application in which the user clicks on the window area to "open a
*  door" by pulsing the event with interprocess name "FrontDoor".  This
*  program creates the event; other processes can wait on it.
*
*****************************************************************************/

#include <windows.h>

// An auto-reset, initially unsignalled, event
HANDLE frontDoor = CreateEvent(0, 0, 0, "FrontDoor");

LRESULT APIENTRY WndProc(HWND hwnd, UINT msgId, WPARAM wParam, LPARAM lParam) {
    switch (msgId) {
        case WM_LBUTTONDOWN:
            PulseEvent(frontDoor);
            return 0;
        case WM_DESTROY:
            CloseHandle(frontDoor);
            PostQuitMessage(0);
            return 0;
    }
    return DefWindowProc(hwnd, msgId, wParam, lParam);
}

int WINAPI WinMain(HINSTANCE currentInstance, HINSTANCE previousInstance,
    LPSTR commandLine, int showState) {

    char* className = "Hello";
    WNDCLASS thisClass;

    thisClass.style = CS_HREDRAW | CS_VREDRAW;
    thisClass.lpfnWndProc = WndProc;
    thisClass.cbClsExtra = 0;
    thisClass.cbWndExtra = 0;
    thisClass.hInstance = currentInstance;
    thisClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    thisClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    thisClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    thisClass.lpszMenuName = NULL;
    thisClass.lpszClassName = className;
    RegisterClass(&thisClass);

    HWND mainWindow = CreateWindow(className,
        "Click inside the window to open the door", WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
        NULL, NULL, currentInstance, NULL);
    ShowWindow(mainWindow, showState);
    UpdateWindow(mainWindow);

    MSG message;
    while (GetMessage(&message, NULL, 0, 0) > 0) {
        TranslateMessage(&message);
        DispatchMessage(&message);
    }
    return message.wParam;
}
src/guest.cpp
guest.cpp
/*****************************************************************************
*
*  guest.cpp
*
*  This is a simple console program.  It simulates a guest that wants to
*  enter a friend's house.  The friend's house is supposed to be simulated
*  in a completely different program.  This other program creates a Win API
*  event called "FrontDoor".  The program in this file waits on that event.
*  The other program will signal the event at some time; this signal will
*  relase the program here from waiting.
*
*****************************************************************************/

#include <windows.h>
#include <iostream>

int main() {
    HANDLE frontdoor = OpenEvent(EVENT_ALL_ACCESS, FALSE, "FrontDoor");

    if (!frontdoor) {
        std::cout << "I'm supposed to be a guest trying to visit a friend.\n";
        std::cout << "But the process that creates my friend and her house\n";
        std::cout << "is not running on this system.\n";
        return -1;
    }

    std::cout << "I'm waiting for the front door to be opened...\n";
    WaitForSingleObject(frontdoor, INFINITE);

    std::cout << "Yay! I got in.\n";
    CloseHandle(frontdoor);
    return 0;
}
src/edu/lmu/cs/demos/threads/MyEvent.java
 Missing content
docs/philosopher_critical_sections.txt
One could use EnterCriticalSection to pick up and LeaveCriticalSection
to put down.  The only limitation of critical sections would be that
a philosopher could not wait on both chopsticks at the same time,
but my program doesn't do that.  Mutexes can also be shared between
processes, but my program is only a single process so that doesn't
matter either.  Critical sections are way, way faster anyway.
Perhaps the only real difference is that the program might behave a
little differently in the case where a philosopher dies while holding
a chopstick, but who cares about that?
src/priority31.cpp
priority31.cpp
/*****************************************************************************
*
*  priority31.cpp
*
*  This program launches a thread at priority level 31 which does nothing
*  but busy waits for 30 seconds.
*
*****************************************************************************/

#include <windows.h>

int main() {
    SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS);
    SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
    DWORD startTime = GetTickCount();
    while (GetTickCount() < startTime + 30000)
        ;
    return 0;
}
docs/priority_31_discussion.txt
I have a two-processor Windows box at home, and running the program
seemed to have no effect on the computer's operation.  The Windows
Task Manager showed that one of the CPU was fully maxed.  When I
ran two copies of the program at the same time the UI completely
froze until one of the processes finished.  The task manager's
animation of the CPU Usage History and Page File Usage History
completely stopped as well.  This was awesome.
src/edu/lmu/cs/demos/threads/PiServer.java
 Missing content
src/edu/lmu/cs/demos/threads/PiSpigot.java
 Missing content
src/edu/lmu/cs/demos/threads/PiClient.java

I didn't write a client. You can test hit the server with telnet.