0% found this document useful (0 votes)
20 views37 pages

CORBA Architecture Case Study Overview

The document describes 9 experiments related to distributed systems including: 1. A case study on CORBA architecture and its components like Object Request Broker, Object Adapter, Skeletons, Stubs and various services. 2. Implementation of concepts like deadlock, election algorithms, clock synchronization using Lamport's algorithm through software simulation. 3. Study of other distributed computing concepts and technologies including Domain Name System, Distributed Shared Memory, Remote Procedure Call and Distributed Database systems. 4. It also describes an experiment on Amoeba distributed operating system.

Uploaded by

Rocky Samuel
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
20 views37 pages

CORBA Architecture Case Study Overview

The document describes 9 experiments related to distributed systems including: 1. A case study on CORBA architecture and its components like Object Request Broker, Object Adapter, Skeletons, Stubs and various services. 2. Implementation of concepts like deadlock, election algorithms, clock synchronization using Lamport's algorithm through software simulation. 3. Study of other distributed computing concepts and technologies including Domain Name System, Distributed Shared Memory, Remote Procedure Call and Distributed Database systems. 4. It also describes an experiment on Amoeba distributed operating system.

Uploaded by

Rocky Samuel
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

List of Experiments

S. No. Experiment Date Sign.

1 Case Study – CORBA.

2 Implementation of Deadlock through Simulation.

3 Implementation of Election Algorithm

S/W Simulation for Clock Synchronization in Distributed System


4
using Lamport’s Algorithm

5 Study of Domain Name System.

6 Study of Distributed Shared Memory

7 Study of Remote Procedure Call

8 Study of Distributed Database.

9 Study of Amoeba Distributed System.


Experiment-01

Aim : Case Study of CORBA Architecture.


CORBA is a middleware design that allows application programs to communicate with one another
irrespective of their programming languages, their hardware and software platforms, the networks they
communicate over and their implementers. Applications are built from CORBA objects, which
implement interfaces defined in CORBA’s interface definition language, IDL. Clients access the
methods in the IDL interfaces of CORBA objects by means of RMI. The middleware component that
supports RMI is called the Object Request Broker or ORB.
The specification of CORBA has been sponsored by members of the Object Management Group
(OMG). Many different ORBs have been implemented from the specification, supporting a variety of
programming languages including Java and C++. CORBA services provide generic facilities that may
be of use in a wide variety of applications. They include the Naming Service, the Event and Notification
Services, the Security Service, the Transaction and Concurrency Services and the Trading Service.

CORBA RMI
Programming in a multi-language RMI system such as CORBA RMI requires more of the programmer
than programming in a single-language RMI system such as Java RMI. The following new concepts
need to be learned:
• the object model offered by CORBA;
• the interface definition language and its mapping onto the implementation language.
In particular, the programmer defines remote interfaces for the remote objects and then uses an interface
compiler to produce the corresponding proxies and skeletons. But in CORBA, proxies are generated in
the client language and skeletons in the server language.

CORBA's object model

The term CORBA object is used to refer to remote objects. Thus, a CORBA object implements an IDL
interface, has a remote object reference and is able to respond to invocations of methods in its IDL
interface. A CORBA object can be implemented by a language that is not object oriented, for example
without the concept of class. Since implementation languages will have different notions of class or
even none at all, the class concept does not exist in CORBA. Therefore classes cannot be defined in
CORBA IDL, which means that instances of classes cannot be passed as arguments. However, data
structures of various types and arbitrary complexity can be passed as arguments.

CORBA IDL

CORBA IDL provides an interface consisting of a name and a set of methods that a client can request.
IDL supports fifteen primitive types, constructed types and a special type called Object.
Primitive types: short, long, unsigned short, unsigned long, float, double, char, boolean, octet, and any.
Constructed types such as arrays and sequences must be defined using typedefs and passed by value.
Interfaces and other IDL type definitions can be grouped into logical units called modules.
CORBA Architecture

Implementation
repository
Client Server
Request
Client ORB ORB Servant
skeleton
adapter
Object

Program Proxy core core A


for A Reply

Interface
repository
The architecture is designed to support the role of an object request broker that enables clients to invoke
methods in remote objects, where both clients and servers can be implemented in a variety of
programming languages. The CORBA architecture contains three additional components: the object
adapter, the implementation repository and the interface repository. CORBA provides for both static
and dynamic invocations. Static invocations are used when the remote interface of the CORBA object
is known at compile time, enabling client stubs and server skeletons to be used. If the remote interface
is not known at compile time, dynamic invocation must be used. Most programmers prefer to use static
invocation because it provides a more natural programming model.

ORB core
The role of the ORB core is that of the communication module. In addition, an ORB core provides an
interface that includes the following:
• operations enabling it to be started and stopped;
• operations to convert between remote object references and strings;
• operations to provide argument lists for requests using dynamic invocation.

Object adapter
The role of an object adapter is to bridge the gap between CORBA objects with IDL interfaces and the
programming language interfaces of the corresponding servant classes. This role also includes that of
the remote reference and dispatcher modules. An object adapter has the following tasks:
• it creates remote object references for CORBA objects;
• it dispatches each RMI via a skeleton to the appropriate servant;
• it activates and deactivates servants.
An object adapter gives each CORBA object a unique object name, which forms part of its remote
object reference. The same name is used each time an object is activated. The object name may be
specified by the application program or generated by the object adapter. Each CORBA object is
registered with its object adapter, which may keep a remote object table that maps the names of CORBA
objects to their servants. Each object adapter has its own name, which also forms part of the remote
object references of all of the CORBA objects it manages. This name may either be specified by the
application program or generated automatically.

Portable object adapter


The CORBA 2.2 standard for object adapters is called the Portable Object Adapter. It is called portable
because it allows applications and servants to be run on ORBs produced by different developers. This
is achieved by means of the standardization of the skeleton classes and of the interactions between the
POA and the servants. The POA supports CORBA objects with two different sorts of lifetimes:
• those whose lifetimes are restricted to that of the process their servants are instantiated in;
• and those whose lifetimes can span the instantiations of servants in multiple processes.

The former have transient object references and the latter have persistent object references.
The POA allows CORBA objects to be instantiated transparently; and in addition, it separates the
creation of CORBA objects from the creation of the servants that implement those objects. Server
applications such as databases with large numbers of CORBA objects can create servants on demand,
only when the objects are accessed. In this case, they may use database keys for the object names;
alternatively, they may use a single servant to support all of these objects. In addition, it is possible to
specify policies to the POA, for example, as to whether it should provide a separate thread for each
invocation, whether the object references should be persistent or transient and whether there should be
a separate servant for each CORBA object. The default is that a single servant can represent all of the
CORBA objects for its POA.

Skeletons
Skeleton classes are generated in the language of the server by an IDL compiler. As before, remote
method invocations are dispatched via the appropriate skeleton to a particular servant and the skeleton
unmarshals the arguments in request messages and marshals exceptions and results in reply messages.
Client stubs/proxies
These are in the client language. The class of a proxy (for object oriented languages) or a set of stub
procedures (for procedural languages) is generated from an IDL interface by an IDL compiler for the
client language. As before, the client stubs/proxies marshal the arguments in invocation requests and
unmarshal exceptions and results in replies.

Implementation repository
An implementation repository is responsible for activating registered servers on demand and for
locating servers that are currently running. The object adapter name is used to refer to servers when
registering and activating them. An implementation repository stores a mapping from the names of
object adapters to the pathnames of files containing object implementations. Object implementations
and object adapter names are generally registered with the implementation repository when server
programs are installed. When object implementations are activated in servers, the hostname and port
number of the server are added to the mapping.

Implementation repository entry:

object adapter name pathname of object hostname and port number of


implementation server

Not all CORBA objects need to be activated on demand. Some objects, for example callback objects
created by clients, run once and cease to exist when they are no longer needed. They do not use the
implementation repository.
An implementation repository generally allows extra information to be stored about each server, for
example access control information as to who is allowed to activate it or to invoke its operations. It is
possible to replicate information in implementation repositories in order to provide availability or fault
tolerance.

Interface repository
The role of the interface repository is to provide information about registered IDL interfaces to clients
and servers that require it. For an interface of a given type it can supply the names of the methods and
for each method, the names and types of the arguments and exceptions. Thus, the interface repository
adds a facility for reflection to CORBA. Suppose that a client program receives a remote reference to a
new CORBA object. Also suppose that the client has no proxy for it; then it can ask the interface
repository about the methods of the object and the types of parameter each of them requires. When an
IDL compiler processes an interface, it assigns a type identifier to each
IDL type it encounters. For each interface registered with it, the interface repository provides a mapping
between the type identifier of that interface and the interface itself. Thus, the type identifier of an
interface is sometimes called the repository ID because it may be used as a key to IDL interfaces
registered in the interface repository.
Every CORBA remote object reference includes a slot that contains the type identifier of its interface,
enabling clients that hold it to enquire of its type with the interface repository. Those applications that
use static (ordinary) invocation with client proxies and IDL skeletons do not require an interface
repository. Not all ORBs provide an interface repository.
Experiment-02

Aim 2- Implementation of Deadlock through Simulation.


Program of Deadlock:
public class AnotherDeadLock extends Thread
{
public static void main(String[] args) {
final Object resource1 = "resource1";
final Object resource2 = "resource2";
// t1 tries to lock resource1 then resource2
Thread t1 = new Thread() {
public void run() {
// Lock resource 1
synchronized (resource1) {
[Link]("Thread 1: locked resource 1");
try {
[Link](50);
} catch (InterruptedException e) {
}
synchronized (resource2) {
[Link]("Thread 1: locked resource 2");
}
}
}
};
// t2 tries to lock resource2 then resource1
Thread t2 = new Thread() {
public void run() {
synchronized (resource2) {
[Link]("Thread 2: locked resource 2");
try {
[Link](50);
} catch (InterruptedException e) {
}
synchronized (resource1) {
[Link]("Thread 2: locked resource 1");
}
}
}
};
// If all goes as planned, deadlock will occur,
// and the program will never exit.
[Link]();
[Link]();
}
}
Output of Deadlock
Experiment-03

Aim 3- Implementation of Election Algorithm (Bully).


import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
public class BullyAlgo implements Runnable{
static int leader_id=-1;
static int self_id=-1;
static int server_Port = 5511 ;
String operation;
String reqtype;
static int source_id=-1;
static HashMap<Integer,String> processes= new HashMap<Integer,String>();
static boolean received=false;
static long start_time=-1;
static boolean leader_flag=false;
static boolean election_req=false;
static int higher;
static int ok_ctr=0;
static long start_time_ok=-1;
public BullyAlgo(String operation) {
[Link] = operation;
}
public BullyAlgo(String operation, String reqtype) {
[Link] = operation;
[Link]=reqtype;
}
public static void main(String args[]) throws UnknownHostException, IOException,
InterruptedException{
initialize();
Runnable receiver = new BullyAlgo("receiver");
new Thread(receiver).start();
// [Link](10);
Runnable heartbeat = new BullyAlgo("heartbeat");
new Thread(heartbeat).start();
while(true){}
public void run(){
if([Link]("timer")){
[Link]("Inside timer thread");
try{
[Link](7000);
//[Link]("Timer thread Awake");
if(!received){
leader_id=self_id;
election_req=false; //to allow another election req to come in
leader_flag=true;
[Link]("******I am the selected LEADER ! "+leader_id);
Runnable sender = new BullyAlgo("sender","cood");
new Thread(sender).start();
}
if(received && !leader_flag){
[Link]("Received OK but LEADER HAS FAILED, leaderflag= "+leader_flag);
election_req=false;
received=false;
[Link]("election_req= "+election_req+" received = "+received);
Runnable sender = new BullyAlgo("sender","elecreq");
new Thread(sender).start();
}
}
catch(Exception e){
[Link]("Interrupted in Timer Thread");
}
}
else if([Link]("timerok")){
[Link]("Inside timerOK thread");
while(true){
if((!leader_flag) && [Link]()-start_time_ok>(5000+ (5000*(5-self_id)))){
ok_ctr=0;
[Link]("Higher Process Sent OK but Failed, so Start a new Election process");
Runnable sender = new BullyAlgo("sender","elecreq");
new Thread(sender).start();
break;
}
}
}
else if([Link]("receiver")){
ServerSocket serverSocket = null;
try{
serverSocket = new ServerSocket(server_Port);
while(true){
Socket socket = [Link]();
//[Link]("Connection established.....");
DataInputStream in = new DataInputStream([Link]());
String option=[Link]();
if([Link]("elecreq")){
source_id=[Link]([Link]());
[Link]("received election request from "+source_id);
if(self_id>source_id){
Runnable sender = new BullyAlgo("sender","ok");
new Thread(sender).start();
}
if(!election_req){
Runnable sender = new BullyAlgo("sender","elecreq");
new Thread(sender).start();
start_time=[Link]();
election_req=true;
Runnable timer = new BullyAlgo("timer");
new Thread(timer).start();
[Link]("Start time here is :"+start_time);
}
}
else if([Link]("ok")){
received=true;
int sender=[Link]([Link]());
[Link]("Received OK from "+[Link](sender));
}
else if([Link]("cood")){
leader_id=[Link]([Link]());
leader_flag=true;
election_req=false;
received=false;
[Link]("******LEADER selected is :"+leader_id+" : "+[Link](leader_id)+ " Leader
Flag= "+leader_flag);
[Link]("Election Request value= "+election_req+" Value of received= "+received);
}
else if([Link]("heartbeat")){
int sender=[Link]([Link]());
[Link]("HEARTBEAT received from "+[Link](sender));
}
[Link]();
}
}
catch(Exception e){
[Link]();
}
}
else if([Link]("heartbeat")){
while(true){
try{
[Link]("");
if(leader_flag && (self_id!=leader_id)){
[Link](1500);
String destination_server=[Link](leader_id);
Socket socket = new Socket(destination_server + ".[Link]", server_Port);
DataOutputStream out = new DataOutputStream([Link]());
[Link]("heartbeat");
[Link](self_id+"");
[Link]("Sent HEARTBEAT to : "+destination_server);
}
}
catch(Exception e){
leader_flag=false;
[Link]("Leader has FAILED!");
[Link]("election_req= "+election_req+" received = "+received);
//send election request
Runnable sender = new BullyAlgo("sender","elecreq");
new Thread(sender).start();
}
}
}
else if([Link]("sender")){
if([Link]("elecreq")){
try{
sendElectionRequest();
}
catch(Exception e){
[Link]("Process has FAILED, Election Request cannot be processed !");
}
}
else if([Link]("ok")){
try{
sendOK();
}
catch(Exception e){
[Link]();
}
}
else if([Link]("cood")){
try{
sendCoordinatorMsg();
}
catch(Exception e){
[Link]("Process has FAILED, Won't get the new leader !");
}
}
}
}
public static void sendCoordinatorMsg() throws IOException{
for (int key : [Link]()) {
if(key!=self_id){
String destination_server=[Link](key);
try{
Socket socket = new Socket(destination_server + ".[Link]", server_Port);
DataOutputStream out = new DataOutputStream([Link]());
[Link]("cood");
[Link](leader_id+"");
[Link]("Sent Leader ID to : "+destination_server);
}
catch(Exception e){
[Link]("The process "+destination_server+" has failed, won't get the new leader !");
}
}
}
}
public static void sendOK() throws IOException{
try{
String destination_server=[Link](source_id);
Socket socket = new Socket(destination_server + ".[Link]", server_Port);
DataOutputStream out = new DataOutputStream([Link]());
[Link]("ok");
[Link](self_id+"");
[Link]("Sent OK to : "+destination_server);
}
catch(Exception e){
[Link]("Process "+[Link](source_id)+" has FAILED. OK Message cannot be sent
!");
}
}
public static void sendElectionRequest() throws IOException{
[Link]("Election Initiated..");
int failure=0;
for (int key : [Link]()) {
if(key>self_id){
String destination_server=[Link](key);
try{
Socket socket = new Socket(destination_server + ".[Link]", server_Port);
DataOutputStream out = new DataOutputStream([Link]());
[Link]("elecreq");
[Link](self_id+"");
[Link]("Sent Election Request to : "+destination_server);
}
catch(Exception e){
[Link]("The process :"+destination_server+" has FAILED, cannot send Election Request
!");
failure++;
}
}
}
if(failure==higher){
if(!election_req){
start_time=[Link]();
[Link]("Inside if of sendElectionRequest, start_time= "+start_time);
election_req=true;
received=false;
Runnable timer = new BullyAlgo("timer");
new Thread(timer).start();
}
}
}
public static void initialize() throws UnknownHostException, IOException{
[Link](5,"yes");
[Link](4,"comet");
[Link](3,"doors");
[Link](2,"gorgon");
[Link](1,"queeg");
InetAddress iAddress = [Link]();
String server_name = [Link]();
if(server_name.equals("yes")){
self_id=5;
[Link]("Server id here is= "+self_id);
higher=-1;
}
else if(server_name.equals("comet")){
self_id=4;
[Link]("Server id here is= "+self_id);
higher=1;
}
else if(server_name.equals("doors")){
self_id=3;
[Link]("Server id here is= "+self_id);
higher=2;
//Runnable sender = new BullyAlgo("sender","elecreq");
//new Thread(sender).start();
}
else if(server_name.equals("gorgon")){
self_id=2;
higher=3;
[Link]("Server id here is= "+self_id);
//Election Initiator
Runnable sender = new BullyAlgo("sender","elecreq");
new Thread(sender).start();
}
else if(server_name.equals("queeg")){
self_id=1;
higher=4;
[Link]("Server id here is= "+self_id);
}
}
}
Experiment-04

Aim 4- Software Simulation for Clock Synchronization in Distributed System using Lamport’s
Algorithm

Program of Lamport’s Algorithm:


import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link].*;
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
public class LamportAlgorithm {
public static void main (String args []) {
ActionListener addProcess = new ActionListener () {
public void actionPerformed(ActionEvent e) {
(new Thread (new LamportProcess ())).start();
}
};
JFrame mainFrame = new JFrame ("Lamport");
[Link] (125, 75);
[Link] (JFrame.DISPOSE_ON_CLOSE);
JButton btnAddProcess = new JButton ("Add Process");
[Link](addProcess);
[Link](btnAddProcess);
[Link] (true);
(new Thread (new LamportServer ())).start();
}
}
final class LamportServer implements Runnable {
private int numOfClients = 0;
ArrayList outputConnections = new ArrayList ();
private ServerSocket socket;
private Socket tempSocket;
private ObjectOutputStream tempObjectOutputStream;
private JFrame serverFrame;
private JPanel serverPanel;
private JLabel lblClients;
private JTextArea txtNotifications;
private JScrollPane scrollPane;
LamportServer () {
serverFrame = new JFrame ("Mediator");
[Link] (true);
[Link](JFrame.EXIT_ON_CLOSE);
[Link] (225, 200);
serverPanel = new [Link]();
[Link](new [Link](0, 1));
lblClients = new [Link]();
[Link](new Font ("Times New Roman", 0, 21));
updateClientCount ();
txtNotifications = new JTextArea (4, 16);
[Link](false);
scrollPane = new JScrollPane (txtNotifications);
[Link](180, 150);
[Link](lblClients);
[Link](scrollPane);
[Link](serverPanel);
[Link](true);
}
public void run() {
try {
socket = new ServerSocket (1234);
while (true) {
try {
tempSocket = [Link]();
tempObjectOutputStream = new ObjectOutputStream ([Link]());
[Link](new RegisterMessage (++numOfClients));
[Link]("Registered process number " + numOfClients + "\n");
updateClientCount ();
[Link](tempObjectOutputStream);
(new Thread (new ServerThread (this, tempSocket))).start();
} catch (IOException ex) {
[Link]([Link]()).log([Link], null, ex);
}
}
} catch (IOException ex) {
[Link]([Link]()).log([Link], null, ex);
}
}
private void updateClientCount() {
[Link]("Number of Processes: " + numOfClients);
}
}
class ServerThread implements Runnable {
LamportServer server;
Socket socket;
ObjectInputStream inputStream;
ObjectOutputStream outputStream;
ServerThread (LamportServer server, Socket socket) {
try {
[Link] = server;
[Link] = socket;
[Link] = new ObjectInputStream ([Link]());
} catch (IOException ex) {
[Link]([Link]()).log([Link], null, ex);
}
}
public void run() {
CommunicationMessage message;
while (true) {
try {
message = (CommunicationMessage) [Link]();
outputStream =
(ObjectOutputStream)[Link]([Link]-1);
[Link] (message);
} catch (IOException ex) {
[Link]([Link]()).log([Link], null, ex);
} catch (ClassNotFoundException ex) {
[Link]([Link]()).log([Link], null, ex);
}
}
}
}
class LamportProcess implements Runnable {
private Socket socket;
private int processNumber;
private int time = 0;
ObjectInputStream fromServer;
ObjectOutputStream toServer;
private JFrame processFrame;
private JTextField txtSendMessageTo;
private JPanel clockPanel;
private JPanel clockRatePanel;
private JButton btnIncrement;
private JButton btnDecrement;
private JLabel clock;
private JPanel messagePanel;
private JLabel lblSendMessageTo;
private JButton btnSend;
private Timer timer;
private JTextArea notificationArea;
private ActionListener sendMessage = new ActionListener () {
public void actionPerformed(ActionEvent e) {
try {
CommunicationMessage message = new CommunicationMessage (processNumber, time,
[Link]([Link]()));
[Link](message);
} catch (UnknownHostException ex) {
[Link]([Link]()).log([Link], null, ex);
} catch (IOException ex) {
[Link]([Link]()).log([Link], null, ex);
}
}
};
private ActionListener incrementClockRate = new ActionListener () {
public void actionPerformed(ActionEvent e) {
[Link]([Link]()/2);
}
};
private ActionListener decrementClockRate = new ActionListener () {
public void actionPerformed(ActionEvent e) {
[Link]([Link]()*2);
}
};
LamportProcess () {
}
private int initiateConnection () {
try {
socket = new Socket ("localhost", 1234);
toServer = new ObjectOutputStream ([Link]());
fromServer = new ObjectInputStream ([Link]());
RegisterMessage message = (RegisterMessage) [Link]();
processNumber = [Link];
} catch (ClassNotFoundException ex) {
[Link]([Link]()).log([Link], null, ex);
} catch (UnknownHostException ex) {
[Link]([Link]()).log([Link], null, ex);
} catch (IOException ex) {
[Link]([Link]()).log([Link], null, ex);
}
return processNumber;
}
private void Communicate () {
CommunicationMessage message;
while (true) {
try {
message = (CommunicationMessage) [Link]();
[Link]("Got a message from " + [Link] + " with timestamp
" + [Link] + "\n");
if (time <= [Link]) {
time = [Link];
[Link]();
[Link](null);
}
} catch (IOException ex) {
[Link]([Link]()).log([Link], null, ex);
} catch (ClassNotFoundException ex) {
[Link]([Link]()).log([Link], null, ex);
}
}
}
private ActionListener clockTick = new ActionListener () {
public void actionPerformed(ActionEvent e) {
[Link]([Link](time));
time++;
}
};
public void run() {
processFrame = new JFrame ("Lamport Process : " + processNumber);
[Link](true);
[Link](JFrame.DISPOSE_ON_CLOSE);
[Link](new FlowLayout ());
[Link] (395, 240);
clockPanel = new JPanel (new FlowLayout ());
clock = new JLabel ();
[Link](new Font ("Times New Roman", 0, 50));
[Link](null);
[Link](clock);
[Link](true);

clockRatePanel = new JPanel (new GridLayout (2, 1));


btnIncrement = new JButton ("+");
btnDecrement = new JButton ("-");
[Link](incrementClockRate);
[Link](decrementClockRate);
[Link](btnIncrement);
[Link](btnDecrement);
[Link](clockRatePanel);
[Link](clockPanel);
messagePanel = new JPanel (new GridLayout ());
lblSendMessageTo = new JLabel ("Send a message to ");
[Link](lblSendMessageTo);
txtSendMessageTo = new JTextField ();
[Link](sendMessage);
[Link] (txtSendMessageTo);
btnSend = new JButton ("Send");
[Link](sendMessage);
[Link] (btnSend);
[Link](messagePanel);
notificationArea = new [Link](5, 32);
[Link]((new JPanel (new GridLayout (1,1))).add(new JScrollPane (notificationArea)));
timer = new Timer (2000, clockTick);
[Link]();
[Link](true);
processNumber = initiateConnection ();
[Link]("Lamport Process : " + processNumber);
Communicate ();
}
}
//interface Message extends Serializable {};
class CommunicationMessage implements Message {
CommunicationMessage (int sendingProcessNumber, int time, int receivingProcessNumber) {
[Link] = sendingProcessNumber;
[Link] = time;
[Link] = receivingProcessNumber;
}
int sendingProcessNumber;
int time;
int receivingProcessNumber;
}
class RegisterMessage implements Message {
int processNumber = 0;
RegisterMessage (int ProcessNumber) {
[Link] = ProcessNumber;
}
RegisterMessage() {}
}

Output of Lamport’s Algorithm


Experiment-05

Aim 5- Study of Domain Name System.


To identify hosts, IP addresses (especially IPv6 addresses) are cumbersome for humans to use and
remember. The Internet supports the use of host names to identify hosts, both clients and servers. In
order to be used by protocols such as TCP and IP, host names are converted into IP addresses using a
process known as name resolution. There are different forms of name resolution in the Internet, but the
most prevalent and important one uses a distributed database system known as the Domain Name
System (DNS). DNS runs as an application on the Internet, using IPv4 or IPv6 (or both). For scalability,
DNS names are hierarchical, as are the servers that support name resolution.
DNS is a distributed client/server networked database used by TCP/IP applications to map between host
names and IP addresses (and vice versa), to provide capabilities like electronic mail routing information
and service naming. The DNS provides the protocol that allows clients and servers to communicate
with each other and also a protocol for allowing servers to exchange information.
From an application’s point of view, access to the DNS is through an application library called
a resolver. An application must convert a host name to an IPv4 and/or IPv6 address before it can ask
TCP to open a connection or send a unicast datagram using UDP. The TCP and IP protocol
implementations know nothing about the DNS; they operate only with the addresses.

The DNS Name Space


The DNS name space is the set of all names used with DNS. This space is partitioned hierarchically
and is case insensitive.
The current DNS name space is a tree of domains with an unnamed root at the top. The top echelons of
the tree are the so-called top-level domains (TLDs), which include:

• Generic TLDs (gTLDs)


• Country-code TLDs (ccTLDs)
• Internationalized country-code TLDs (IDN ccTLDs)
• A special infrastructure TLD called, for historical reasons, ARPA [RFC3172].

These form the top levels of a naming tree with the form shown below.
There are five commonly used groups of TLDs, and one group of specialized domains being used
for internationalized domain names (IDNs). [p512]
The gTLDs are grouped into categories:

• Generic
• Generic-restricted
• Sponsored

The generic gTLDs (generic appears twice) are open for unrestricted use. The others (generic-restricted
and sponsored) are limited to various sorts of uses or are constrained as to what entity may assign names
from the domain.
There is a "new gTLD" program in the works that may significantly expand the current set, possibly to
several hundred or even thousand. This program and policies relating to TLD management in general
are maintained by the Internet Corporation for Assigned Names and Numbers (ICANN).
Because some of these two-letter country codes of ccTLDs are suggestive of other uses and meanings,
various countries have been able to find commercial windfalls from selling names within their ccTLDs.
For example, the domain name [Link] is really a registration in the Pacific island of Tuvalu, which has
been selling domain names associated with the television entertainment industry. This is called
a domain hack.

DNS Naming Syntax

The names below a TLD in the DNS name tree are further partitioned into subdomains, which is very
common practice, especially for the ccTLDs.
Fully qualified domain name (FQDN) *

The example names we have seen so far are known as fully qualified domain names (FQDNs). They
are sometimes written more formally with a trailing period (e.g., [Link].). This trailing period indicates
that the name is complete; no additional information should be added to the name when performing a
name resolution.
Unqualified domain name *

An unqualified domain name, which is used in combination with a default domain or domain search
list set during system configuration, has one or more strings appended to the end. During configuration,
system is typically assigned a default domain extension and search list using DHCP. For example, the
default domain [Link] might be configured in systems at the computer science department at
UC Berkeley. If a user on one of these machines types in the name vangogh, the local resolver software
converts this name to the FQDN [Link]. before invoking a resolver to
determine vangogh’s IP address.
A domain name consists of a sequence of labels separated by periods. The name represents a location
in the name hierarchy, where the period is the hierarchy delimiter and descending down the tree takes
place from right to left in the name.
The hierarchical structure of the DNS name space allows different administrative authorities to manage
different parts of the name space. For example, creating a new DNS
name [Link] dealing with the owner of the [Link] subdomain
only. The [Link] and edu portions of the name space would not require alteration, so the owners
of those would not need to be bothered. This feature of DNS is one key aspect of its scalability. No
single entity is required to administer all the changes for the entire DNS name space. [p516]
Name Servers and Zones

A person responsible for managing part of the active DNS name space is supposed to arrange for at
least two name servers or DNS servers to hold information about the name space so that Internet users
can perform queries on the names.
The DNS (formed by servers) is a distributed system whose primary job is to provide name-to-address
mappings; however, it can also provide a wide array of additional information.
A zone, as the unit of administrative delegation, is a subtree of the DNS name space that can be
administered separately from other zones. Every domain name exists within some zone (even the TLDs
that exist in the root zone). Whenever a new record is added to a zone, the DNS administrator for the
zone allocates a name and additional information (usually an IP address) for the new entry into the name
server’s database. For example:

• At a small campus, one person could do this each time a new server is added to the network;
• In a large enterprise the responsibility would have to be delegated (probably by departments or
other organizational units), as one person likely could not keep up with the work.

A DNS server can contain information for more than one zone. At any hierarchical change point in a
domain name (i.e., wherever a period appears), a different zone and containing server may be accessed
to provide information for the name. This is called a delegation. A common delegation approach uses
a zone for implementing a second-level domain name, such as [Link]. In this domain, there may
be individual hosts (e.g., [Link]) or other domains (e.g., [Link]). Each zone has a
designated owner or responsible party who is given authority to manage the names, addresses, and
subordinate zones within the zone. Often this person manages not only the contents of the zone but also
the name servers that contain the zone’s database(s).
For redundancy, zone information is supposed to exist in at least two places: there should be at least
two servers containing information for each zone. All of these servers contain identical information
about a zone. Among the servers, a primary server contains the zone database in a disk file, and one or
more secondary servers obtain copies from the primary using a process called a zone transfer. DNS
has a special protocol for performing zone transfers, but copies of a zone’s contents can also be obtained
using other means (e.g., the rsync utility).
Experiment-06

Aim 6- Study of Remote Procedure Call

Remote Procedure Call


In 1984, Birrell and Nelson devised a mechanism to allow programs to call procedures on
other machines. A process on machine A can call a procedure on machine B. The process on
A is suspended and execution continues on B. When B returns, the return value is passed to A
and A continues execution. This mechanism is called the Remote Procedure Call (RPC). To
the programmer, the goal is that it should appear as if a normal procedure call is taking place.
Obviously, a remote procedure call is different from a local one in the underlying
implementation.

Steps in a remote procedure call

Clearly, there is no architectural support for making remote procedure calls. A local procedure
call generally involves placing the calling parameters on the stack and executing some form
of a call instruction to the address of the procedure. The procedure can read the parameters
from the stack, do its work, place the return value in a register and then return to the address
on top of the stack. None of this exists for calling remote procedures. We’ll have to simulate
it all with the tools that we do have, namely local procedure calls and sockets for net- work
communication. This simulation makes remote procedure calls a language- level construct as
opposed to sockets, which are an operating system level construct. This means that our
compiler will have to know that remote procedure call invocations need the presence of special
code.
The entire trick in making remote procedure calls work is in the creation of stub functions that
make it appear to the user that the call is really local. A stub function looks like the function
that the user intends to call but really contains code for sending and receiving messages over
a network. The following sequence of operations takes place (from p. 693 of W. Richard
Steven’s UNIX Net- work Programming):
Figure 1. Functional steps in a remote procedure call
The sequence of operations, depicted in Figure 1, is:
1. The client calls a local procedure, called the client stub. To the client process, it appears
that this is the actual procedure. The client stub packages the arguments to the remote
procedure (this may involve converting them to a standard format) and builds one or more
net- work messages. The packaging of arguments into a network message is called
marshaling.
2. Network messages are sent by the client stub to the remote system (via a system call to
the local kernel).
3. Network messages are transferred by the kernel to the remote system via some protocol
(either connectionless or connection-oriented).
4. A server stub procedure on the server receives the messages. It unmarshals the arguments
from the messages and possibly converts them from a standard form into a machine-specific
form.
5. The server stub executes a local procedure call to the actual server function, passing it the
arguments that it received from the client.
6. When the server is finished, it returns to the server stub with its return values.
7. The server stub converts the return values (if necessary) and marshals them into one or
more network messages to send to the client stub.
8. Messages get sent back across the network to the client stub.
9. The client stub reads the messages from the local kernel.
10. It then returns the results to the client function (possibly converting them first).
The client code then continues its execution.

The major benefits of RPC are twofold: the programmer can now use procedure call semantics
and writing distributed applications is simplified because RPC hides all of the network code
into stub functions. Application programs don’t have to worry about details (such as sockets,
port numbers, byte ordering). Using the OSI reference model, RPC is a presentation layer
service.

How do you pass parameters?


Passing by value is simple (just copy the value into the network message). Passing by reference
is hard – it makes no sense to pass an address to a remote machine. If you want to support
passing by reference, you'll have to copy the items referenced to ship them over and then copy
the new values back to the reference. If remote procedure calls are to support more complex
structures, such as trees and linked lists, they will have to copy the structure into a pointer less
representation (e.g., a flattened tree), transmit it, and reconstruct the data structure on the
remote side.

How do we represent data?


On a local system there are no data incompatibility problems—the data format is always the
same. With RPC, a remote machine may have different byte ordering, different sizes of
integers, and a different floating point representation. The problem was solved in the IP
protocol suite by forcing everyone to use big endian byte ordering for all 16 and 32 bit fields
in headers (hence the htons and htonl functions). For RPC, we need to select a “standard”
encoding for all data types that can be passed as parameters if we are to communicate with
heterogeneous systems. Sun’s RPC, for example, uses XDR (eXternal Data Representation)
for this process. Most data representation implementations use implicit typing (only the value
is transmitted, not the type of the variable). The ISO data representation (ASN.1—Abstract
Syntax Notation) uses explicit typing, where the type of each field is transmitted along with
the value.

What are the semantics of calling remote procedures?


The semantics of calling a regular procedure are simple: a procedure is executed exactly once
when we call it. With a remote procedure, the “exactly once” aspect is quite difficult to
achieve. A remote procedure may be executed:
• 0 times if the server crashed or process died before running the server code.
• Once if everything works fine.
• Once or more if the server crashed after returning to the server stub but before sending
the response. The client won’t get the return response and may decide to try again, thus
executing the function more than once. If it doesn’t try again, the function is executed
once.
• More than once if the client times out and retransmits. It’s possible that the original
request may have been delayed. Both may get executed (or not).

If a function may be run any number of times without harm, it is idempotent (e.g., time of day,
math functions, read static data). Otherwise, it is a nonidempotent function (e.g., append or
modify a file).
Figure 2. Compilation steps for Remote Procedure Calls
What about performance?
A regular procedure call is fast typically only a few instruction cycles. What about a remote
procedure call? Think of the extra steps involved. Just calling the client stub function and
getting a return from it incurs the overhead of a procedure call. On top of that, we need to
execute the code to marshal parameters, call the network routines in the OS (incurring a
context switch), deal with network latency, have the server receive the message and switch to
the server process, unmarshal parameters, call the server function, and do it all over again on
the return trip. Without a doubt a remote procedure call will be much slower.
Aim 7- Study of Distributed Database Management System.

Definition
A distributed database is basically a database that is not limited to one system; it is spread over different
sites, i.e, on multiple computers or over a network of computers. A distributed database system is
located on various sited that don’t share physical components. This may be required when a particular
database needs to be accessed by various users globally. It needs to be managed such that for the users
it looks like one single database.
The software that creates and administers the distributed database and provides data to the users is called
the Distributed Database Management system (DDBMS).It coordinates the access to the data at various
nodes in the distributed network environment. A distributed database management system is a software
system that permits the management of a distributed database and makes the distribution transparent to
the users.

Factors Encouraging DDBMS


The following factors encourage moving over to DDBMS −

• Distributed Nature of Organizational Units − Most organizations in the current times are
subdivided into multiple units that are physically distributed over the globe. Each unit requires
its own set of local data. Thus, the overall database of the organization becomes distributed.

• Need for Sharing of Data − The multiple organizational units often need to communicate with
each other and share their data and resources. This demands common databases or replicated
databases that should be used in a synchronized manner.
• Support for Both OLTP and OLAP − Online Transaction Processing (OLTP) and Online
Analytical Processing (OLAP) work upon diversified systems which may have common data.
Distributed database systems aid both these processing by providing synchronized data.

• Database Recovery − One of the common techniques used in DDBMS is replication of data
across different sites. Replication of data automatically helps in data recovery if database in
any site is damaged. Users can access data from other sites while the damaged site is being
reconstructed. Thus, database failure may become almost inconspicuous to users.

• Support for Multiple Application Software − Most organizations use a variety of application
software each with its specific database support. DDBMS provides a uniform functionality for
using the same data among different platforms.

Advantages of Distributed Databases


Following are the advantages of distributed databases over centralized databases.

Modular Development − If the system needs to be expanded to new locations or new units, in
centralized database systems, the action requires substantial efforts and disruption in the existing
functioning. However, in distributed databases, the work simply requires adding new computers and
local data to the new site and finally connecting them to the distributed system, with no interruption in
current functions.

More Reliable − In case of database failures, the total system of centralized databases comes to a halt.
However, in distributed systems, when a component fails, the functioning of the system continues may
be at a reduced performance. Hence DDBMS is more reliable.

Better Response − If data is distributed in an efficient manner, then user requests can be met from
local data itself, thus providing faster response. On the other hand, in centralized systems, all queries
have to pass through the central computer for processing, which increases the response time.

Lower Communication Cost − In distributed database systems, if data is located locally where it is
mostly used, then the communication costs for data manipulation can be minimized. This is not feasible
in centralized systems.

Disadvantages of Distributed Databases


Following are some of the disadvantages associated with distributed databases.

• Need for complex and expensive software − DDBMS demands complex and often expensive
software to provide data transparency and co-ordination across the several sites.

• Processing overhead − Even simple operations may require a large number of


communications and additional calculations to provide uniformity in data across the sites.

• Data integrity − The need for updating data in multiple sites pose problems of data integrity.
• Overheads for improper data distribution − Responsiveness of queries is largely dependent
upon proper data distribution. Improper data distribution often leads to very slow response to
user requests.

Types of Distributed Databases


Distributed databases can be broadly classified into homogeneous and heterogeneous distributed
database environments, each with further sub-divisions, as shown in the following illustration.

Homogeneous Distributed Databases


In a homogeneous distributed database, all the sites use identical DBMS and operating systems. Its
properties are −

• The sites use very similar software.

• The sites use identical DBMS or DBMS from the same vendor.

• Each site is aware of all other sites and cooperates with other sites to process user requests.

• The database is accessed through a single interface as if it is a single database.

Types of Homogeneous Distributed Database


There are two types of homogeneous distributed database −

• Autonomous − Each database is independent that functions on its own. They are integrated by
a controlling application and use message passing to share data updates.

• Non-autonomous − Data is distributed across the homogeneous nodes and a central or master
DBMS co-ordinates data updates across the sites.

Heterogeneous Distributed Databases


In a heterogeneous distributed database, different sites have different operating systems, DBMS
products and data models. Its properties are −

• Different sites use dissimilar schemas and software.


• The system may be composed of a variety of DBMSs like relational, network, hierarchical or
object oriented.

• Query processing is complex due to dissimilar schemas.

• Transaction processing is complex due to dissimilar software.

• A site may not be aware of other sites and so there is limited co-operation in processing user
requests.

Types of Heterogeneous Distributed Databases


• Federated − The heterogeneous database systems are independent in nature and integrated
together so that they function as a single database system.

• Un-federated − The database systems employ a central coordinating module through which
the databases are accessed.

Distributed DBMS Architectures


DDBMS architectures are generally developed depending on three parameters −

• Distribution − It states the physical distribution of data across the different sites.

• Autonomy − It indicates the distribution of control of the database system and the degree to
which each constituent DBMS can operate independently.

• Heterogeneity − It refers to the uniformity or dissimilarity of the data models, system


components and databases.

Design Alternatives
The distribution design alternatives for the tables in a DDBMS are as follows −

• Non-replicated and non-fragmented


• Fully replicated
• Partially replicated
• Fragmented
• Mixed
Non-replicated & Non-fragmented
In this design alternative, different tables are placed at different sites. Data is placed so that it is at a
close proximity to the site where it is used most. It is most suitable for database systems where the
percentage of queries needed to join information in tables placed at different sites is low. If an
appropriate distribution strategy is adopted, then this design alternative helps to reduce the
communication cost during data processing.
Fully Replicated
In this design alternative, at each site, one copy of all the database tables is stored. Since, each site has
its own copy of the entire database; queries are very fast requiring negligible communication cost. On
the contrary, the massive redundancy in data requires huge cost during update operations. Hence, this
is suitable for systems where a large number of queries is required to be handled whereas the number
of database updates is low.

Partially Replicated
Copies of tables or portions of tables are stored at different sites. The distribution of the tables is done
in accordance to the frequency of access. This takes into consideration the fact that the frequency of
accessing the tables vary considerably from site to site. The number of copies of the tables (or portions)
depends on how frequently the access queries execute and the site which generate the access queries.

Fragmented
In this design, a table is divided into two or more pieces referred to as fragments or partitions, and each
fragment can be stored at different sites. This considers the fact that it seldom happens that all data
stored in a table is required at a given site. Moreover, fragmentation increases parallelism and provides
better disaster recovery. Here, there is only one copy of each fragment in the system, i.e. no redundant
data.

The three fragmentation techniques are −

• Vertical fragmentation
• Horizontal fragmentation
• Hybrid fragmentation
Mixed Distribution
This is a combination of fragmentation and partial replications. Here, the tables are initially fragmented
in any form (horizontal or vertical), and then these fragments are partially replicated across the
different sites according to the frequency of accessing the fragments.

Data Replication
Data replication is the process of storing separate copies of the database at two or more sites. It is a
popular fault tolerance technique of distributed databases.

Fragmentation
Fragmentation is the task of dividing a table into a set of smaller tables. The subsets of the table are
called fragments. Fragmentation can be of three types: horizontal, vertical, and hybrid (combination
of horizontal and vertical). Horizontal fragmentation can further be classified into two techniques:
primary horizontal fragmentation and derived horizontal fragmentation.
Fragmentation should be done in a way so that the original table can be reconstructed from the
fragments. This is needed so that the original table can be reconstructed from the fragments whenever
required. This requirement is called “reconstructiveness.”

Vertical Fragmentation
In vertical fragmentation, the fields or columns of a table are grouped into fragments. In order to
maintain reconstructiveness, each fragment should contain the primary key field(s) of the table.
Vertical fragmentation can be used to enforce privacy of data.

For example, let us consider that a University database keeps records of all registered students in a
Student table having the following schema.

STUDENT

Regd_No Name Course Address Semester Fees Marks

Now, the fees details are maintained in the accounts section. In this case, the designer will fragment
the database as follows −
CREATE TABLE STD_FEES AS
SELECT Regd_No, Fees
FROM STUDENT;

Horizontal Fragmentation
Horizontal fragmentation groups the tuples of a table in accordance to values of one or more fields.
Horizontal fragmentation should also confirm to the rule of re-constructiveness. Each horizontal
fragment must have all columns of the original base table.

For example, in the student schema, if the details of all students of Computer Science Course needs to
be maintained at the School of Computer Science, then the designer will horizontally fragment the
database as follows −

CREATE COMP_STD AS

SELECT * FROM STUDENT

WHERE COURSE = "Computer Science";

Hybrid Fragmentation
In hybrid fragmentation, a combination of horizontal and vertical fragmentation techniques are used.
This is the most flexible fragmentation technique since it generates fragments with minimal extraneous
information. However, reconstruction of the original table is often an expensive task.

Hybrid fragmentation can be done in two alternative ways −


• At first, generate a set of horizontal fragments; then generate vertical fragments from one or
more of the horizontal fragments.

• At first, generate a set of vertical fragments; then generate horizontal fragments from one or
more of the vertical fragments.
Experiment-08

Aim 8- Study of Amoeba Distributed System.


What is Amoeba?
Amoeba is a general-purpose distributed operating system. It is designed to take a collection of
machines and make them act together as a single integrated system. In general, users are neither aware
of the number and location of the processors that run their commands, nor of the number and location
of the file servers that store their files. To the casual user, an Amoeba system looks like a single old-
fashioned time-sharing system.
Amoeba is an ongoing research project. It should be thought of as a platform for doing research and
development in distributed and parallel systems, languages, protocols and applications. Although it
provides some UNIX emulation, and has a definite UNIX-like flavor (including over 100 UNIX-like
utilities), it is NOT a plug-compatible replacement for UNIX. It should be of interest to educators and
researchers who want the source code of a distributed operating system to inspect and tinker with, as
well as to those who need a base to run distributed and parallel applications. Amoeba is intended for
both ‘‘distributed’’ computing (multiple independent users working on different projects) and
‘‘parallel’’ computing (e.g., one user using 50 CPUs to play chess in parallel). Amoeba provides the
necessary mechanism for doing both distributed and parallel applications, but the policy is entirely
determined by user-level programs. For example, both a traditional (i.e. sequential) ‘make’ and a new
parallel ‘amake’ are supplied.
Design Goals
The basic design goals of Amoeba are:
Distribution—Connecting together many machines
Parallelism—Allowing individual jobs to use multiple CPUs easily
Transparency—Having the collection of computers act like a single system
Performance—Achieving all of the above in an efficient manner
Fundamental Concepts in Amoeba
The following sections briefly provide an introduction to Amoeba and some of its characteristics.
Microkernel + Server Architecture
Amoeba was designed with what is currently termed a microkernel architecture. This means that every
machine in an Amoeba system runs a small, identical piece of software called the kernel. The kernel
supports the basic process, communication, and object primitives. It also handles raw device I/O and
memory management. Everything else is built on top of these fundamentals, usually by user-space
server processes.
Threads
In many traditional operating systems, a process consists of an address space and a single thread of
control. In Amoeba, each process has its own address space, but it may contain multiple ‘‘threads of
control’’ (threads). Each thread has its own program counter and its own stack, but shares code and
global data with all the other threads in its process.
Remote Procedure Call
Threads often need to communicate with one another. Threads within a single process can just
communicate via the shared memory, but threads located in different processes need a different
mechanism. The basic Amoeba communication mechanism is the remote procedure call (RPC).
Communication consists of a client thread sending a message to a server thread, then blocking until the
server thread sends back a return message, at which time the client is unblocked.
Group Communication
For many applications, one-to-many communication is needed, in which a single sender wants to send
a message to multiple receivers. For example, a group of cooperating servers may need to do this when
a data structure is updated. It is also frequently needed for parallel programming. Amoeba provides a
basic facility for reliable, totally-ordered group communication, in which all receivers are guaranteed
to get all group messages in exactly the same order. This mechanism simplifies many distributed and
parallel programming problems.
Objects and Capabilities
There are two fundamental concepts in Amoeba: objects and capabilities. All services and
communication are built around them.
An object is conceptually an abstract data type. That is, an object is a data structure on which certain
operations are defined. For example, a directory is an object to which certain operations can be applied,
such as ‘‘enter name’’ and ‘‘look up name.’’ Amoeba primarily supports software objects, but hardware
objects also exist. Each object is managed by a server process to which RPCs can be sent. Each RPC
specifies the object to be used, the operation to be performed, and any parameters to be passed.
When an object is created, the server doing the creation constructs a 128-bit value called a capability
and returns it to the caller. Subsequent operations on the object require the user to send its capability to
the server to both specify the object and prove the user has permission to manipulate the object.
Capabilities are protected cryptographically to prevent tampering. All objects in the entire system are
named and protected using this one simple, transparent scheme.

Memory Management
The Amoeba memory model is simple and efficient. A process’ address space consists of one or more
segments mapped onto user-specified virtual addresses. When a process is executing, all its segments
are in memory. There is no swapping or paging at present, thus Amoeba can only run programs that fit
in physical memory. The primary advantage of this scheme is simplicity and high performance. The
primary disadvantage is that it is not possible to run programs larger than physical memory.
Input/Output
I/O is also handled by kernel threads. To read raw blocks from a disk, for example, a user process having
the appropriate authorization, does RPCs with a disk I/O thread in the kernel. The caller is not aware
that the server is actually a kernel thread, since the interface to kernel threads and user threads is
identical. Generally speaking, only file servers and similar system-like processes communicate with
kernel I/O threads.
Bullet File Server
The standard Amoeba file server has been designed for high performance and is called the Bullet server.
It stores files contiguously on disk, and caches whole files contiguously in core. Except for very large
files, when a user programs needs a file, it will request that the Bullet server send it the entire file in a
single RPC. A dedicated machine with at least 16 MB of RAM is needed for the Bullet file server for
installation (except on the Sun 3 where there is a maximum of 12 MB). The more RAM the better, in
fact. The performance is improved with a larger file cache. The maximum file size is also limited by
the amount of physical memory available to the Bullet server.
Machines on which Amoeba Runs
Amoeba currently runs on the following architecture

• Sun 4c and MicroSPARC SPARCstations


• Intel 386/486/Pentium/Pentium Pro (IBM AT bus, PCI bus)
• 68030 VME-bus boards (Force CPU-30)
• Sun 3/60 & Sun 3/50 workstations

You might also like