Vous êtes sur la page 1sur 19

MODULE-5

ADVANCES IN LANGUAGE DESIGN Advances in Language design - Variations of subprogram control, Parallel programming, Introduction to exception handling - Exception handling in JAVA, Hardware developments, software architecture SUBPROGRAM CONTROL Subprogram control: interaction among subprograms and how subprograms manage to pass data among themselves in a structured and efficient manner. Terminology: Function call subprograms that return values directly Subroutine call subprograms that operate only through side effects on shared data. A. SUBPROGRAM SEQUENCE CONTROL Simple subprogram call return Copy rule view of subprograms: the effect of a call statement is the same as if the subprogram were copied and inserted into the main program. Implicit assumptions present in this view : o Subprograms cannot be recursive o Explicit call statements are required o Subprograms must execute completely at each call o Immediate transfer of control at point of call o Single execution sequence Simple call-return subprograms Execution of subprograms Outline of the method: 1. Subprogram definition and subprogram activation. The definition is translated into a template, used to create an activation each time a subprogram is called. 2. Subprogram activation: consists of a code segment (the invariant part) - executable code and constants an activation record (the dynamic part) - local data, parameters created anew each time the subprogram is called, destroyed when the subprogram returns. Execution is implemented by the use of two system-defined pointers: Current-instruction pointer CIP-address of the next statement to be executed Current-environment pointer CEP- pointer to the activation record. On call instruction: c. An activation record is created. d. Current CIP and CEP are saved in the created activation record as return point e. CEP is assigned the address of the activation record. f. CIP gets the address of the first instruction in the code segment
40

g. The execution continues from the address in CIP On return h. The old values of CIP and CEP are retrieved . i. The execution continues from the address in CIP Restrictions of the model: at most one activation of any subprogram The simplest implementation: to allocate storage for each activation as an extension of the code segment. Used in FORTRAN and COBOL. The activation record is not destroyed - only reinitialized for each subprogram execution. Hardware support - CIP is the program counter, CEP is not used, simple jump executed on return. Stack-based implementation - the simplest run-time storage management technique call statements : push CIP and CEP return statements : pop CIP and CEP off of the stack. Used in most C implementations LISP: uses the stack as an environment. RECURSIVE SUBPROGRAMS Specification Syntactically - no difference Semantically - multiple activations of the same subprogram exist simultaneously at some point in the execution. Implementation Stack-based - CIP and CEP are stored in stack, forming a dynamic chain of links. A new activation record is created for each call and destroyed at return. The lifetimes of the activation records cannot overlap - they are nested. Some language compilers (C, Pascal) always assume recursive structure of subprograms, while in others non-recursive subprograms are implemented in the simple way. VARIATIONS OF SUBPROGRAM CONTROL The simple call-return subprogram activation was based on several assumptions: 1. No recursive subprograms 2. Explicit call statements 3. Subprograms must execute completely at each call 4. Control must be transferred immediately at the point of call 5. There must be a single execution sequence Changing these assumptions will result in different processing models. Here we shall discuss assumptions 2 through 5. Assumption Removing the assumption results in Explicit call statements Exception handlers Subprograms must execute completely at each call Co-routines Control must be transferred immediately at the point of call Scheduled subprograms There must be a single execution sequence

41

1. Exceptions and exception handlers Exception Handlers are subprograms used to handle some special situations, called exceptions. They are not invoked by explicit calls. Instead they are invoked when a particular condition or event occurs, e.g. Error conditions Unpredictable conditions Tracing and monitoring Exception handlers typically contain only: o A set of declarations of local variables and o A sequence of executable statements Exception Handlers can be o predefined in the language o programmer defined Raising and catching an exception Languages provide methods for raising (throwing) and testing for exceptions. Example: try { statement1; statement2; if badCondition throw ExceptionName; } catch ExceptionName { .// do something for exception.} Here try, throw and catch are keywords, different language may have different keywords. Implementation e. Operating system exceptions - raised directly by hardware interrupts. f. Programmer defined - the translator inserts code to handle the exceptions. co-routines Co-routines: subprograms that can return control to the caller before completion of execution. Implementation: similar to the simple call-return structure, the difference is in handling the CIP. Each co-routine has IP location in its activation record, used to provide the value for CIP on resuming the execution. scheduled subprograms Subprogram scheduling results from relaxation of the assumption that execution of a subprogram should always be initiated immediately on its call. Subprograms scheduling techniques: o Execution after other subprograms call B after A o Execution when a Boolean expression becomes true call B when X=5 o Execution on the basis of a simulated time scale call B when time=25 o Execution based on priority call B with priority 7 Implementation: Scheduling is a run-time activity. The process is controlled (usually) by a system-defined scheduler program that maintains a list of currently scheduled subprogram activations.

42

PARALLEL PROGRAMMING Parallel processing: the execution of more than one program/subprogram simultaneously. A subprogram that can execute concurrently with other subprograms is called a task or a process. Two basic ways to achieve parallel processing: a. hardware supported: a multiprocessor system a distributed (parallel) computer system b. software simulated separate tasks run concurrently on the virtual computer, one task at a time on the actual computer - time sharing. 1. PRINCIPLES OF PARALLEL PROGRAMMING LANGUAGES Issues to be addressed: o Variable definitions mutable : values may be assigned to the variables and changed during program execution (as in sequential languages). definitional: variable may be assigned a value only once. o Parallel composition: A parallel statement, which causes additional threads of control to begin executing. o Execution models (Program structure) Transformational: transforms the input data into an appropriate output value. E.G. parallel matrix multiplication Reactive: the program reacts to external stimuli called events. E.G. real-time control systems. Non-determinism - the behavior depends on the occurring events. o Communication shared memory with common data objects accessed by each parallel program; messages. o Synchronization. Parallel programs must be able to coordinate the execution of various threads of control. 2. CONCURRENT EXECUTION a. Programming constructs using parallel execution primitives of the operating system (C can invoke the fork operation of Unix ) Using parallel constructs. A programming language parallel construct indicates parallel execution Example: AND statement (programming language level) Syntax: statement1 and statement2 and statementN Semantics: All statements execute in parallel. call ReadProcess and call Write process and call ExecuteUserProgram ; No assumption is made on the order of execution, i.e. the tasks can be executed in a while loop b. Guarded commands Guard: a condition that can be true or false. Guards are associated with statements. A statement is executed when its guard becomes true. Non-determinism of execution - the guards acquire their truth value in run-time.

43

Guarded if: if B1 S1 | B2 S2 | Bn Sn fi If some guards Bi are true one of the corresponding statements is executed. Guarded repetition statement do B1 S1 | B2 S2 | Bn Sn od If some guards Bi are true one of the corresponding statements is executed. The process repeats while there are true guards. c. Tasks Tasks are subprograms that run in parallel with the program that has initiated them. They are dependents on the initiating program. The initiating program cannot terminate until all of its dependents terminate. A task may have multiple simultaneous activations. Task activation Explicit call statements Implicitly, based on their declaration. Types of interaction (with respect to the degree of awareness of the existence of other tasks/processes) Tasks unaware of each other Independent tasks that are not intended to work together. Tasks indirectly aware of each other Tasks share access to some object, such as an I/O buffer, but are not necessarily aware of each other by their respective IDs. Tasks directly aware of each other Tasks that are designed to work jointly on some activity and are able to communicate with each other. The communication provides a way to synchronize, or coordinate, the various activities. Typically, communication can be characterized as consisting of messages of some sort. Control Problems Mutual exclusion Two tasks require access to a single non-shareable resource. Critical resource - the resource in question. Critical section in the program - the portion in the program that uses the resource The rule: only one program at a time can be allowed in its critical section Deadlock Involves at least two processes P1 waits for an event to be produced by P2 P2 waits for an event to be produced by P1 Starvation Involves at least three processes P1, P2, P3 competing for non-shareable resource. P1 and P2 alternatively use the resource, P3 may indefinitely be denied access to that resource. Synchronization of Tasks If several tasks work on one problem and share a resource, they may need to be synchronized at certain points of their execution. Techniques for synchronization: Interrupts - provided by the operating system. Semaphores - shared data objects, with two primitive operations - signal and wait. Messages - information is sent from one task to another. The sending task may continue to execute.

44

Guarded commands - force synchronization by insuring conditions are met before the tasks are executed. Rendezvous - similar to messages, the sending task waits for an answer. Example: Semaphores The setting: Special variable called a semaphore is used for signaling If a process is waiting for a signal, it is suspended until that signal is sent Wait and signal operations cannot be interrupted Queue is used to hold processes waiting on the semaphore Semaphore is a variable that has an integer value May be initialized to a nonnegative number Wait operation decrements the semaphore value Signal operation increments semaphore value Mutual exclusion with semaphores Each task performs: wait(s); /* critical section */ signal(s); The produces/consumer problem One or more producers are generating data and placing these in a buffer A single consumer is taking items out of the buffer one at time Only one producer or consumer may access the buffer at any one time Solution : s - semaphore for entering the critical section delay - semaphore to ensure reading from nonempty buffer Producer: Consumer: produce(); wait(delay); wait (s); wait(s); append(); take(); signal(delay); signal(s); signal(s); consume(); 3. Persistent systems Traditional software: Data stored outside of program - persistent data Data processed in main memory - transient data Processing model: Read data from file Process data Store results on file Consider an application system where several programs running in parallel use and update a large database, e.g. ticket reservation system. The traditional processing model is inefficient. Solution1: keep the database in main memory as a shared data object. Drawbacks: in case of system failure all data will be lost. Solution2: keep the database in main memory as a shared data object and maintain its image on a file system - recording each change at the time it occurs Languages that do not make distinction between persistent and transient data, and automatically reflect changes in the database, are called persistent languages Design issues: 0. A mechanism to indicate an object is persistent
45

Approach: assume all data are transient and indicate which objects are persistent 1. A mechanism to address a persistent object The language can develop its own model of persistent storage 2. Simultaneous access to an individual persistent object Use of semaphores 3. Check type compatibility of persistent objects Because of the multiple programs that access persistent data, name equivalence is difficult to use, structural equivalence is the preferred method in persistent languages. 4. Client-server computing 4.1. Network models o Centralized, where a single processor does the scheduling and informs the other machines as to the tasks to execute. When completed, the assigned processor will indicate that it is ready to do another task o Distributed or peer-to-peer, where each machine is an equal and the process of scheduling is spread among all of the machines. - One processor broadcasts a message to all the processors, and an inactive processor could respond with the message "I'll do it." - Alternatively, each machine in the network will individually invoke a task on a specified machine elsewhere in the network. In this way, work gradually gets propagated around the network. 4.2. Client-server mediator architecture Client machine: o Interacts with user o Has protocol to communicate with server Server: o Decides where data is located o Accesses data o Mediator is software that uses encoded knowledge about sets of data to create information for a higher class of application. o Issues: May be communicating with multiple clients simultaneously Need to keep each such transaction separate Multiple local address spaces in server EXCEPTIONS AND EXCEPTION HANDLERS Exception Handlers are subprograms used to handle some special situations, called exceptions. They are not invoked by explicit calls. Instead they are invoked when a particular condition or event occurs, e.g. Error conditions Unpredictable conditions Tracing and monitoring Exception handlers typically contain only: A set of declarations of local variables and
46

A sequence of executable statements Exception Handlers can be predefined in the language programmer defined

Raising and catching an exception Languages provide methods for raising (throwing) and testing for exceptions. Example: try { statement1; statement2; if badCondition throw ExceptionName; } catch ExceptionName { .// do something for exception.} Here try, throw and catch are keywords, different language may have different keywords. Implementation a. Operating system exceptions - raised directly by hardware interrupts. b. Programmer defined - the translator inserts code to handle the exceptions. CO-ROUTINES Co-routines: subprograms that can return control to the caller before completion of execution.

47

Implementation: similar to the simple call-return structure, the difference is in handling the CIP. Each co-routine has IP location in its activation record, used to provide the value for CIP on resuming the execution. SCHEDULED SUBPROGRAMS Subprogram scheduling results from relaxation of the assumption that execution of a subprogram should always be initiated immediately on its call. Subprograms scheduling techniques:
o o o o

Execution after other subprograms call B after A Execution when a Boolean expression becomes true call B when X=5 Execution on the basis of a simulated time scale call B when time=25 Execution based on priority call B with priority 7

Implementation: Scheduling is a run-time activity. The process is controlled (usually) by a system-defined scheduler program that maintains a list of currently scheduled subprogram activations. A parallel programming model is a concept that enables the expression of parallel programs which can be compiled and executed. The value of a programming model is usually judged on its generality: how well a range of different problems can be expressed and how well they execute on a range of different architectures. The implementation of a programming model can take several forms such as libraries invoked from traditional sequential languages, language extensions, or complete new execution models.
48

Consensus on a particular programming model is important as it enables software expressed within it to be transportable between different architectures. The von Neumann model has facilitated this with sequential architectures as it provides an efficient bridge between hardware and software, meaning that high-level languages can be efficiently compiled to it and it can be efficiently implemented in hardware. JAVA - EXCEPTIONS HANDLING AN EXCEPTION IS A PROBLEM that arises during the execution of a program. An exception can occur for many different reasons, including the following:

A user has entered invalid data. A file that needs to be opened cannot be found. A network connection has been lost in the middle of communications, or the JVM has run out of memory.

Some of these exceptions are caused by user error, others by programmer error, and others by physical resources that have failed in some manner. To understand how exception handling works in Java, you need to understand the three categories of exceptions:

Checked exceptions: A checked exception is an exception that is typically a user error or a problem that cannot be foreseen by the programmer. For example, if a file is to be opened, but the file cannot be found, an exception occurs. These exceptions cannot simply be ignored at the time of compilation. Runtime exceptions: A runtime exception is an exception that occurs that probably could have been avoided by the programmer. As opposed to checked exceptions, runtime exceptions are ignored at the time of compliation. Errors: These are not exceptions at all, but problems that arise beyond the control of the user or the programmer. Errors are typically ignored in your code because you can rarely do anything about an error. For example, if a stack overflow occurs, an error will arise. They are also ignored at the time of compilation.

Exception Hierarchy: All exception classes are subtypes of the java.lang.Exception class. The exception class is a subclass of the Throwable class. Other than the exception class there is another subclass called Error which is derived from the Throwable class. Errors are not normally trapped form the Java programs. These conditions normally happen in case of severe failures, which are not handled by the java programs. Errors are generated to indicate errors generated by the runtime environment. Example : JVM is out of Memory. Normally programs cannot recover from errors.
49

The Exception class has two main subclasses : IOException class and RuntimeException Class.

Here is a list of most common checked and unchecked Java's Built-in Exceptions. Exceptions Methods: Following is the list of important medthods available in the Throwable class. SN Methods with Description public String getMessage() Returns a detailed message about the exception that has occurred. This message is initialized in the Throwable constructor. public Throwable getCause() Returns the cause of the exception as represented by a Throwable object. public String toString() Returns the name of the class concatenated with the result of getMessage() public void printStackTrace() Prints the result of toString() along with the stack trace to System.err, the error output stream.

50

public StackTraceElement [] getStackTrace() Returns an array containing each element on the stack trace. The element at index 0 represents the top of the call stack, and the last element in the array represents the method at the bottom of the call stack. public Throwable fillInStackTrace() Fills the stack trace of this Throwable object with the current stack trace, adding to any previous information in the stack trace.

Catching Exceptions: A method catches an exception using a combination of the try and catch keywords. A try/catch block is placed around the code that might generate an exception. Code within a try/catch block is referred to as protected code, and the syntax for using try/catch looks like the following: try { //Protected code }catch(ExceptionName e1) { //Catch block } A catch statement involves declaring the type of exception you are trying to catch. If an exception occurs in protected code, the catch block (or blocks) that follows the try is checked. If the type of exception that occurred is listed in a catch block, the exception is passed to the catch block much as an argument is passed into a method parameter. Example: The following is an array is declared with 2 elements. Then the code tries to access the 3rd element of the array which throws an exception. // File Name : ExcepTest.java import java.io.*; public class ExcepTest{ public static void main(String args[]){ try{ int a[] = new int[2];

51

System.out.println("Access element three :" + a[3]); }catch(ArrayIndexOutOfBoundsException e){ System.out.println("Exception thrown :" + e); } System.out.println("Out of the block"); } } This would produce following result: Exception thrown :java.lang.ArrayIndexOutOfBoundsException: 3 Out of the block

Multiple catch Blocks: A try block can be followed by multiple catch blocks. The syntax for multiple catch blocks looks like the following: try { //Protected code }catch(ExceptionType1 e1) { //Catch block }catch(ExceptionType2 e2) { //Catch block }catch(ExceptionType3 e3) { //Catch block } The previous statements demonstrate three catch blocks, but you can have any number of them after a single try. If an exception occurs in the protected code, the exception is thrown to the first catch block in the list. If the data type of the exception thrown matches ExceptionType1, it gets caught there. If not, the exception passes down to the second catch statement. This continues until the exception either is caught or falls through all catches, in which case the current method stops execution and the exception is thrown down to the previous method on the call stack. Example: Here is code segment showing how to use multiple try/catch statements.
52

try { file = new FileInputStream(fileName); x = (byte) file.read(); }catch(IOException i) { i.printStackTrace(); return -1; }catch(FileNotFoundException f) //Not valid! { f.printStackTrace(); return -1; }

The throws/throw Keywords: If a method does not handle a checked exception, the method must declare it using the throws keyword. The throws keyword appears at the end of a method's signature. You can throw an exception, either a newly instantiated one or an exception that you just caught, by using the throw keyword. Try to understand the different in throws and throw keywords. The following method declares that it throws a RemoteException: import java.io.*; public class className { public void deposit(double amount) throws RemoteException { // Method implementation throw new RemoteException(); } //Remainder of class definition } Amethod can declare that it throws more than one exception, in which case the exceptions are declared in a list separated by commas. For example, the following method declares that it throws a RemoteException and an InsufficientFundsException: import java.io.*; public class className

53

{ public void withdraw(double amount) throws RemoteException, InsufficientFundsException { // Method implementation } //Remainder of class definition }

The finally Keyword The finally keyword is used to create a block of code that follows a try block. A finally block of code always executes, whether or not an exception has occurred. Using a finally block allows you to run any cleanup-type statements that you want to execute, no matter what happens in the protected code. A finally block appears at the end of the catch blocks and has the following syntax: try { //Protected code }catch(ExceptionType1 e1) { //Catch block }catch(ExceptionType2 e2) { //Catch block }catch(ExceptionType3 e3) { //Catch block }finally { //The finally block always executes. } Example: public class ExcepTest{ public static void main(String args[]){ int a[] = new int[2];

54

try{ System.out.println("Access element three :" + a[3]); }catch(ArrayIndexOutOfBoundsException e){ System.out.println("Exception thrown :" + e); } finally{ a[0] = 6; System.out.println("First element value: " +a[0]); System.out.println("The finally statement is executed"); } } } This would produce following result: Exception thrown :java.lang.ArrayIndexOutOfBoundsException: 3 First element value: 6 The finally statement is executed Note the followings:

A catch clause cannot exist without a try statement. It is not compulsory to have finally clauses when ever a try/catch block is present. The try block cannot be present without either catch clause or finally clause. Any code cannot be present in between the try, catch, finally blocks.

Declaring you own Exception: You can create your own exceptions in Java. Keep the following points in mind when writing your own exception classes:

All exceptions must be a child of Throwable. If you want to write a checked exception that is automatically enforced by the Handle or Declare Rule, you need to extend the Exception class. If you want to write a runtime exception, you need to extend the RuntimeException class.

We can define our own Exception class as below: class MyException extends Exception{ }

55

You just need to extend the Exception class to create your own Exception class. These are considered to be checked exceptions. The following InsufficientFundsException class is a userdefined exception that extends the Exception class, making it a checked exception. An exception class is like any other class, containing useful fields and methods. Example: // File Name InsufficientFundsException.java import java.io.*; public class InsufficientFundsException extends Exception { private double amount; public InsufficientFundsException(double amount) { this.amount = amount; } public double getAmount() { return amount; } } To demonstrate using our user-defined exception, the following CheckingAccount class contains a withdraw() method that throws an InsufficientFundsException. // File Name CheckingAccount.java import java.io.*; public class CheckingAccount { private double balance; private int number; public CheckingAccount(int number) { this.number = number; } public void deposit(double amount) { balance += amount; } public void withdraw(double amount) throws InsufficientFundsException {

56

if(amount <= balance) { balance -= amount; } else { double needs = amount - balance; throw new InsufficientFundsException(needs); } } public double getBalance() { return balance; } public int getNumber() { return number; } } The following BankDemo program demonstrates invoking the deposit() and withdraw() methods of CheckingAccount. // File Name BankDemo.java public class BankDemo { public static void main(String [] args) { CheckingAccount c = new CheckingAccount(101); System.out.println("Depositing $500..."); c.deposit(500.00); try { System.out.println("\nWithdrawing $100..."); c.withdraw(100.00); System.out.println("\nWithdrawing $600..."); c.withdraw(600.00); }catch(InsufficientFundsException e) { System.out.println("Sorry, but you are short $" + e.getAmount()); e.printStackTrace(); } }

57

} Compile all the above three files and run BankDemo, this would produce following result: Depositing $500... Withdrawing $100... Withdrawing $600... Sorry, but you are short $200.0 InsufficientFundsException at CheckingAccount.withdraw(CheckingAccount.java:25) at BankDemo.main(BankDemo.java:13)

Common Exceptions: In java it is possible to define two catergories of Exceptions and Errors.

JVM Exceptions: - These are exceptions/errors that are exclusively or logically thrown by the JVM. Examples : NullPointerException, ArrayIndexOutOfBoundsException, ClassCastException, Programmatic exceptions . These exceptions are thrown explicitly by the application or the API programmers Examples: IllegalArgumentException, IllegalStateException.

58