For each experiment, describe your methods: the number of repeats of the operation being measured, the number of the experiments, how you selected the final result, and its accuracy.
Do man 2 gettimeofday. The system call gives time measured in
seconds and microseconds. We shall assume that the microseconds figure
are precise rather than accurate (we leave you to discover whether this
is true of Linux). For the purposes of these exercises, we shall take the
resolution of the system clock to be 100Hz.
2.1 How can you nonetheless use gettimeofday to measure the time taken for one operation in milliseconds, to an accuracy of 2 decimal places? Quantify your answer!
Measure the time taken to perform a getpid system call.
2.2 What is the error due to execution of the control loop in your experiment? Explain how you determined this.
2.3 What accounts for variations in the figures you obtain for getpid?
2.4 How did you obtain a single timing figure from the varied
measurements?
Write a program that uses fork to create as many processes as the system will allow and then awaits their termination. Make sure that each new process immediately calls exit. Run your program a suitable number of times and record the values obtained.
3.1 How many processes were created in each experiment?
3.2 How long, in milliseconds, does each fork + wait take? Careful: design a different experiment to the one you just produced. What is the accuracy of your answer?
Do man exec, to find out how to run a specified program in the calling process. You will find that various forms of exec exist. A simple form is execv, which requires a full path name for the program binary, and an argv pointer. Note that argv cannot be NULL (0).
Create a very simple program that immediately exits. Call the resultant binary fred, say.
Produce a modified version of the fork+wait program, so that each child process execs fred. Attach this program. Run this program several times and record the values obtained.
3.3 How do you account for the time difference between this case and the last experiment?
3.4 You probably found that the first measurement in the exec
experiment was larger than subsequent ones. Why should that be?
Find out the size of a page ? the smallest unit of mapped memory.
Input the following simple program, compile it, use size on the binary and convert size’s output to hexadecimal representation.
static char *aStaticString = "fred";
static int aStaticDataItem;
static int anInitialisedStaticDataItem = 0x666;
main(int argc, char *argv[])
{
unsigned char *cp;
unsigned char aCharacter;
cp = &aCharacter;
printf("address of character on stack = 0x%x\n",
cp);
printf("address of initialised string = 0x%x\n",
aStaticString );
printf("address of uninitialised int = 0x%x\n",
&aStaticDataItem);
printf("address of initialised int = 0x%x\n", &anInitialisedStaticDataItem);
printf("address of procedure main = 0x%x\n", main);
}
4.1 Apart from the address of aCharacter, account for
the address values printed by this program, relating them to the output
of size.
4.2 Discuss whether you have sufficient evidence to determine
the top of the stack’s address range.
Add the following code to the program above.
for(cp = &aCharacter; ; cp -= PAGESIZE) /* you need to #define PAGESIZE
*/
{
aCharacter = *cp;
printf("made it to 0x%x!\n", cp);
}
4.3 You should find that this program gives a ‘segmentation violation’ after a certain number of loop iterations. What has happened? Investigate whether the same effect occurs using a recursive procedure call to extend the stack, and account for what you find.
4.4 Write a program to walk the whole address space of a process, from address 0. The program should report address ranges in which write and/or read accesses to memory are possible. Attach a listing, and briefly explain here what you found by running the program. Explain your findings.
Hints: An attempt to access an address outside the address space causes
a segmentation violation exception (SIGSEGV: do man signal). Alternatively,
you may utilise system calls to check your addresses. Your program may
take a long time; consider how crude you can make the search.
Run a client and server together at the same machine, and test that they work together.
6.1 How long does a single request-reply interaction take when datasize is a) 4 bytes? b) 1024 bytes? Explain the accuracy of your answers, and how you arrived at them from the measurements.
6.2 How do you think the elapsed time for a local request-reply
interaction is spent? Give a qualitative answer.
7.1 How long does a single request-reply interaction take when datasize is a) 4 bytes? b) 1024 bytes? State the accuracy of your answers, and how you arrived at them from the measurements.
7.2 sendto uses UDP. This places an 8-byte header onto an IP packet, which in turn uses a 20-byte header. An Ethernet packet carries 18 bytes of its own header and checksum. The minimum Ethernet packet size is 64 bytes. Ethernet bandwidth is 10 or 100 Mbits/sec (find out about your Ethernet).
What is the total hardware transmission time (time "on the wire") for the 2 packets in a single remote request-reply interaction involving a) 4 bytes b) 1024 bytes?
How is the rest of the elapsed time for a remote request-reply interaction
spent? Give a qualitative description, in terms of differences to your
answer to 6.2.
Run a client and server at separate, dedicated machines. NB You may find that sendto fails for lack of buffer space after a certain number of sends. Try to accommodate this by reducing the number of attempted sends each time.
8.1 Do messages get lost? If so, how? How did you detect losses?
8.2 How long does each client request take if datasize is a)
4 bytes? b) 1024 bytes?
int option = 1;
setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &option,
sizeof(option));
9.1 How long does a single request-reply interaction take when datasize is a) 4 bytes? b) 1024 bytes?
9.2 How do you think the elapsed time for a remote request-reply
interaction is spent? Give your answer in terms of how it differs from
your answer to the corresponding part of 7.2, and in particular refer to
the fact that TCP is a reliable protocol.
10.2 If you were designing an RPC/RMI system under Unix, would you use connected or unconnected sockets? Why? What are the merits of the other choice?