A Solution: Consider the UNIX read() operation.
The nonblocking read() would take one extra parameter, a nonblocking semaphore used to signal the completion of the read operation. The thread level primitive would then be:
THread( d, buf, len ) is sem: THsem, initially blocked; begin NBread( sem, d, buf, len ) while not NBP(sem) THrelinquish end while end
The Problem: Why, in a multiprocessor system with user-level threads, processes and shared memory, it is common to find each mutual exclusion and synchronization mechanism offered in three forms, one that uses busy waiting, one that is implemented by the thread package, and one that involves a kernel call.
The Answer: Busy-waiting mutual exclusion provides very low overhead blocking, typically without even the overhead of a procedure call, for internal conditions detected within a single multithreaded shared-memory application. This is typically most appropriate for very short very-frequent critical sections.
Thread-level mutual exclusion is typically used for longer critical sections where hanging one of the processors for the duration of the wait for critical section entry is inappropriate. As with busy-waiting, it is limited to waits that relate only to one multithreaded shared memory application, but it allows other threads to run while one thread is blocked.
Process-level blocking on kernel implemented semaphores has the highest overhead of the three alternatives, but it is the only form that allows a process to wait for an external condition, outside the multithreaded shared memory application.
Problem, part A: Given a fixed application mix, which of these places the greatest demands on the bandwidth of the network.
Solution: Classifying all machines as a single shared pool has the potential to maximize the communications loading.
Problem, part B: What load balancing problems does each of these alternatives pose?
Solution: The single computational resource model, typically of fully distributed operating systems, poses the greatest opportunities for load balancing. Processes and files can all be moved in order to minimize computational imbalance while minimizing network imbalance. If each machine is a dedicated personal workstation, there is almost no opportunity for load balancing. Specialized machines simplify the load balancing problem -- the file servers can trade files in order to balance file loadings, and the compute servers can trade processes in order to balance process loadings, but each problem is simplified by the fact that the problems are essentially disconnected from each other.