Paper 3F6: Software Engineering and Systems Distributed Systems Design Solutions to Examples Paper 3



Similar documents
(Pessimistic) Timestamp Ordering. Rules for read and write Operations. Pessimistic Timestamp Ordering. Write Operations and Timestamps

Mutual Exclusion using Monitors

Overview Motivating Examples Interleaving Model Semantics of Correctness Testing, Debugging, and Verification

Concepts of Concurrent Computation

Monitors, Java, Threads and Processes

SOFT 437. Software Performance Analysis. Ch 5:Web Applications and Other Distributed Systems

Goals. Managing Multi-User Databases. Database Administration. DBA Tasks. (Kroenke, Chapter 9) Database Administration. Concurrency Control

An Implementation Of Multiprocessor Linux

Last Class: Semaphores


PostgreSQL Concurrency Issues

Interpreters and virtual machines. Interpreters. Interpreters. Why interpreters? Tree-based interpreters. Text-based interpreters

Transactions and Concurrency Control. Goals. Database Administration. (Manga Guide to DB, Chapter 5, pg , ) Database Administration

MPLAB Harmony System Service Libraries Help

3 - Lift with Monitors

Moving from CS 61A Scheme to CS 61B Java

Concurrency Control. Chapter 17. Comp 521 Files and Databases Fall

Outline of this lecture G52CON: Concepts of Concurrency

OPERATING SYSTEMS PROCESS SYNCHRONIZATION

Rolle s Theorem. q( x) = 1

Multiprocessor Scheduling and Scheduling in Linux Kernel 2.6

SMTP-32 Library. Simple Mail Transfer Protocol Dynamic Link Library for Microsoft Windows. Version 5.2

BSc (Hons) Business Information Systems, BSc (Hons) Computer Science with Network Security. & BSc. (Hons.) Software Engineering

Lecture 7: Concurrency control. Rasmus Pagh

CPS122 Lecture: State and Activity Diagrams in UML

Monitor Object. An Object Behavioral Pattern for Concurrent Programming. Douglas C. Schmidt

Lecture 6: Introduction to Monitors and Semaphores

Lecture 12 Doubly Linked Lists (with Recursion)

Design Patterns in C++

3F6 - Software Engineering and Design. Handout 10 Distributed Systems I With Markup. Steve Young

CORBAservices. Naming. Part of the CORBA Naming Service Interface in IDL. CORBA Naming Service

Data Management in the Cloud

Shared Address Space Computing: Programming

Lecture 10: Dynamic Memory Allocation 1: Into the jaws of malloc()

Lecture 6: Semaphores and Monitors

Jorix kernel: real-time scheduling

OMPT and OMPD: OpenMP Tools Application Programming Interfaces for Performance Analysis and Debugging

1 An application in BPC: a Web-Server

Lightweight Locking for Main Memory Database Systems

3C03 Concurrency: Condition Synchronisation

Systemnahe Programmierung KU

1.5. Factorisation. Introduction. Prerequisites. Learning Outcomes. Learning Style

Lecture 9 verifying temporal logic

Linux Driver Devices. Why, When, Which, How?

CS Fall 2008 Homework 2 Solution Due September 23, 11:59PM

Database Concurrency Control and Recovery. Simple database model

Section 3.7. Rolle s Theorem and the Mean Value Theorem. Difference Equations to Differential Equations

G(s) = Y (s)/u(s) In this representation, the output is always the Transfer function times the input. Y (s) = G(s)U(s).

Why Threads Are A Bad Idea (for most purposes)

Distributed Transactions

OMPT: OpenMP Tools Application Programming Interfaces for Performance Analysis

CHAPTER 2. Logic. 1. Logic Definitions. Notation: Variables are used to represent propositions. The most common variables used are p, q, and r.

Threads 1. When writing games you need to do more than one thing at once.

Getting Started with the Internet Communications Engine

NSPK Protocol Security Model Checking System Builder

A Survey of Parallel Processing in Linux

CS4410 Final Exam : Solution set. while(ticket[k] && (ticket[k],k) < (ticket[i],i))

Resurrecting Ada s Rendez-Vous in Java

Database Management System Prof. D. Janakiram Department of Computer Science & Engineering Indian Institute of Technology, Madras Lecture No.

Infrastructure that supports (distributed) componentbased application development

Chapter Replication in SQL Server

Operating Systems and Networks

Introduction CORBA Distributed COM. Sections 9.1 & 9.2. Corba & DCOM. John P. Daigle. Department of Computer Science Georgia State University

Textbook and References

Assignment # 2: Design Patterns and GUIs

Illustration 1: Diagram of program function and data flow

MATLAB as an Automated Execution System

CORBA Programming with TAOX11. The C++11 CORBA Implementation

PUTNAM TRAINING POLYNOMIALS. Exercises 1. Find a polynomial with integral coefficients whose zeros include

Resource Allocation and Deadlock Resource Allocation and Handling

pm4dev, 2015 management for development series Project Schedule Management PROJECT MANAGEMENT FOR DEVELOPMENT ORGANIZATIONS

Mathematics for Computer Science/Software Engineering. Notes for the course MSM1F3 Dr. R. A. Wilson

1 Posix API vs Windows API

More informed trading Exchange Traded Funds (ETFs)

language 1 (source) compiler language 2 (target) Figure 1: Compiling a program

DEVELOPING DATA PROVIDERS FOR NEEDFORTRADE STUDIO PLATFORM DATA PROVIDER TYPES

How To Understand The Theory Of Algebraic Functions

Storage Classes CS 110B - Rule Storage Classes Page 18-1 \handouts\storclas

A POSIX-Ada Interface for Application-Defined Scheduling

Storage Class Extensibility in the Brown Object Storage System

Scheduling. Anne Banks Pidduck Adapted from John Musser

Last Class: OS and Computer Architecture. Last Class: OS and Computer Architecture

Design by Contract beyond class modelling

Introduction to Python

Tasks Schedule Analysis in RTAI/Linux-GPL

Operating System Manual. Realtime Communication System for netx. Kernel API Function Reference.

Tail call elimination. Michel Schinz

SYSTEM ecos Embedded Configurable Operating System

Intrusion Detection via Static Analysis

Middleware. Peter Marwedel TU Dortmund, Informatik 12 Germany. technische universität dortmund. fakultät für informatik informatik 12

The Document Review Process: Automation of your document review and approval. A White Paper. BP Logix, Inc.

Semaphores. Otto J. Anshus University of {Tromsø, Oslo}

An Introduction To Simple Scheduling (Primarily targeted at Arduino Platform)

Output: struct treenode{ int data; struct treenode *left, *right; } struct treenode *tree_ptr;

Concurrency Control. Module 6, Lectures 1 and 2

MonitorExplorer: A State Exploration-Based Approach to Testing Java Monitors

EXTENDED FILE SYSTEM FOR FMD AND NANO-10 PLC

SAS, Excel, and the Intranet

Administration. Instruction scheduling. Modern processors. Examples. Simplified architecture model. CS 412 Introduction to Compilers

Using the VMRC Plug-In: Startup, Invoking Methods, and Shutdown on page 4

Transcription:

Engineering Tripos Part IIA THIRD YEAR Paper 3F: Software Engineering and Systems Distributed Systems Design Solutions to Examples Paper 3 CORBA 1. (a) A typical IDL file for this application is as follows: typedef long Money; // amount in pence interface StockBroker Money get_price(in string sharecode); bool buy(in string sharecode, in long numshares); bool sell(in string sharecode, in long numshares); Money get_balance(); The Money typedef defines an alias for a long, which just makes the interface definition more readable, and helps avoid confusion. Alternative solutions could define a Money structure storing pounds and pence, or use pounds as a float. buy and sell need to indicate whether or not they were successful, hence in this answer they return a bool. It would be even better to have them raise exceptions (which are available CORBA, but not covered in the context of CORBA in this course). (b) Naively, these extensions could be implemented by adding two new functions to the existing interface. However, this could break existing software that uses the old interface, so the safest way to provide the extra facilities is to create a derived interface. interface ExtendedStockBroker : StockBroker Money get_avgprice(in string sharecode, in long numdays); float get_pe_ratio(in string sharecode); (c) i. The server has to know the account balance for each customer the number of each type of share held In practice, the server should also probably know something about the identity of each customer and a password or similar to allow customers to verify their identity. 1

only one Broker_Factory in the whole system one StockBroker object per client Broker_Factory +get_broker(): StockBroker 1 << instantiate >> StockBroker +get_price(): money +buy(sharecode:string,numshares:int) +sell(sharecode:string,numshares:int) +get_balance(): money 1 Server Client * Trading_Client 1 To begin trading, a Trading_Client first asks the Broker_Factory for a StockBroker object The Broker_Factory creates a StockBroker object and passes a CORBA pointer to this object back to the Trading_Client The Trading_Client can then use this StockBroker object for trading This way, each Trading_Client has its own personal StockBroker object in the server Figure 1: (Question 1(c)) The stock broker application showing the factory ii. CORBA factories are objects which create objects of some other type. In this case, a BrokerFactory could be used to create StockBroker objects (or ExtendedStockBroker objects) for each customer. interface BrokerFactory StockBroker get_broker(in string userid); This IDL allows each user to obtain their own StockBroker from the BrokerFactory. This means that each StockBroker object can store the per customer information for the individual customer that it serves. The get_broker function is interesting because instead of returning a data value (e.g. a long), it returns a pointer to another CORBA object. The client can use this return value to access the newly created StockBroker object and call the methods provided in its interface. A UML class diagram for the system is shown in Figure 1. 2. (a) The idl file has to support downloading of four types of object. Each of the media objects are identified by a code number, stored in the associated hotpoint. interface TourismServer Model get_model(); Image get_image(in long imageno); Movie get_movie(in long movieno); 2

SoundClip get_soundclip(in long clipno); (b) The simplest way to do this is just to supply an argument to the get_model method to identify the zone to be downloaded, which becomes Model get_zone(in long zone); For an alternative (and more general) approach see part (c). (c) An alternative approach to answering the above question and a method which can be used to host zones on other servers is to create a Zone object, one per zone. Each Zone object is then responsible for handling the downloading of its model, images, movies and soundclips. The client could keep going back to the TourismServer for each new Zone pointer, but a better solution would be to embed the Zone CORBA pointers directly into the Model data, so that the client can link to them directly. All the TourismServer then has to do is provide a pointer to the first Zone object. This new idl file would then look like: interface Zone Model get_model(); Image get_image(in long imageno); Movie get_movie(in long movieno); SoundClip get_soundclip(in long clipno); interface TourismServer Zone get_first_zone(); (d) In order to do this load balancing, the pointers contained in the models must be separated from the actual Zone objects that will supply the downloading. The simplest way to do this is to introduce an intermediate object: interface ZoneFactory Zone get_zone(); The Model data will now contain pointers to ZoneFactorys (there is a separate ZoneFactory per zone). The ZoneFactory object can perform the load balancing when a client uses its get_zone method by determining which of the server s computers is the least heavily loaded and returning a pointer to a Zone object created on that computer, which is used as in part (c). (e) In order for users to see each other moving within the world, two things need to happen: Users need to let the server know about their movements in the world. This could be achieved by adding a move_to method to the Zone object 3

interface Zone void move_to(in string userid, in long x, in long y); Users need to find out about the movements of other users. This can be achieved in one of two ways; either the user requests the information from the server (client pull), or the server automatically notifies the user (server push). Using the client pull technique, this could be achieved using the following interface: struct User string userid; long xpos; long ypos; typedef sequence<user> UserList; interface Zone UserList get_users(); Using the server push technique is a little more complicated. In order to do this, each client program has to become a server also (since it is going to provide a method which will be called by the Zone object). This means that the client programs will need an interface: interface ZoneClient void notify(in UserList users); Also the clients will have to provide a pointer to their ZoneClient object when moving within a zone (in place of their userid): interface Zone void move_to(in ZoneClient clientptr, in long x, in long y); To allow users to send text messages to each other requires an additional method on the Zone object: interface Zone void send_message(in string userid, in string message); The users then have to be able to obtain messages either by client pull: 4

interface Zone string get_message(in string userid); or server push: interface ZoneClient void deliver_message(in string message); Database Systems 3. (a) Pessimism and optimism are two extremes of transactional concurrency control policy. The main difference between optimism and pessimism with reference to the ACID properties is isolation. Pessimistic policies exhibit strict isolation using locking systems. This means that no transaction can access an object that has had a write operation performed on it until the transaction that performed the write operation has committed. More optimistic policies allow other transactions to perform operations on objects before a previous invoker has committed. If a potential conflict is subsequently detected then all of the transactions involved are aborted. The difference is a tradeoff between efficiency and the likelihood of an abort. If simultaneous access to an object is unlikely, then optimistic strategies will be more efficient. Alternatively, if simultaneous access is frequent, then pessimistic strict locking will probably be better although note that dead-lock is more likely with pessimistic schemes. The locking mechanism itself carries an overhead, hence optimistic strategies are also preferred for cases where data is read frequently but updated very rarely. (b) i. A pessimistic policy would be more efficient since there can be a large number of potential concurrent accesses associated with a flight booking system (e.g. when a large group of people need to book on the same flight). ii. An optimistic policy would lead to a more efficient implementation since it is likely that updates will be reasonably infrequent but many concurrent reads may occur when several interested parties review a case. iii. An optimistic policy would be more efficient. The assumptions above about criminals hold for patients. Also, it is important to be able to get a potentially life-saving information quickly and optimistic methods do not delay at transaction startup since they never have to wait for locks. 4. (a) When a transaction T x issues a Q.read, then a lock Q.S must be requested. If the lock is granted then it should be drawn as pointing to 5

T x (see T 4 in the given graph). When multiple reads are requested on the same account Q, then Q.S should point to each transaction (see T 2 and T 3 both reading F in the graph). When an exclusive lock Q.X is requested, then Q.S may or may not be already allocated to T x. If it is not, it should be implicitly allocated. In either case, the exclusive lock Q.X should point to Q.S which in turn points to the transaction to which it is allocated (see E.X in the graph). All of the above assumes that requested locks are granted. As explained in the lectures, a read request will block if some other transaction has exclusive access. A write will also block if some other process has shared or exclusive access. This occurs at step 10 when T 5 request a write on account A. In this case, a dotted arrow is inserted between T 5 and A.X to show that T 5 is blocked waiting to aquire A.X. (b) the graphs following steps 12, 20, 25, and 35 are shown below. When a transaction commits or aborts, all of the locks allocated to it are released (note for these purposes the effects of Commit and abort are identical). T 14 12 C.S A.S 15 C.X T T10 14 12 24 C.S A.S 15 C.X T5 T4 T2 T3 5 4 2 8 A.S D.S B.S E.S F.S 12 10 T A.X E.X T4 T2 T3 T T T8 4 2 8 1 18 1 D.S B.S E.S F.S G.S 20 H.S 1 E.X G.X T4 T2 4 2 T3 8 T T8 23 20 18 22 1 D.S B.S E.S F.S G.S 25 H.S 1 25 E.X G.X H.X a) Resource graph after step 12 b) Resource graph after step 20 c) Resource graph after step 25 Figure 2: (Question 4(b)) (c) A deadlock is indicated in a graph if there is a cycle of dependencies. Activity upto step 25 yields simple graphs with no loops. The final graph however shows a number of transactions waiting on locks, and there is a loop involving T 2, T 3, T 8 and T. These transactions are therefore dead-locked. T 4 depends on T, T 12 depends on T 4 and both T 10 and T 11 depend on T 12, so all of these transactions are also stalled by the deadlock. Concurrent Systems 5. (a) This solution fails to provide mutual exclusion. This can be seen by considering a likely sequence of instructions when the program first starts:

4 18 22 T11 2 31 C.S 31 C.X 2 T12 28 34 D.S 34 D.X 32 T3 8 F.S F.X 24 T10 A.S 33 33 A.X T4 H.X 35 G.X 25 25 1 G.S T H.S 23 1 T8 B.S 2 20 E.S T2 30 E.X d) Resource graph after step 35 Figure 3: (Question 4(b and c)) thread1 finds c2 is true thread2 finds c1 is true thread1 sets c1 false thread2 sets c2 false thread1 executes its critical section thread2 executes its critical section (b) The problem in the previous example is that each thread tests the other s so-called claim variable before setting its own. The suggested reordering of the instructions solves this problem and therefore may be expected to provide mutual exclusion (in fact it can be proved that it does). Unfortunately it deadlocks and is therefore also no use. This can be shown by considering the sequence thread1 sets c1 false thread2 sets c2 false thread1 finds c2 is false and remains in the spinlock forever thread2 finds c1 is false and remains in the spinlock forever. A solution is shown below. Important points to note in the solution are: secure the semaphore for each fork before using it, to ensure mutual exclusion each of the fork semaphores is initialised to 1

the semaphore room is initialised to 4 to make sure that at most 4 philosophers can be in the room at any instant of time. Without this, if five philosophers were allowed in at the same, deadlock could occur with each philosopher having one fork and all waiting for the second. (NB. A trivial solution would be to initialise the room semaphore to 1. This would satisfy the requirements given in the question, but is not an efficient solution as most of the forks would be sitting unused.) semaphore sfork[5]; // Initialised in main() semaphore sroom; // Initialised in main() void philosopher(int ID) while(true) think(); secure(sroom); secure(sfork[id % 5]; secure(sfork[(id + 1) % 5]); eat(); release(sfork[id % 5]; release(sfork[(id + 1) % 5]); release(sroom); int main() // Initialise the semaphores sroom = 4; for(int i = 0; i < 4; i++) sfork[i] = 1; // Start the philosophers for(int i=1; i < 5; i++) fork(philosopher(i));. The solution to this problem requires that the wrapper object maintains a count of the number of nested calls and also records the identity of the caller who currently holds the semaphore. Also, a second semaphore is needed to protect the extended classes critical sections. Thus, the new class definition might be class semaphorex public: void enter(); void leave(); private: semaphore sx; semaphore mutex; int count; // the semaphore being extended // to control access to this class // count nested calls 8

thread * caller; // pointer to calling thread Possible implementations of the enter and leave methods are semaphorex::enter() mutex.enter(); if (caller == CallingThread()) ++count; // nested call to enter else mutex.leave(); sx.enter(); mutex.enter(); count=1; caller = CallingThread(); mutex.leave(); // acquire the real semaphore semaphorex::leave() mutex.enter(); if (caller == CallingThread()) --count; // nested call to leave critical section if (count==0) sx.leave(); // final exit caller = NULL; else raise error; // too many leave calls mutex.leave(); Steve Young February 2008