|
1. September 18 |
|
3. Explain what must be done to convert an OBJECT file into an EXECUTABLE file (begin by defining these two terms) 4. Explain what a stack frame is, how it is created and how it operates. |
|
"He who asks is a fool for five minutes; he who does not ask remains a fool forever." - Anonymous Chinese Proverb
Due
date Wednesday September 18, 2002 10:00
|
|
I have scheduled about 2 days per chapter or one week each. When you miss a day you are responsible for picking up on your own what was talked about in class. There is a homework assignment for each class period so you should always be doing something to get ready for class. You will need your Java book and you might refresh yourself by reading through Appendix A. We will generally be modifying programs that the author supplies and using the language constructs that he has introduced, such as the Thread class. However, he does not include Threads in the appendix, but this should not be your first encounter with the class. Email me or use the discussion group to get Java questions resolved.
Assignment
Due date Monday September 23, 2002 10:00 1. Add a timer to the programs so that each will stop after 30 seconds. Note that the Server does nothing but start the Consumer and Producer threads when it is created. You will need to invent a way to stop these threads. They each run infinite loops, so you can initiate a timer to end the threads. However, what happens then? 2. When the Consumer and Producer objects exit, let each print how much was consumed (produced) and how many times there was nothing to consume
|
|
This is a short chapter that provides some details to the introduction of threads in chapter 4. The author's slides inserted the Solaris discussion (5.5) into chapter 4 by mistake. The only new materials is in 5.6 where the details of Java threads and operations on threads are discussed. Your last JAVA exercise sought to implement a way to break out of the infinite while loops that both the Consumer and Producer objects enter when their threads start. Let's consider the possible approaches to this problem:
Revised
due date because you are behind. Your main routine will start by loading 6 into register 0 and then it will make a call to subroutine fib copying the contents of register 0 to the stack as a parameter, and fib will leave its value on the stack in place of the parameter when it returns. The logic of fib will be to test to see if the parameter is 1 or 2, and if so, to return 1 in the parameter location. If not, fib must make two calls to fib and add the two results. Therefore it needs to push two variables on the stack, n-1 and n-2, and jsr to fib. Upon return the contents of its two stack locations must be exchanged and another call to fib made. Upon return the two stack locations must be added and the sum placed in the original parameter location before returning. Upon return to main the parameter must be retrieved and left in register 0 (where the original 6 has long since been overwritten). |
|
excerpt from Inside the
Java Virtual Machine Figure 5-1 shows a block
diagram of the Java virtual machine that includes the major subsystems and
memory areas described in the specification. As mentioned in previous
chapters, each Java virtual machine has a class loader subsystem: a mechanism
for loading types (classes and interfaces) given fully qualified names. Each
Java virtual machine also has an execution engine: a mechanism responsible
for executing the instructions contained in the methods of loaded classes. Although the same runtime data areas exist in some form in every Java virtual machine implementation, their specification is quite abstract. Many decisions about the structural details of the runtime data areas are left to the designers of individual implementations. Different implementations of the virtual machine can have very different memory constraints. Some implementations may have a lot of memory in which to work, others may have very little. Some implementations may be able to take advantage of virtual memory, others may not. The abstract nature of the specification of the runtime data areas helps make it easier to implement the Java virtual machine on a wide variety of computers and devices. Some runtime data areas are
shared among all of an application's threads and others are unique to
individual threads. Each instance of the Java virtual machine has one method
area and one heap. These areas are shared by all threads running inside the
virtual machine. When the virtual machine loads a class file, it parses
information about a type from the binary data contained in the class file. It
places this type information into the method area. As the program runs, the
virtual machine places all objects the program instantiates onto the heap.
See Figure 5-2 for a graphical depiction of these memory areas. As each new thread comes into existence, it gets its own pc register (program counter) and Java stack. If the thread is executing a Java method (not a native method), the value of the pc register indicates the next instruction to execute. A thread's Java stack stores the state of Java (not native) method invocations for the thread. The state of a Java method invocation includes its local variables, the parameters with which it was invoked, its return value (if any), and intermediate calculations. The state of native method invocations is stored in an implementation-dependent way in native method stacks, as well as possibly in registers or other implementation-dependent memory areas. The Java stack is composed of stack frames (or frames). A stack frame contains the state of one Java method invocation. When a thread invokes a method, the Java virtual machine pushes a new frame onto that thread's Java stack. When the method completes, the virtual machine pops and discards the frame for that method. The Java virtual machine has no registers to hold intermediate data values. The instruction set uses the Java stack for storage of intermediate data values. This approach was taken by Java's designers to keep the Java virtual machine's instruction set compact and to facilitate implementation on architectures with few or irregular general purpose registers. In addition, the stack-based architecture of the Java virtual machine's instruction set facilitates the code optimization work done by just-in-time and dynamic compilers that operate at run-time in some virtual machine implementations. See Figure 5-3 for a graphical
depiction of the memory areas the Java virtual machine creates for each
thread. These areas are private to the owning thread. No thread can access
the pc register or Java stack of another thread. Figure 5-3 shows a snapshot of a virtual machine instance in which three threads are executing. At the instant of the snapshot, threads one and two are executing Java methods. Thread three is executing a native method. In Figure 5-3, as in all graphical depictions of the Java stack in this book, the stacks are shown growing downwards. The "top" of each stack is shown at the bottom of the figure. Stack frames for currently executing methods are shown in a lighter shade. For threads that are currently executing a Java method, the pc register indicates the next instruction to execute. In Figure 5-3, such pc registers (the ones for threads one and two) are shown in a lighter shade. Because thread three is currently executing a native method, the contents of its pc register--the one shown in dark gray--is undefined. Exercise 5.9 on p. 132 asks
that you revise the MessageQueue class on page 108. One way to do this is to add methods sendPermission(Producer) and receivePermission(Consumer)to the MessageQueue class. If the mailbox is full, the SP method places the Producer reference in a Vector and suspends the producer thread. Similarly for RP. The receive method is then ammended to resume one suspend consumer. The receive method is also ammended to resume one suspended consumer. The new methods have signature
public void sendPermission(Thread producer) etc. and the call is made
immediately before the send: mbox.sendPermission(this); Deposit your consumer, producer and messagequeue source files in the drop box after testing to see that they work with the Server class. Also deposit a file of your run output and an analysis of what you see there (how well does the program work?). |
|
|
|
We got into 6.5 on Real-Time Scheduling last time. Hard real-time systems cannot share resources or depend upon secondary storage access, so such systems are designed to be dedicated (which is why there are so many different computers in automobiles). We will pick up with soft real-time OS considerations and then look at Thread scheduling, particulary in Java. section 6.8 concerns how to measure and predict how effective a scheduling policy (SJF, FCFS, RR have been discussed) will be given some assumed job characteristics. The author discusses
The homework due today involves experimenting with the author's scheduler class: The author provides the code for his round-robin scheduler. You run this scheduler by running TestScheduler. Think about what happens when you do this:
Do the above experiments and answer the questions posed. |
|
" Any sufficiently advanced technology is indistinguishable from magic." - A. Clarke Chapter 7 is long and sophisticated. We are learning to deal with concurrency and to understand the intricacies of sharing. Unfortunately, there is no indication that the class has grasped scheduling since homework has not been turned in. The author illustrates what your programming exercises were intended to reveal (in bounded buffer problems) that when you do not control when code can be interrupted, you can experience problems with shared data. We want to enforce mutual exclusion to solve these problems, but our efforts are hampered by not being able to control when our enforcement will be interrupted, allowing deadlock. The solution is to insure that some operations are NEVER interrupted. We can do this with hardware (special instructions or disabling interrupts). This chapter presents three classic synchronization problems that make it easier to see the difficulties of enforcing mutual exclusion without encountering deadlock or starvation: Bounded Buffer (what do you do when the buffer is full?), the Reader/Writer problem (how do you prevent Writers from changing data in the middle of a read or writers from overwriting each other?) and the Dining Philosopher problem (how do you avoid deadlock when multiple resources are being acquired in some order?). In trying to solve these problems we illustrate critical sections, locking, semaphores, and monitors. The homework due today was question answers from chapter 6
|
|
"One can think effectively only when one is willing to endure suspense and to undergo the trouble of searching." - J. Dewey Semaphores must be supported in hardware because they must complete an operation on a data item without interruption. One operation is to test and wait if not positive, then decrement, the other is to increment.
|
|
Dr. Dijkstra, the inventor of semaphores, died last month. Today we survey how Java implements cooperating processes by looking at thread synchronization. |
|
At this point you should be able to explain the following concepts:
As a consequence of your completing the homework exercises you should be able to trace and comment a JAS assembly program or a Java program dealing with buffer/message passing and thread scheduling. Expect to define several terms (any bolded words in the text). About 25% of the exam will be objective, the rest short answer.
|
|
|
|
|
|
|
|
|