Anda di halaman 1dari 90

17CS2208 (R)- Operating Systems Lab

LAB – I

Pre-lab:

Whatis command is helpful to get brief information about Linux commands or functions. Whatis
command displays man page single line description for command that matches string passed as
a command line argument to whatis command. man command, short for manual, provides help
for the commands, utilities or function in Linux and Unix systems. If you are new to Unix and
Linux system and looking for help command in Unix or info command in Linux to get started,
man command is the answer.

os@klu:~$ whatis man


man (1) - an interface to the on-line reference manuals
man (7) - macros to format man pages

os@klu:~$ whatis ls
ls (1) - list directory contents

os@klu:~$ whatis echo


echo (1) - display a line of text

os@klu:~$ whatis date


date (1) - print or set the system date and time
os@klu:~$ whatis cal
cal (1) - displays a calendar and the date of Easter

os@klu:~$ whatis who


who (1) - show who is logged on

os@klu:~$ whatis uname


uname (1) - print system information
uname (2) - get name and information about current kernel

os@klu:~$ whatis pwd


pwd (1) - print name of current/working directory

os@klu:~$ whatis mount


mount (8) - mount a filesystem
mount (2) - mount filesystem

os@klu:~$ whatis umount


umount (8) - unmount file systems
umount (2) - unmount filesystem

os@klu:~$ whatis cat


cat (1) - concatenate files and print on the standard output

os@klu:~$ whatis more


more (1) - file perusal filter for crt viewing

os@klu:~$ whatis less


less (1) - opposite of more

os@klu:~$ whatis grep


grep (1) - print lines matching a pattern

os@klu:~$ whatis diff


diff (1) - compare files line by line

os@klu:~$ whatis ln
ln (1) - make links between files

os@klu:~$ whatis rm
rm (1) - remove files or directories

os@klu:~$ whatis mv
mv (1) - move (rename) files
os@klu:~$ whatis cp
cp (1) - copy files and directories

os@klu:~$ whatis mkdir


mkdir (1) - make directories
mkdir (2) - create a directory

os@klu:~$ whatis chmod


chmod (1) - change file mode bits
chmod (2) - change permissions of a file

os@klu:~$ whatis touch


touch (1) - change file timestamps

os@klu:~$ whatis gzip


gzip (1) - compress or expand files

os@klu:~$ whatis tar


tar (1) - an archiving utility

os@klu:~$ whatis find


find (1) - search for files in a directory hierarchy
os@klu:~$ whatis ping
ping (8) - send ICMP ECHO_REQUEST to network hosts

os@klu:~$ whatis traceroute


lft.db (1) - print the route packets trace to network host
tcptraceroute.db (8) - print the route packets trace to network host

os@klu:~$ whatis telnet


telnet (1) - user interface to the TELNET protocol

os@klu:~$ whatis nslookup


nslookup (1) - query Internet name servers interactively

os@klu:~$ whatis df
df (1) - report file system disk space usage

os@klu:~$ whatis du
du (1) - estimate file space usage

os@klu:~$ whatis free


free (1) - Display amount of free and used memory in the system
free (3) - allocate and free dynamic memory
os@klu:~$ whatis top
top (1) - display Linux processes

os@klu:~$ whatis ps
ps (1) - report a snapshot of the current processes.

os@klu:~$ whatis kill


kill (1) - send a signal to a process
kill (2) - send signal to a process

os@klu:~$ whatis killall


killall (1) - kill processes by name
In-lab:
Post-lab:
LAB – II

Pre-lab:

2. Write a C program that reads line by line in myfile.txt and prints the first 10-digit number in the
given file (digits should be continuous), If not found then print first 10 characters excluding
numbers.
/*

Write a C program that reads line by line in myfile.txt and prints the first 10-digit

number in the given file (digits should be continuous), If not found then print first 10

characters excluding numbers.

*/

#include <stdio.h>

int main()

//Reading the file

FILE *fp = fopen("myfile.txt" , "r");

int count;

int c=0;

while(1)

count = 0;

for(int i=0;i<10;i++){

c = getc(fp);

if( c == -1)

break;

if(c>='0' && c<='9')

count++;
}

if(c == -1)

break;

if(count==10){

char s[10];

fseek(fp,-10,SEEK_CUR);

fgets(s,11,fp);

printf("%s",s);

break;

fseek(fp,-9,SEEK_CUR);

if (count!=10)

rewind(fp);

for(int i=0;i<10;)

c = getc(fp);

if(c>='0' && c<='9')

continue;

printf("%c",c);

i++;

return 0;

}
3. Write a C program that saves 10 random numbers to a file, using own “rand.h” header file which
contains your own random( ) function.

rand.h
#include <stdlib.h>

int ownrand(){

return rand()%10;

main.c

#include <stdio.h>

#include <time.h>

#include "rand.h"

int main()

srand(time(0));

FILE *fptr;

fptr = fopen("random.txt","w");

for (int i = 0; i < 10; ++i)

fprintf(fptr, "%d", ownrand()%10);

fprintf(fptr, "\n");

return 0;

}
In-lab:

2. As part of the tradition, Treasure Hunt is played in Hogwarts school of witchcraft and wizardry by
all the houses. By decoding all the hints, Gryffindor has reached the final level, the rest were
knocked out. Gryffindors have obtained the Treasure, to unlock the treasure they must perform the
following operations using UNIX system calls (open, close, read, write): a) Open and Read the file
/etc/passwd, write all the contents of file to crypt.txt (In pwd).
b) Close the file (/etc/passwd).
c) Using lseek go to the last line of crypt.txt.
d) Store the first 12 characters of last line to a file decrypt.txt
e) Display the contents of decrypt.txt

The contents of decrypt.txt is the key to unlock the treasure.-


/*

As part of the tradition, Treasure Hunt is played in Hogwarts school of witchcraft and

wizardry by all the houses. By decoding all the hints, Gryffindor has reached the final

level, the rest were knocked out. Gryffindors have obtained the Treasure, to unlock

the treasure they must perform the following operations using UNIX system calls

(open, close, read, write):

a) Open and Read the file /etc/passwd, write all the contents of file to crypt.txt

(In pwd).

b) Close the file (/etc/passwd).

c) Using lseek go to the last line of crypt.txt.

d) Store the first 12 characters of last line to a file decrypt.txt

e) Display the contents of decrypt.txt

The contents of decrypt.txt is the key to unlock the treasure.

*/

#include <fcntl.h>

#include <stdio.h>

#include <unistd.h>

#include <sys/stat.h>
int main(){

char buf;

int c;

//Opening passwd file

int fd1 = open("/etc/passwd", O_RDONLY);

// Creating crypt.txt

int fd2 = open("crypt.txt", O_CREAT | O_WRONLY |O_TRUNC , S_IRUSR | S_IWUSR | S_IRGRP |


S_IROTH);

//Copying all the contents of passswd to crypt.txt

while(1){

if(read(fd1,&buf,1)!=0)

write(fd2,&buf,1);

else

break;

close(fd1);

close(fd2);

fd1 = open("crypt.txt",O_RDONLY);

// creating decrypt.txt

fd2 = open("decrypt.txt",O_CREAT | O_WRONLY |O_TRUNC , S_IRUSR | S_IWUSR | S_IRGRP |


S_IROTH);

//Going to the end of crypt.txt

lseek(fd1,-2,SEEK_END);

read(fd1,&buf,1);

printf("%c",buf);

while(buf != '\n'){

lseek(fd1,-2,SEEK_CUR);

read(fd1,&buf,1);

}
//saving the 12 characters to decrypt.txt

char s[12];

read(fd1,s,12);

write(fd2,s,12);

close(fd1);

close(fd2);

fd1 = open("decrypt.txt", O_RDONLY);

while(1){

if(read(fd1,&buf,1)!=0)

write(1,&buf,1);

else

break;

return 0;

3. Write a UNIX system program that will perform copy data from one file to other file with error
handling. Both file names to the program should be given as command line arguments.

#include<unistd.h>

#include<sys/types.h>

#include<sys/stat.h>

#include<fcntl.h>

#include <stdio.h>

#include<stdlib.h>

int main( int argc,char *argv[] )

char buf;
int sourcefile,destfile,n;

if(argc!=3)

write(STDOUT_FILENO,"Invalid arguments \nprogram <sourcefile> <destination file>\n",58);

exit(1);

else

sourcefile=open(argv[1],O_RDONLY);

if(sourcefile==-1)

perror("SOURCE FILE ERROR");

exit(1);

else

destfile=open(argv[2],O_WRONLY | O_CREAT , 0641);

if(destfile==-1)

perror("DESTINATION FILE ERROR");

exit(1);

else

n=read(sourcefile,&buf,1);

while(n != 0 && n != -1 )

write( destfile, &buf, 1 );

n=read(sourcefile,&buf,1);
}

write(STDOUT_FILENO, "FILES COPIED\n" , 15);

close(sourcefile);

close(destfile);

return 0;

}
Post-lab:

1) Write a UNIX system program that creates a file with a hole in it.
#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <stdio.h>

#include <unistd.h>

#include <stdlib.h>

char buf1[] = "abcdefghij";

char buf2[] = "ABCDEFGHIJ";

int main(void)

int fd;

if ((fd = creat("file.hole", 777)) < 0)

perror("creat error");

if (write(fd, buf1, 10) != 10)

perror("buf1 write error");

/* offset now = 10 */

if (lseek(fd, 16384, SEEK_SET) == -1)

perror("lseek error");

/* offset now = 16384 */

if (write(fd, buf2, 10) != 10)

perror("buf2 write error");

/* offset now = 16394 */

exit(0);

}
/*

$ ./a.out

#(check its size)

$ ls -l file.hole

-rw-r--r-- 1 sar 16394 Nov 25 01:01 file.hole

#(let’s look at the actual contents)

$ od -c file.hole

Both files are the same size, the file without holes consumes 20 disk blocks,

whereas the file with holes consumes only 8 blocks

*/

2) Write a program using system calls to write in reverse order of all the contents of file
(/etc/passwd) to reverse.txt. Show a pictorial arrangement of File Descriptor, File and Inode tables
for a single process that has two different files open.

/*

Write a program using system calls to write in reverse order of all the contents of file

(/etc/passwd) to reverse.txt. Show a pictorial arrangement of File Descriptor, File and Inode

tables for a single process that has two different files open.

*/

#include <fcntl.h>

#include <unistd.h> /* For STDOUT_FILENO */

#include <stdio.h>

#include <stdlib.h>
int main(int argc, char **argv) {

int size, fd;

char buf;

int fd1 = open("reverse.txt",O_WRONLY | O_CREAT | O_TRUNC, 0777);

if ((fd = open(argv[1], O_RDONLY)) == -1){

perror("open");

exit(2);

lseek(fd, 1, SEEK_END); /* Pointer taken to EOF + 1 first */

while (lseek(fd, -2, SEEK_CUR) >= 0) { /* and then back by two bytes */

if (read(fd, &buf, 1) != 1){

perror("read");

exit(1);

if (write(fd1, &buf, 1) != 1){

perror("write");

exit(1);

close(fd); /* Can have error here too */

close(fd1);

exit(0); /* exit doesn't return - hence no error */

3) Write a program using system calls to print the content of the file (/etc/passwd) onto the
console.
/*

Write a program using system calls to print the content of the file (/etc/passwd) onto the

console.
*/

#include <fcntl.h>

#include <unistd.h> /* For STDOUT_FILENO */

#include <stdio.h>

#include <stdlib.h>

int main(int argc, char **argv) {

int size, fd;

char buf; /* Single-character buffer */

if ((fd = open(argv[1], O_RDONLY)) == -1){

perror("open");

exit(2);

while ((read(fd, &buf, 1) >0)) { /* and then back by two bytes */

if (write(STDOUT_FILENO, &buf, 1) != 1){

perror("write");

exit(1);

close(fd); /* Can have error here too */

exit(0); /* exit doesn't return - hence no error */

}
LAB – III

Pre-lab:
2. The process obtains its own PID and its parent’s PID using the getpid and getppid system calls. The
program also prints the effective UID and GID, which normally are equal to the real UID and GID. Write a
UNIX system program that prints PID, PPID, real and effective UIDs and GIDs and fetches and sets PATH

/*

The process obtains its own PID and its parent’s PID using the getpid and getppid system

calls. The program also prints the effective UID and GID, which normally are equal to the

real UID and GID. Write a UNIX system program that prints PID, PPID, real and effective

UIDs and GIDs and fetches and sets PATH

*/

#include<stdio.h>

#include<stdlib.h>

#include<string.h>

int main(){

pid_t p;

printf("This process is %d\n",getpid());

printf("This real user ID is %d\n",getuid());

printf("This effective user ID is %d\n",geteuid());

printf("Real group ID: %d\n",getgid());

printf("Effective group ID: %d\n",getegid());

if(fork()==0){

printf("This process is %d\n",getpid());

printf("This real user ID is %d\n",getuid());

printf("This effective user ID is %d\n",geteuid());

printf("Real group ID: %d\n",getgid());

printf("Effective group ID: %d\n",getegid());


printf("PATH : %s\n",getenv("PATH"));

char *s=strdup(getenv("PATH"));

setenv("PATH","sumanth",1);

printf("PATH : %s\n",getenv("PATH"));

setenv("PATH",s,1);

printf("PATH : %s\n",getenv("PATH"));

}
In-lab:

1. Minni has a document named "Mickey" which contains the verses of a song. She is interested to
know the count of words and lines of the song. She utilizes Linux directions and system calls, in
order to accomplish her objective. Help Minni to finish her assignment by utilizing fork system call.
The parent process tallies the no.of lines utilizing execvp() and the child procedure checks the
aggregate no.of words in the song. Display the check of words pursued by the tally of lines utilizing
wait(). Demonstrate the child’s various exit status. Show a pictorial arrangement - Sharing of open
files between parent and child after fork

#include <unistd.h>

#include <stdio.h>

#include<stdlib.h>

#include <sys/stat.h>

#include<wait.h>

#include <fcntl.h>

int main()

char* pcomm[] = {"wc","-l","Mickey",NULL};

char* ccomm[] = {"wc","-w","Mickey",NULL};

switch(fork())

case -1:

perror("fork");

exit(1);

case 0:

//child

if(execvp("wc",ccomm)<0)

printf(" execvp error in child\n");

exit(2);
break;

default:

if(execvp("wc",pcomm)<0)

printf(" execvp error in parent\n");

exit(3);

break;

2. Write a program to execute a given command and show the usage of dup2 function in a way that
instead of printing on monitor, redirecting the output to a file named "Lab3.txt"

/*

Write a program to execute a given command and show the usage of dup2 function in

a way that instead of printing on monitor, redirecting the output to a file named

"Lab3.txt"

*/

#include <unistd.h>

#include <stdio.h>

#include<stdlib.h>

#include <sys/stat.h>

#include<wait.h>

#include <fcntl.h>

int main(int argc, char **argv)

if(argc > 1 ){

if(fork()==0){

int fd = open("Lab3.txt",O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR);
dup2(fd,1);

execvp(argv[1], &argv[1]); //ls

perror("exec error");

exit(2);

else{

int rv;

wait(&rv);

printf("Exit status: %d\n", WEXITSTATUS(rv));

exit(0);

else{

perror("Error Provide arguments\n");

}
Post-lab:

1. Write a program redirection.c that achieves the effect of redirection without using the < and >
symbols. Child opens files and uses dup2 to reassign the descriptors and execute a command line.
Note: The first two arguments are input and output filenames. The command line to execute is
specified as the remaining arguments.

Redirection:
#include <unistd.h>

#include <stdio.h>

#include<stdlib.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <wait.h>

int main(int argc, char **argv) {

int fd1, fd2, rv, exit_status;

if (fork() == 0) { /* Child */

if ((fd1 = open(argv[1], O_RDONLY)) == -1)

perror("Error in opening file for reading\n");

exit(1);

if ((fd2 = open(argv[2],O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR)) == -1)

perror("Error in opening file for writing\n");

exit(1);

dup2(fd1,0);

dup2(fd2,1);

execvp(argv[3], &argv[3]); /* Uses PATH */


perror("exec error");

exit(2);

else { /* Parent */

wait(&rv);

printf("Exit status: %d\n", WEXITSTATUS(rv));

exit(0);

2. Write a UNIX system program to create zombie (by letting parent sleep & child dies) and orphan
process (by letting child sleep for 2 minutes Parent doesn't call wait and dies immediately).
Zombie

#include <stdlib.h>

#include <sys/types.h>

#include <unistd.h>

int main()

// fork() creates child process identical to parent

int pid = fork();

// if pid is greater than 0 than it is parent process

// if pid is 0 then it is child process

// if pid is -ve , it means fork() failed to create child process

// Parent process

if (pid > 0)

sleep(20);
// Child process

else

exit(0);

return 0;

2_2)

#include <stdio.h>

#include <sys/types.h>

#include <unistd.h>

int main()

// fork() Create a child process

int pid = fork();

if (pid > 0)

//getpid() returns process id

// while getppid() will return parent process id

printf("Parent process\n");

printf("ID : %d\n\n",getpid());

else if (pid == 0)

printf("Child process\n");
// getpid() will return process id of child process

printf("ID: %d\n",getpid());

// getppid() will return parent process id of child process

printf("Parent -ID: %d\n\n",getppid());

sleep(0);

// At this time parent process has finished.

// So if u will check parent process id

// it will show different process id

printf("After parent dies\n");

printf("\nChild process \n");

printf("ID: %d\n",getpid());

printf("Parent -ID: %d\n",getppid());

else

printf("Failed to create child process");

return 0;

}
LAB – IV

Pre-lab:

1. Write a C program using spin() function to understand that loops and prints a certain string value.
And also run it with multiple instances (of the same program) to demonstrate virtualizing the CPU
use gettimeofday() library function.

#include <stdio.h>

#include <stdlib.h>

#include <assert.h>

double GetTime() {

struct timeval t;

int rc = gettimeofday(&t, NULL);

assert(rc == 0);

return (double)t.tv_sec + (double)t.tv_usec/1e6;

void Spin(int howlong) {

double t = GetTime();

while ((GetTime() - t) < (double)howlong); // do nothing in loop

int main(int argc, char *argv[])

if (argc != 2) {

fprintf(stderr, "usage: cpu <string>\n");

exit(1);
}

char *str = argv[1];

while (1) {

printf("%s\n", str);

Spin(1);

return 0;

2. xv6 is a re-implementation of Dennis Ritchie's and Ken Thompson's Unix Version 6 (v6). xv6 loosely
follows the structure and style of v6, but is implemented for a modern x86-based multiprocessor using
ANSI C. Adding a system call in XV6 OS: Show you how to add a system call to XV6 OS. Add a simple
helloworld system call which will print hello world and the argument passed to the system call.
In-lab:

1) Zabih the Prime Minister of Honolulu is very strict regarding the taxation policy in his country. On the
very first day of his tenure as the Prime Minister he formed a committee of his council of ministers
belonging to different regions. This committee members followed by had a group of well talented tax
officers who would look out at the working of the tax department.

a) The Prime Minister got an anonymous tip that certain people in the administration were practicing
unethical means to evade taxes.
b) The Prime Minister ordered the Chief of Police to question all of them and find the culprit.
c) Now, in order to call all of them for questioning, one needs to know the addresses of all the workforce
working under the tax department.
d) Help the police department to gather the information regarding the addresses of the workforce.
e) Here, the council of ministers are a segment of the taxation norm and the officers working under
them can be considered as different variables for the tax department.
f) Write a UNIX system program to print all the addresses of all the segments and the addresses of the
variables residing in their respective segments.

#include <stdio.h>

#include <malloc.h> /* for definition of ptrdiff_t on GLIBC */

#include <unistd.h>

#include <alloca.h> /* for demonstration only */

extern void afunc(void); /* a function for showing stack growth */

int bss_var; /* auto init to 0, should be in BSS */

int data_var = 42; /* init to nonzero, should be data */

int

main(int argc, char **argv) /* arguments aren't used */

char *p, *b, *nb;

printf("Text Locations:\n");
printf("\tAddress of main: %p\n", main);

printf("\tAddress of afunc: %p\n", afunc);

printf("Stack Locations:\n");

afunc();

p = (char *) alloca(32);

if (p != NULL) {

printf("\tStart of alloca()'ed array: %p\n", p);

printf("\tEnd of alloca()'ed array: %p\n", p + 31);

printf("Data Locations:\n");

printf("\tAddress of data_var: %p\n", & data_var);

printf("BSS Locations:\n");

printf("\tAddress of bss_var: %p\n", & bss_var);

b = sbrk((ptrdiff_t) 32); /* grow address space */

nb = sbrk((ptrdiff_t) 0);

printf("Heap Locations:\n");

printf("\tInitial end of heap: %p\n", b);

printf("\tNew end of heap: %p\n", nb);

b = sbrk((ptrdiff_t) -16); /* shrink it */

nb = sbrk((ptrdiff_t) 0);

printf("\tFinal end of heap: %p\n", nb);

/* infinite loop */
while (1) {}

void

afunc(void)

static int level = 0; /* recursion level */

auto int stack_var; /* automatic variable, on stack */

if (++level == 3) /* avoid infinite recursion */

return;

printf("\tStack level %d: address of stack_var: %p\n",

level, & stack_var);

afunc(); /* recursive call */

}
2) Lottery Sch
Post-lab:

1) Write a UNIX system program to establish a connection between two processes, in such a way
that output of one process is input of the other using the pipe() system call

#include <stdlib.h>

#include <unistd.h>

int main(void) {

int n, fd[2];

char buf[100];

pipe(fd);

if (fork()) {

close(fd[1]);

n = read(fd[0], buf, 14);

write(STDOUT_FILENO, buf, n);

else{

close(fd[0]);

write(fd[1],"Hello World \n ", 50);

}
2) Write a system program to demonstrate shared memory IPC - execute with and without
command line arguments.
/*

** shmdemo.c -- read and write to a shared memory segment

*/

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/shm.h>

#define SHM_SIZE 1024 /* make it a 1K shared memory segment */

int main(int argc, char *argv[])

key_t key;

int shmid;

char *data;

if (argc > 2) {

fprintf(stderr, "usage: shmdemo [data_to_write]\n");

exit(1);

/* make the key: */

if ((key = ftok("shmdemo.c", 'R')) == -1) {

perror("ftok");
exit(1);

/* connect to (and possibly create) the segment: */

if ((shmid = shmget(key, SHM_SIZE, 0644 | IPC_CREAT)) == -1) {

perror("shmget");

exit(1);

/* attach to the segment to get a pointer to it: */

printf("SHMID = %d\n",shmid);

data = shmat(shmid, (void *)0, 0);

if (data == (char *)(-1)) {

perror("shmat");

exit(1);

/* read or modify the segment, based on the command line: */

if (argc == 2) {

printf("writing to segment: \"%s\"\n", argv[1]);

strncpy(data, argv[1], SHM_SIZE);

} else

printf("segment contains: \"%s\"\n", data);

/* detach from the segment: */

if (shmdt(data) == -1) {

perror("shmdt");

exit(1);

}
return 0;

}
Review 1:
LAB – V
Pre-lab:
2)

#define MAX_ALLOCS 1000000

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <string.h>

int main(int argc, char *argv[])

char *ptr[MAX_ALLOCS];

int freeStep, freeMin, freeMax, blockSize, numAllocs, j;

printf("\n");

if (argc < 3 || strcmp(argv[1], "--help") == 0)

{ printf("%s num-allocs block-size [step [min [max]]]\n", argv[0]);

exit(5); }

numAllocs = strtol(argv[1], NULL, 10);

if (numAllocs > MAX_ALLOCS)

{ printf("num-allocs > %d\n", MAX_ALLOCS);

exit(5); }

blockSize = strtol(argv[2], NULL, 10);

freeStep = (argc > 3) ? strtol(argv[3], NULL, 10): 1;

freeMin = (argc > 4) ? strtol(argv[4], NULL, 10) : 1;

freeMax = (argc > 5) ? strtol(argv[5], NULL, 10) : numAllocs;

if (freeMax > numAllocs)

{ printf("free-max > num-allocs\n");

exit(5); }

printf("Initial program break: %10p\n", sbrk(0));

printf("Allocating %d*%d bytes\n", numAllocs, blockSize);


for (j = 0; j < numAllocs; j++) {

ptr[j] = malloc(blockSize);

if (ptr[j] == NULL)

{ perror("malloc");

exit(5); }

printf("Program break is now: %10p\n", sbrk(0));

printf("Freeing blocks from %d to %d in steps of %d\n",

freeMin, freeMax, freeStep);

for (j = freeMin - 1; j < freeMax; j += freeStep)

free(ptr[j]);

printf("After free(), program break is: %10p\n", sbrk(0));

exit(10);

}
In-lab:

1) Twin Sisters Riya and Siya collected money to help their friend Radha to buy books. Riya
approached her elder sister Diya to help her calculate the total amount she collected. Riya said that
she collected money from ‘n’ persons and gave Diya a list of values of amount she collected from
each person. After a while Siya arrived and said that she also collected money from ‘m’ people and
submitted information like Riya.
Now Diya has inputs as bellow
First value is ‘n’, followed by n values of amounts collected by Riya. Then the next value is ‘m’,
followed by m values of amounts collected by Siya.
As you are explaining Diya, how to allocate memory dynamically. Take this situation and provide her
with an example program, which stores the above n values provide by Riya in an array using malloc
() and then m values provided by Siya in the same array and using realloc() calculate the total
amount they have collected using malloc(), realloc(). Don’t forget to free the memory allocated, by
using free ().
2) One of the simplest methods for memory allocation is to divide memory into several fixed-sized
partitions. Each partition may contain exactly one process. In this multiple-partition method, when
a partition is free, a process is selected from the input queue and is loaded into the free partition.
When the process terminates, the partition becomes available for another process. The operating
system keeps a table indicating which parts of memory are available and which are occupied.
Finally, when a process arrives and needs memory, a memory section large enough for this process
is provided. When it is time to load or swap a process into main memory, and if there is more than
one free block of memory of enough size, then the operating system must decide which free block
to allocate. Best-fit strategy chooses the block that is closest in size to the request. First-fit chooses
the first available block that is large enough. Worst-fit chooses the largest available block.
Post-lab:
Write a simple memory allocator: memalloc is a simple memory allocator. Which uses own malloc (),
calloc(), realloc() and free() implemented using system calls.

/* implement malloc(), calloc(), realloc() and free() - memalloc.c */

#include <unistd.h>

#include <string.h>

#include <pthread.h>

/* Only for the debug printf */

#include <stdio.h>

struct header_t {

size_t size;

unsigned is_free;

struct header_t *next;

};

struct header_t *head = NULL, *tail = NULL;

pthread_mutex_t global_malloc_lock;

struct header_t *get_free_block(size_t size)

struct header_t *curr = head;

while(curr) {

/* see if there's a free block that can accomodate requested size */

if (curr->is_free && curr->size >= size)

return curr;

curr = curr->next;

return NULL;
}

void free(void *block)

struct header_t *header, *tmp;

/* program break is the end of the process's data segment */

void *programbreak;

if (!block)

return;

pthread_mutex_lock(&global_malloc_lock);

header = (struct header_t*)block - 1;

/* sbrk(0) gives the current program break address */

programbreak = sbrk(0);

/*

Check if the block to be freed is the last one in the

linked list. If it is, then we could shrink the size of the

heap and release memory to OS. Else, we will keep the block

but mark it as free.

*/

if ((char*)block + header->size == programbreak) {

if (head == tail) {

head = tail = NULL;

} else {

tmp = head;

while (tmp) {

if(tmp->next == tail) {

tmp->next = NULL;
tail = tmp;

tmp = tmp->next;

/*

sbrk() with a negative argument decrements the program break.

So memory is released by the program to OS.

*/

sbrk(0 - header->size - sizeof(struct header_t));

/* Note: This lock does not really assure thread

safety, because sbrk() itself is not really

thread safe. Suppose there occurs a foregin sbrk(N)

after we find the program break and before we decrement

it, then we end up realeasing the memory obtained by

the foreign sbrk().

*/

pthread_mutex_unlock(&global_malloc_lock);

return;

header->is_free = 1;

pthread_mutex_unlock(&global_malloc_lock);

void *malloc(size_t size)

size_t total_size;

void *block;

struct header_t *header;


if (!size)

return NULL;

pthread_mutex_lock(&global_malloc_lock);

header = get_free_block(size);

if (header) {

/* Woah, found a free block to accomodate requested memory. */

header->is_free = 0;

pthread_mutex_unlock(&global_malloc_lock);

return (void*)(header + 1);

/* We need to get memory to fit in the requested block and header from OS. */

total_size = sizeof(struct header_t) + size;

block = sbrk(total_size);

if (block == (void*) -1) {

pthread_mutex_unlock(&global_malloc_lock);

return NULL;

header = block;

header->size = size;

header->is_free = 0;

header->next = NULL;

if (!head)

head = header;

if (tail)

tail->next = header;

tail = header;

pthread_mutex_unlock(&global_malloc_lock);

return (void*)(header + 1);

}
void *calloc(size_t num, size_t nsize)

size_t size;

void *block;

if (!num || !nsize)

return NULL;

size = num * nsize;

/* check mul overflow */

if (nsize != size / num)

return NULL;

block = malloc(size);

if (!block)

return NULL;

memset(block, 0, size);

return block;

void *realloc(void *block, size_t size)

struct header_t *header;

void *ret;

if (!block || !size)

return malloc(size);

header = (struct header_t*)block - 1;

if (header->size >= size)

return block;

ret = malloc(size);

if (ret) {
/* Relocate contents to the new bigger block */

memcpy(ret, block, header->size);

/* Free the old memory block */

free(block);

return ret;

/* A debug function to print the entire link list */

void print_mem_list()

struct header_t *curr = head;

printf("head = %p, tail = %p \n", (void*)head, (void*)tail);

while(curr) {

printf("addr = %p, size = %zu, is_free=%u, next=%p\n",

(void*)curr, curr->size, curr->is_free, (void*)curr->next);

curr = curr->next;

/*

Compile and Run

vishnu@mannava:~$ gcc -o memalloc.so -fPIC -shared memalloc.c

The -fPIC and -shared options makes sure the compiled output has position-independent code and tells
the linker to produce a shared object suitable for dynamic linking.

On Linux, if you set the enivornment variable LD_PRELOAD to the path of a shared object, that file will
be loaded before any other library. We could use this trick to load our compiled library file first, so that
the later commands run in the shell will use our malloc(), free(), calloc() and realloc().

vishnu@mannava:~$ export LD_PRELOAD=$PWD/memalloc.so


Now, if you run something like ls, it will use our memory allocator.

ls

memalloc.c memalloc.so

You can also run your own programs with this memory allocator.

*/

/*

vishnu@mannava:~$ cc sll.c

sll.c: In function deletenode:

sll.c:10:6: internal compiler error: Segmentation fault

void deletenode(node * head, int num) {

Please submit a full bug report,

with preprocessed source if appropriate.

See <file:///usr/share/doc/gcc-5/README.Bugs> for instructions.

*/

After restarting the linux

/*

vishnu@mannava:~$ cc sll.c

vishnu@mannava:~$./a.out

insert 5 more elements in to Linked List - Already element 0 is in SLL

Display elements in Linked List

543210

Display elements in Linked List after deleting 2

54310

*/

/* Program for implementation of single Linked List with out functions */


#include <stdio.h>

#include <stdlib.h>

struct node

int data ;

struct node * next ;

};

typedef struct node node;

void deletenode(node * head, int num) {

node *temp;

if(head->data == num)

/* remove the node */

temp = head->next;

free(head);

head = temp;

else {

while(head->next->data != num)

head = head->next;

temp = head->next->next;

free(head->next);

head->next = temp;

void main( )

int i;

node *head, *tmp;


head = malloc(sizeof(node));

head->data = 0;

head->next = NULL;

printf ( "\n insert 5 more elements in to Linked List - Already element 0 is in SLL" ) ;

for(i=1; i < 6; i++) {

tmp = malloc(sizeof(node));

if(tmp == NULL)

printf("malloc failed");

tmp->data = i;

tmp->next = head;

head = tmp;

printf ( "\n Display elements in Linked List\n" ) ;

tmp = head; // start at the 1st node

while(tmp != NULL) {

printf(" %d ", tmp->data);

tmp = tmp->next; // make tmp point to next node

deletenode(head,2);

printf ( "\n Display elements in Linked List after deleting 2\n" ) ;

tmp = head; // start at the 1st node

while(tmp != NULL) {

printf(" %d ", tmp->data);

tmp = tmp->next; // make tmp point to next node

}
LAB – VI
Pre-lab:
In-lab:
Post-lab:
Review 2:
LAB – VII
Pre-lab:
3)

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <sys/types.h>

#include <pthread.h>

void* func_one(void* ptr)

{ int *i=(int *)ptr;

printf("Hello World !!!! by Thread ID : %d, Thread Number : %d\n",pthread_self(),*i+1);

int main()

pthread_t thread_one[5];

int i=0;

int a[5];

// creating thread one

for(i=0;i<5;i++){

a[i]=i;

pthread_create(&thread_one[i], NULL, func_one, (void *)&a[i]);

for(i=0;i<5;i++)

pthread_join(thread_one[i], NULL);
// wait for thread two

printf("done\n");

}
In-lab:
1)

#include <pthread.h>

#include<semaphore.h>

#include<stdio.h>

static int glob = 0;

sem_t sem1;

/* Loop 'arg' times incrementing 'glob' */

static void * threadFunc(void *arg)

int loops = *((int *) arg);

int loc, j;

for (j = 0; j < loops; j++) {

sem_wait(&sem1);

loc = glob;

loc++;
glob = loc;

sem_post(&sem1);

return NULL;

int

main(int argc, char *argv[])

pthread_t t1, t2;

long loops, s;

sem_init(&sem1,0,1);

loops = strtol(argv[1], NULL, 10);

s = pthread_create(&t1, NULL, threadFunc, &loops);

if (s != 0)

perror("pthread_create");
s = pthread_create(&t2, NULL, threadFunc, &loops);

if (s != 0)

perror("pthread_create");

s = pthread_join(t1, NULL);

if (s != 0)

perror("pthread_join");

s = pthread_join(t2, NULL);

if (s != 0)

perror("pthread_join");

printf("glob = %d\n", glob);

exit(0);

2)

#include<stdio.h>

#include<pthread.h>

#include<stdlib.h>

#define no_threads 10
#define n 20

static long sum = 0;

long a[n];

static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;

static void *slave(void *st)

long rank=(long*)st;

long my_n=n/no_threads;

long my_first_i = my_n *rank;

long my_last_i = my_first_i + my_n;

long i;

for (i = my_first_i; i < my_last_i; i++)

pthread_mutex_lock(&mtx);

printf(" thread rank = %d Global sum it is fetching is %d \n", rank, sum);

sum += *(a + i);

printf(" hello from thread %d and its partial sum = %d\n",rank,sum);

pthread_mutex_unlock(&mtx);

return NULL; }

main()

long i;

pthread_t thread[10];

for (i = 0; i < n; i++)

a[i] = i+1;

for (i = 0; i < no_threads; i++)

if (pthread_create(&thread[i], NULL, slave,(void*) i) != 0)


perror("Pthread create fails");

for (i = 0; i < no_threads; i++) {

if (pthread_join(thread[i], NULL) != 0)

perror("Pthread join fails"); }

printf("The sum of numbers from %d to %d is %d\n",a[0],a[n-1], sum);

exit(0); }
Post-lab:
1)

#include <stdio.h>

#include <unistd.h>

#include <fcntl.h>

#include <pthread.h>

#include <semaphore.h>

#include <sys/types.h>

#define NBUFF 10

#define SEM_MUTEX "mutex"

/* these are args to px_ipc_name() */

#define SEM_NEMPTY "nempty"

#define SEM_NSTORED "nstored"

int nitems; /* read-only by producer and consumer */

struct {

/* data shared by producer and consumer */

int buff[NBUFF];

sem_t *mutex;

sem_t *nempty;

sem_t *nstored;

} shared;

void *produce(void *), *consume(void *);

int main(int argc, char **argv)

pthread_t

tid_produce, tid_consume;

if (argc != 2)

printf("usage: prodcons1 <#items>");


exit(1);

nitems = atoi(argv[1]);

Synchronization - II

/* 4create three semaphores */

shared.mutex = sem_open(SEM_MUTEX, O_CREAT | O_EXCL, 0644, 1);

shared.nempty = sem_open(SEM_NEMPTY, O_CREAT | O_EXCL, 0644, NBUFF);

shared.nstored = sem_open(SEM_NSTORED, O_CREAT | O_EXCL, 0644, 0);

/* 4create one producer thread and one consumer thread */

pthread_setconcurrency(2);

pthread_create(&tid_produce, NULL, produce, NULL);

pthread_create(&tid_consume, NULL, consume, NULL);

/* 4wait for the two threads */

pthread_join(tid_produce, NULL);

pthread_join(tid_consume, NULL);

/* 4remove the semaphores */

sem_unlink(SEM_MUTEX);

sem_unlink(SEM_NEMPTY);

sem_unlink(SEM_NSTORED);

exit(0);

/* end main */

/* include prodcons */

void *produce(void *arg)

int i;

for (i = 0; i < nitems; i++) {

sem_wait(shared.nempty);

/* wait for at least 1 empty slot */


sem_wait(shared.mutex);

shared.buff[i % NBUFF] = i;

/* store i into circular buffer */

sem_post(shared.mutex);

sem_post(shared.nstored);

/* 1 more stored item */

return(NULL);

void *consume(void *arg)

int i;

for (i = 0; i < nitems; i++) {

sem_wait(shared.nstored);

/* wait for at least 1 stored item */

sem_wait(shared.mutex);

if (shared.buff[i % NBUFF] == i)

printf("buff[%d] = %d\n", i, shared.buff[i % NBUFF]);

sem_post(shared.mutex);

sem_post(shared.nempty);

/* 1 more empty slot */

return(NULL);

}
LAB – VIII

Pre-lab:

4)

#include<pthread.h>

#include<stdio.h>

int done = 0;

pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;

pthread_cond_t c = PTHREAD_COND_INITIALIZER;

void thr_exit() {

Pthread_mutex_lock(&m);

done = 1;

Pthread_cond_signal(&c);

Pthread_mutex_unlock(&m);

void *child(void *arg) {

printf("child\n");

thr_exit();

return NULL;

void thr_join() {

Pthread_mutex_lock(&m);

while (done == 0)

Pthread_cond_wait(&c, &m);

Pthread_mutex_unlock(&m);

int main(int argc, char *argv[]) {

printf("parent: begin\n");
pthread_t p;

Pthread_create(&p, NULL, child, NULL);

thr_join();

printf("parent: end\n");

return 0;

}
In-lab:
1)
Post-lab:
1)

#include <stdio.h>

#include <unistd.h>

#include <fcntl.h>

#include <pthread.h>

#include <sys/types.h>

#define MAXNITEMS 1000000

#define MAXNTHREADS 100

/* globals shared by threads */

int nitems;

/* read-only by producer and consumer*/

int buff[MAXNITEMS];

struct {

pthread_mutex_t mutex;

int nput; /* next index to store */

int nval; /* next value to store */

} put = { PTHREAD_MUTEX_INITIALIZER };

struct {

pthread_mutex_t mutex;

pthread_cond_t cond;

int nready;

/* number ready for consumer */

} nready = { PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER };

/* end globals */

void

*produce(void *), *consume(void *);

/* include main */

int main(int argc, char **argv)


{

int i, nthreads, count[MAXNTHREADS];

pthread_t tid_produce[MAXNTHREADS], tid_consume;

if (argc != 3)

printf("usage: prodcons6 <#items> <#threads>");

nitems = atoi(argv[1]);

nthreads = atoi(argv[2]);

pthread_setconcurrency(nthreads + 1);

/* 4create all producers and one consumer */

for (i = 0; i < nthreads; i++) {

count[i] = 0;

pthread_create(&tid_produce[i], NULL, produce, &count[i]);

pthread_create(&tid_consume, NULL, consume, NULL);

/* wait for all producers and the consumer */

for (i = 0; i < nthreads; i++) {

pthread_join(tid_produce[i], NULL);

printf("count[%d] = %d\n", i, count[i]);

pthread_join(tid_consume, NULL);

exit(0);

/* end main */

/* include prodcons */

void *produce(void *arg)

for ( ; ; ) {
pthread_mutex_lock(&put.mutex);

if (put.nput >= nitems) {

pthread_mutex_unlock(&put.mutex);

return(NULL);

/* array is full, we're done */

buff[put.nput] = put.nval;

put.nput++;

put.nval++;

pthread_mutex_unlock(&put.mutex);

pthread_mutex_lock(&nready.mutex);

if (nready.nready == 0)

pthread_cond_signal(&nready.cond);

nready.nready++;

pthread_mutex_unlock(&nready.mutex);

*((int *) arg) += 1;

void *consume(void *arg)

int i;

for (i = 0; i < nitems; i++) {

pthread_mutex_lock(&nready.mutex);

while (nready.nready == 0)

pthread_cond_wait(&nready.cond, &nready.mutex);

nready.nready--;

pthread_mutex_unlock(&nready.mutex);

if (buff[i] == i)

printf("buff[%d] = %d\n", i, buff[i]);


}

return(NULL);

}
Review 3:
LAB – IX

Pre-lab:
In-lab:
Post-lab:
LAB – X

Pre-lab:
In-lab:
Post-lab:
Review 4:
Review 5:
LAB – XI
Pre-lab:
In-lab:
Post-lab:
Review 6:
LAB – XII

Pre-lab:
In-lab:
Post-lab:

Anda mungkin juga menyukai