Вы находитесь на странице: 1из 16

1 The Dining Philosophers Problem

1.1 Aim

Solve Dining Philosophers Problem using semaphores

1.2 Dining Philosophers Problem

The Dining Philosophers problems is a classic synchronization problem (E. W. Dijkstra. Co-operating Sequential Processes. In F. Genuys (ed.) Pro- gramming Languages, Academic Press, London, 1965) introducing semaphores

as a conceptual synchronization mechanism. There is a dining room contain-

ing a circular table with ﬁve chairs. At each chair is a plate, and between each plate is a single chopstick. In the middle of the table is a bowl of spaghetti. Near the room are ﬁve philosophers who spend most of their time thinking, but who occasionally get hungry and need to eat so they can think some more. In order to eat, a philosopher must sit at the table, pick up the two chopsticks to the left and right of a plate, then serve and eat the spaghetti on the plate. Thus, each philosopher is represented by the following pseudocode:

process P[ i ] while true do { THINK; PICKUP(CHOPSTICK[ i ] , EAT; PUTDOWN(CHOPSTICK[ i ] ,

}

CHOPSTICK[ i +1 mod

CHOPSTICK[ i +1 mod

5 ] )

;

5 ] )

A philosopher may THINK indeﬁnately. Every philosopher who EATs will

eventually ﬁnish. Philosophers may PICKUP and PUTDOWN their chop- sticks in either order, or nondeterministically, but these are atomic actions, and, of course, two philosophers cannot use a single CHOPSTICK at the same time. The problem is to design a protocol to satisfy the liveness condition: any philosopher who tries to EAT, eventually does.

1

1.3 Tannenbaum’s Solution

This solution uses only boolean semaphors. There is one global semaphore to provide mutual exclusion for exectution of critical protocols. There is one semaphore for each chopstick. In addition, a local two-phase prioritization scheme is used, under which philosophers defer to their neighbors who have declared themselves ”hungry.” All arithmetic is modulo 5.

system DINING PHILOSOPHERS

 VAR me: s [ 5 ] : semaphore , semaphore n i t i a s [ 5 ] i l l y 1 ; i n i t i a l l y 0; /∗ /∗ f o r for mutual synchronization e x c l u s i o pf l a g [ 5 ] : , {THINK, HUNGRY, EAT} , i n i t i a l l y THINK; /∗ p hil o s o p h e r f l a g ∗ As befor e , each p hil o s o p h e r i s an e n d l e s s c y c l e of t hi n ki n g and e a ti n g .

procedure

{

philosopher ( i )

w hil e TRUE do

{

THINKING; take chopsticks ( i ) ; EATING; drop chopsticks ( i ) ;

}

}

The take chopsticks procedure involves checking the status of neighboring philosophers and then declaring one’s own intention to eat. This is a two- phase protocol; ﬁrst declaring the status HUNGRY, then going on to EAT.

procedure

{

take chopsticks ( i )

 DOWN(me ) ; /∗ c r i t i c a l s e c t i o n ∗/ pf l a g [ i ] := HUNGRY; te st [ i ] ; UP(me ) ; /∗ end c r i t i c a l s e c t i o n ∗/

2

 DOWN( s [ i ] ) / ∗ Eat i f enabled ∗ / } void te st ( i ) /∗ Let phil [ i ] eat , i f waiting ∗/

{

 i f ( pf l a g [ i ] == HUNGRY && pf l a g [ i − 1] != EAT && pf l a g [ i +1] != EAT) then { pf l a g [ i ] := EAT; UP( s [ i ] ) } }

Once a philosopher ﬁnishes eating, all that remains is to relinquish the resources—its two chopsticks—and thereby release waiting neighbors.

void

{

drop chopsticks ( int

i )

 DOWN(me ) ; /∗ c r i t i c a l s e c t i o n ∗/ t e s t ( i −1); /∗ Let phil . on l e f t eat i f p o s s i b l e ∗/ t e s t ( i +1); /∗ Let phil . on rght eat i f p o s s i b l e ∗/ UP(me ) ; /∗ up c r i t i c a l s e c t i o n ∗/

}

The protocol is fairly elaborate, and Tannenbaum’s presentation is made more subtle by its coding style.

3

OS Lab

Bankers Algorithm

Aim

Implementation of Bankers Algorithm

Theory

The Banker's algorithm, sometimes referred to as the avoidance algorithm, is a resource allocation and deadlock avoidance algorithm that tests for safety by simulating the allocation of predetermined maximum possible amounts of all resources, and then makes an "s-state" check to test for possible deadlock conditions for all other pending activities, before deciding whether allocation should be allowed to continue.

When a new process enters a system, it must declare the maximum number of instances of each resource type that it may ever claim; clearly, that number may not exceed the total number of resources in the system. Also, when a process gets all its requested resources it must return them in a finite amount of time.

Let n be the number of processes in the system and m be the number of resource types. Then

we need the following data structures:

Available: A vector of length m indicates the number of available resources of each
type. If Available[j] = k, there are k instances of resource type R​ j​ .
Max: An ​n×​m matrix defines the maximum demand of each process. If Max[i,j] = k,
then P​ i​ may request at most k instances of resource type R​ j​ .
Allocation: An ​n×​m matrix defines the number of resources of each type currently
allocated to each process. If Allocation[i,j] = k, then process P​ i​ is currently allocated k
instances of resource type R​ j​ .
Need: An ​n×​m matrix indicates the remaining resource need of each process. If

Need[i,j] = k, then Pi may need k more instances of resource type Rj to complete the

Note: Need[i,j] = Max[i,j] - Allocation[i,j].

Allocationi specifies the resources currently allocated to process Pi and Needi specifies the additional

resources that process Pimay still request to complete its task.

Banker’s algorithm consist of Safety algorithm and Resource request algorithm

Safety Algorithm

The algorithm for checking whether a system is in safe state or not is as follows

1. Initialize work = available

Finish[i] = false for 1

n

2. Find an i such that both

a. Finish[i] = false

b. need[i]<=work

If no such i exists go to 4

3. Work = work + allocation[i] Finish[i] =true Goto 2

4. If finish[i]= true for all i then system is in safe state

Resource Request algorithm

Let Requestibe the request array for process Pi. Requesti [j] = k means process Piwants k instances of resource type Rj. When a request for resources is made by process Pi, the following actions are taken:

1. If request[i] <=need[i] Goto 2, otherwise raise error

2. If request[i] <=available Goto 3 otherwise process must wait

3. Available = available - request Allocation[i] = allocation[i] + request Need[i] = need[i] - request[i]

1 File System Statistics

1.1 Name

statvfs, fstatvfs - get ﬁle system statistics

1.2 Synopsis

#include sys/statvfs.h int statvfs(const char *path, struct statvfs *buf); int fstatvfs(int fd, struct statvfs *buf);

1.3 Description

The function statvfs() returns information about a mounted ﬁle system. path is the pathname of any ﬁle within the mounted ﬁle system. buf is a pointer to a statvfs structure deﬁned approximately as follows:

struct

s t a t v f s

{

 unsigned unsigned long f b s i z e ; /∗ f i l e system block s i z e ∗/ long f f r s i z e ; /∗ fragment s i z e ∗/ f s b l k c n t t f b l o c k s ; /∗ s i z e of f s in f f r s i z e units ∗/ f s b l k c n t t f b f r e e ; /∗ # f r e e blocks ∗/ f s b l k c n t t f b a v a i l ; /∗ # f r e e blocks for unprivileged user f s f i l c n t t f f i l e s ; /∗ # inodes ∗/ f s f i l c n t t f f f r e e ; /∗ # inodes ∗/ s f i l c n t unsigned unsigned un signed f t long f a v a i l ; f s i d ; f l a g ; f namemax ; f f f /∗ /∗ # f r e e f r e e inodes ID for ∗/ unprivileged user long /∗ f i l e mount system f l a g s ∗/ lo ng /∗ maximum fil e n am e l e n g t h ∗/

};

Here the types fsblkcnt t and fsﬁlcnt t are deﬁned in “sys/types.h ” Both used to be unsigned long. The ﬁeld f ﬂag is a bit mask . Bits deﬁned by POSIX are ST RDONLY : Read-only ﬁle system. ST NOSUID : Set-user-ID/set-group-ID bits are ignored by exec(3). It is unspeciﬁed whether all members of the returned struct have meaningful values on all ﬁle systems.

1

fstatvfs() returns the same information about an open ﬁle referenced by descriptor fd.

1.4 Return Value

On success, zero is returned. appropriately.

On error, -1 is returned, and errno is set

1.5 Errors

1.5.1 EACCES

(statvfs()) Search permission is denied for a component of the path preﬁx of path.

(fstatvfs()) fd is not a valid open ﬁle descriptor.

1.5.3 EFAULT

Buf or path points to an invalid address.

1.5.4 EINTR

This call was interrupted by a signal.

1.5.5 EIO

An I/O error occurred while reading from the ﬁle system.

1.5.6 ELOOP

(statvfs()) Too many symbolic links were encountered in translating path.

1.5.7 ENAMETOOLONG

(statvfs()) path is too long.

2

1.5.8 ENOENT

(statvfs()) The ﬁle referred to by path does not exist.

1.5.9 ENOMEM

Insuﬃcient kernel memory was available.

1.5.10 ENOSYS

The ﬁle system does not support this call.

1.5.11 ENOTDIR

(statvfs()) A component of the path preﬁx of path is not a directory.

1.5.12 EOVERFLOW

Some values were too large to be represented in the returned struct.

3

SMTP using UDP

1.1 SMTP (Simple Mail Transfer Protocol)

SMTP (Simple Mail Transfer Protocol) is a TCP/IP protocol used in sending and receiving e-mail. However, since it is limited in its ability to queue messages at the receiving end, it is usually used with one of two other protocols, POP3 or IMAP, that let the user save messages in a server mailbox and download them periodically from the server. In other words, users typically use a program that uses SMTP for sending e-mail and either POP3 or IMAP for receiving e-mail. On Unix-based systems, sendmail is the most widely-used SMTP server for e-mail.

1.2 UDP (User Datagram Protocol)

UDP (User Datagram Protocol) is an alternative communications protocol to Transmission Control Protocol (TCP) used primarily for establishing low-latency and loss tolerating connections between applications on the Internet.

1.2.1 Steps involved in UDP programming:

1. Create a socket:

if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { perror("cannot create socket"); return 0;

}

2. Name a socket:

#include <sys/socket.h>

/* bind to an arbitrary return address */ /* because this is the client side, we don't care about the address */ /* since no application will initiate communication here - it will */ /* just send responses */ /* INADDR_ANY is the IP address and 0 is the socket */ /* htonl converts a long integer (e.g. address) to a network representation */ /* htons converts a short integer (e.g. port) to a network representation */

return 0;

 } 3. Send message from server to client:

#include <sys/types.h> #include <sys/socket.h> sendto(int socket, const void *buffer, size_t length, int flags, const struct sockaddr *dest_addr, socklen_t dest_len)

The first parameter, socket, is the socket that was created with the socket system call and named via bind. The second parameter, buffer, provides the starting address of the message we want to send. length is the number of bytes that we want to send. The flags parameter is 0 and not useful for UDP sockets. The dest_addr defines the destination address and port number for the message. It uses the same sockaddr_in structure that we used in bind to identify our local address. As with bind, the final parameter is simply the length of the address structure: sizeof(struct sockaddr_in).

#include <sys/socket.h> recvfrom(int socket, void *restrict buffer, size_t length, int flags, struct sockaddr *restrict src_addr, socklen_t *restrict *src_len)

The first parameter, socket is a socket that we created ahead of time (and used bind. The port number assigned to that socket via the bind call tells us on what port recvfrom will wait for data. The incoming data will be placed into the memory at buffer and no more than length bytes will be transferred (that's the size of your buffer). We will ignore flags here. You can look at the man page forrecvfrom for details on this. This parameter allows us to process out-of-band data, peek at an incoming message without removing it from the queue, or block until the request is fully satisfied. We can safely ignore these and use 0. The src_addr parameter is a pointer to a sockaddr structure that you allocate and will be filled in by recvfrom to identify the sender of the message. The length of this structure will be stored in src_len. If you do not care to identify the sender, you can set both of these to zero but you will then have no way to reply to the sender.

5. Close socket:

With TCP sockets, we saw that we can use the shutdown system call to close a socket or to terminate communication in a single direction. Since there is no concept of a connection in UDP, there is no need to call shutdown. However, the socket still uses up a file descriptor in the kernel, so we can free that up with the close system call just as we do with files.

close(fd);

FTP Using TCP

The File Transfer Protocol (FTP) is a standard network protocol used to transfer computer files between a client and server on a computer network. FTP is built on a client-server model architecture and uses separate control and data connections between the client and the server.[1] FTP users may authenticate themselves with a clear-text sign-in protocol, normally in the form of a username and password, but can connect anonymously if the server is configured to allow it. For secure transmission that protects the username and password, and encrypts the content, FTP is often secured with SSL/TLS (FTPS). SSH File Transfer Protocol (SFTP) is sometimes also used instead, but is technologically different.

File transfer TCP Algorithm

Server side Filer Transfer TCP Algorithm STEP 1: Start the program. STEP 2: Declare the variables and structure for the socket. STEP 3: Create a socket using socket functions STEP 4: The socket is binded at the specified port. STEP 5: Using the object the port and address are declared. STEP 6: After the binding is executed the file is specified. STEP 7: Then the file is specified. STEP 8: Execute the client programming

Client File Transfer TCP programming Algorithm

STEP 1: Start the program. STEP 2: Declare the variables and structure. STEP 3: Socket is created and connects function is executed. STEP 4: If the connection is successful then server sends the message. STEP 5: The file name that is to be transferred is specified in the client side. STEP 6: The contents of the file is verified from the server side. STEP 7: Stop the program

Simulation of Sliding Window Protocol

Aim:

1. Simulate Stop and wait sliding window protocol

2. Simulate Go Back N sliding window protocol

3. Simulate Selective Repeat sliding window protocol

Theory:

A sliding window protocol is a feature of packet-based data transmission​ ​protocols.Sliding

window protocols are used where reliable in-order delivery of packets is required, Eg: in TCP.

Each portion of the transmission is assigned a unique consecutive sequence number, and the receiver uses the numbers to place received packets in the correct order, discard duplicate packets and identify missing ones. The problem with this is that there is no limit on the size of the sequence number that can be required.

By placing limits on the number of packets that can be transmitted or received at any given time,

a sliding window protocol allows an unlimited number of packets to be communicated using

fixed-size sequence numbers. The term "window" on the transmitter side represents the logical boundary of the total number of packets yet to be acknowledged by the receiver. The receiver informs the transmitter in each acknowledgment packet the current maximum receiver buffer size (window boundary).

Stop And Wait

In stop and wait ARQ, the sliding window size is limited to one, i.e a packet is transmitted only

after the acknowledgement for the previous packet is received, else the sender will retransmit the packet till an acknowledgment is received.

The following transitions occur:

The sender maintains a timeout counter.

When a frame is sent, the sender starts the timeout counter.

If acknowledgement of frame comes in time, the sender transmits the next

frame in queue.

If acknowledgement does not come in time, the sender assumes that either the

frame or its acknowledgement is lost in transit. Sender retransmits the frame

and starts the timeout counter.

If a negative acknowledgement is received, the sender retransmits the frame.

Go Back N ARQ

Stop and Wait ARQ

Stop and wait ARQ mechanism does not utilize the resources at their best.When the acknowledgement is received, the sender sits idle and does nothing. In Go-Back-N ARQ method, both sender and receiver maintain a window.

Go Back N ARQ

The sending-window size enables the sender to send multiple frames without receiving the acknowledgement of the previous ones. The receiving-window enables the receiver to receive multiple frames and acknowledge them. The receiver keeps track of incoming frame’s sequence number.

When the sender sends all the frames in window, it checks up to what sequence number it has received positive acknowledgement. If all frames are positively acknowledged, the sender sends next set of frames. If sender finds that it has

received NACK or has not receive any ACK for a particular frame, it retransmits all

the frames after which it does not receive any positive ACK.

Selective Repeat ARQ

In Go-back-N ARQ, it is assumed that the receiver does not have any buffer space for its window size and has to process each frame as it comes. This enforces the sender to retransmit all the frames which are not acknowledged.

Selective Repeat ARQ

In Selective-Repeat ARQ, the receiver while keeping track of sequence numbers, buffers the frames in memory and sends NACK for only frame which is missing or damaged.

The sender in this case, sends only packet for which NACK is received.