Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

remove trailing whitespaces #7

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions INSTALL-xv6.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ There! Now you have completed the easiest part.

To play with xv6 on a Mac, you'll need to install two pieces of software. The
first is the [`qemu`](https://www.qemu.org/download/) machine emulation
environment.
environment.

To learn more about what emulation is, read [this
page](https://en.wikipedia.org/wiki/Emulator). The short story is that an
Expand All @@ -38,19 +38,19 @@ but it would make running and debugging xv6 slower and more painful. With a
realistic emulator like `qemu`, you can quickly run your kernel but not have
the pain of rebooting the actual system you are using. Further, if you make a
mistake, your entire machine doesn't lock up, just the emulator, which you can
exit or kill. It just makes your life much better than doing the real thing.
exit or kill. It just makes your life much better than doing the real thing.

To install `qemu` on a Mac, just do the following:

```sh
prompt> sudo port install qemu
```

This will take a little while, so pour yourself a cup of coffee and enjoy.
This will take a little while, so pour yourself a cup of coffee and enjoy.

This command assumes you have [MacPorts](https://www.macports.org/)
installed. If you don't, go to the [MacPorts install
page](https://www.macports.org/install.php) and follow instructions first.
page](https://www.macports.org/install.php) and follow instructions first.

Th command further assumes that the path to port (usually `/opt/local/bin`) is
in your path. You should probably add this directory to your path anyhow; the
Expand All @@ -64,10 +64,10 @@ prompt> qemu-system-x86_64 -nographic
```

This will run the `qemu` emulator, but with no kernel to boot! Alas, not that
useful.
useful.

To quit `qemu`, type `C-a x` (that is, hold down `control` and while doing so,
press `a`, then let go of `control`, then press `x`).
press `a`, then let go of `control`, then press `x`).

The second piece of software you'll need is the `gcc` cross-compilation
toolchain. To install these pieces of software, type:
Expand Down Expand Up @@ -95,7 +95,7 @@ init: starting sh
$
```

The `$` is the shell command prompt: who-hoo!
The `$` is the shell command prompt: who-hoo!

Remember to type `C-a x` to quit the emulation.

Expand Down
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,16 @@ Also (increasingly) available are some tests to see if your code works; eventual
every project will have a set of tests available. The testing framework that is
currently available is found [here](https://github.com/remzi-arpacidusseau/ostep-projects/tree/master/tester).
A specific testing script, found in each project directory, can be used to run
the tests against your code.
the tests against your code.

For example, in the initial utilities project, the relatively simple `wcat`
program that you create can be tested by running the `test-wcat.sh` script.
This could be accomplished by the following commands:
```sh
prompt> git clone https://github.com/remzi-arpacidusseau/ostep-projects
prompt> cd ostep-projects/initial-utilities/wcat
prompt> emacs -nw wcat.c
prompt> gcc -o wcat wcat.c -Wall
prompt> emacs -nw wcat.c
prompt> gcc -o wcat wcat.c -Wall
prompt> ./test-wcat.sh
test 1: passed
test 2: passed
Expand All @@ -28,7 +28,7 @@ test 4: passed
test 5: passed
test 6: passed
test 7: passed
prompt>
prompt>
```
Of course, this sequence assumes (a) you use `emacs` (you should!), (b) your
code is written in one shot (impressive!), and (c) that it works perfectly
Expand All @@ -41,7 +41,7 @@ compile/run/debug cycle might take a few iterations.

These projects are meant to get you warmed up with programming in the C/UNIX
environment. None are meant to be particularly hard, but should be enough so
that you can get more comfortable programming.
that you can get more comfortable programming.

Realize the best thing you can do to learn to program in any environment is to
program **a lot**. These small projects are only the beginning of that
Expand Down Expand Up @@ -82,7 +82,7 @@ version of Unix and developed at MIT. Unlike the C/Linux projects, these give
you direct experience inside a real, working operating system (albeit a simple
one).

Read the [install notes](INSTALL-xv6.md) to see how to download the latest xv6
Read the [install notes](INSTALL-xv6.md) to see how to download the latest xv6
and install the tools you'll need.

### Initial Projects
Expand Down
16 changes: 8 additions & 8 deletions concurrency-mapreduce/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ What's fascinating about MapReduce is that so many different kinds of relevant
computations can be mapped onto this framework. The original paper lists many
examples, including word counting (as above), a distributed grep, a URL
frequency access counters, a reverse web-link graph application, a term-vector
per host analysis, and others.
per host analysis, and others.

What's also quite interesting is how easy it is to parallelize: many mappers
can be running at the same time, and later, many reducers can be running at
Expand Down Expand Up @@ -109,9 +109,9 @@ void MR_Emit(char *key, char *value);

unsigned long MR_DefaultHashPartition(char *key, int num_partitions);

void MR_Run(int argc, char *argv[],
Mapper map, int num_mappers,
Reducer reduce, int num_reducers,
void MR_Run(int argc, char *argv[],
Mapper map, int num_mappers,
Reducer reduce, int num_reducers,
Partitioner partition);

#endif // __mapreduce_h__
Expand All @@ -130,15 +130,15 @@ a Partition function, and then call `MR_Run()`. The infrastructure will then
create threads as appropriate and run the computation.

One basic assumption is that the library will create `num_mappers` threads
(in a thread pool) that perform the map tasks. Another is that your library
(in a thread pool) that perform the map tasks. Another is that your library
will create `num_reducers` threads to perform the reduction tasks. Finally,
your library will create some kind of internal data structure to pass
keys and values from mappers to reducers; more on this below.

## Simple Example: Wordcount

Here is a simple (but functional) wordcount program, written to use this
infrastructure:
infrastructure:

```
#include <assert.h>
Expand Down Expand Up @@ -180,7 +180,7 @@ Let's walk through this code, in order to see what it is doing. First, notice
that `Map()` is called with a file name. In general, we assume that this type
of computation is being run over many files; each invocation of `Map()` is
thus handed one file name and is expected to process that file in its
entirety.
entirety.

In this example, the code above just reads through the file, one line at a
time, and uses `strsep()` to chop the line into tokens. Each token is then
Expand All @@ -189,7 +189,7 @@ key and a value. The key here is the word itself, and the token is just a
count, in this case, 1 (as a string). It then closes the file.

The `MR_Emit()` function is thus another key part of your library; it needs to
take key/value pairs from the many different mappers and store them in a way
take key/value pairs from the many different mappers and store them in a way
that later reducers can access them, given constraints described
below. Designing and implementing this data structure is thus a central
challenge of the project.
Expand Down
6 changes: 3 additions & 3 deletions concurrency-mapreduce/mapreduce.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ void MR_Emit(char *key, char *value);

unsigned long MR_DefaultHashPartition(char *key, int num_partitions);

void MR_Run(int argc, char *argv[],
Mapper map, int num_mappers,
Reducer reduce, int num_reducers,
void MR_Run(int argc, char *argv[],
Mapper map, int num_mappers,
Reducer reduce, int num_reducers,
Partitioner partition);

#endif // __mapreduce_h__
12 changes: 6 additions & 6 deletions concurrency-pzip/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
In an earlier project, you implemented a simple compression tool based on
run-length encoding, known simply as `zip`. Here, you'll implement something
similar, except you'll use threads to make a parallel version of `zip`. We'll
call this version ... wait for it ... `pzip`.
call this version ... wait for it ... `pzip`.

There are three specific objectives to this assignment:

Expand All @@ -30,7 +30,7 @@ Read these chapters carefully in order to prepare yourself for this project.
## Overview

First, recall how `zip` works by reading the description
[here](https://github.com/remzi-arpacidusseau/ostep-projects/tree/master/initial-utilities).
[here](https://github.com/remzi-arpacidusseau/ostep-projects/tree/master/initial-utilities).
You'll use the same basic specification, with run-length encoding as the basic
technique.

Expand All @@ -43,7 +43,7 @@ prompt> ./pzip file > file.z

As before, there may be many input files (not just one, as above). However,
internally, the program will use POSIX threads to parallelize the compression
process.
process.

## Considerations

Expand All @@ -57,7 +57,7 @@ least) the following issues:

One interesting issue that the "best" implementations will handle is this:
what happens if one thread runs more slowly than another? Does the
compression give more work to faster threads?
compression give more work to faster threads?

- **How to determine how many threads to create.** On Linux, this means using
interfaces like `get_nprocs()` and `get_nprocs_conf()`; read the man pages
Expand All @@ -68,14 +68,14 @@ least) the following issues:
will yield speed up, each thread's efficiency in performing the
compression is also of critical importance. Thus, making the core
compression loop as CPU efficient as possible is needed for high
performance.
performance.

- **How to access the input file efficiently.** On Linux, there are many ways
to read from a file, including C standard library calls like `fread()` and
raw system calls like `read()`. One particularly efficient way is to use
memory-mapped files, available via `mmap()`. By mapping the input file
into the address space, you can then access bytes of the input file via
pointers and do so quite efficiently.
pointers and do so quite efficiently.


## Grading
Expand Down
16 changes: 8 additions & 8 deletions concurrency-webserver/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ sends a request just to read a specific file from the server. Slightly more
complex is *dynamic* content, in which a client requests that an executable
file be run on the web server and its output returned to the client.
Each file has a unique name known as a **URL** (**Universal Resource
Locator**).
Locator**).

As a simple example, let's say the client browser wants to fetch static
content (i.e., just some file) from a web server running on some machine. The
Expand Down Expand Up @@ -170,7 +170,7 @@ that it can handle new input parameters (e.g., the number of threads to
create).

## Part 1: Multi-threaded

The basic web server that we provided has a single thread of
control. Single-threaded web servers suffer from a fundamental performance
problem in that only a single HTTP request can be serviced at a time. Thus,
Expand Down Expand Up @@ -275,7 +275,7 @@ backdoor into files in your system.
Your system should also make sure to constrain file requests to stay within
the sub-tree of the file system hierarchy, rooted at the base working
directory that the server starts in. You must take steps to ensure that
pathnames that are passed in do not refer to files outside of this sub-tree.
pathnames that are passed in do not refer to files outside of this sub-tree.
One simple (perhaps overly conservative) way to do this is to reject any
pathname with `..` in it, thus avoiding any traversals up the file system
tree. More sophisticated solutions could use `chroot()` or Linux containers,
Expand Down Expand Up @@ -323,21 +323,21 @@ the following files:
- [`wserver.c`](https://github.com/remzi-arpacidusseau/ostep-projects/blob/master/concurrency-webserver/src/wserver.c): Contains `main()` for the web server and the basic serving loop.
- [`request.c`](https://github.com/remzi-arpacidusseau/ostep-projects/blob/master/concurrency-webserver/src/request.c): Performs most of the work for handling requests in the basic
web server. Start at `request_handle()` and work through the logic from
there.
there.
- [`io_helper.h`](https://github.com/remzi-arpacidusseau/ostep-projects/blob/master/concurrency-webserver/src/io_helper.h) and [`io_helper.c`](https://github.com/remzi-arpacidusseau/ostep-projects/blob/master/concurrency-webserver/src/io_helper.c): Contains wrapper functions for the system calls invoked by
the basic web server and client. The convention is to add `_or_die` to an
existing call to provide a version that either succeeds or exits. For
example, the `open()` system call is used to open a file, but can fail for a
number of reasons. The wrapper, `open_or_die()`, either successfully opens a
file or exists upon failure.
file or exists upon failure.
- [`wclient.c`](https://github.com/remzi-arpacidusseau/ostep-projects/blob/master/concurrency-webserver/src/wclient.c): Contains main() and the support routines for the very simple
web client. To test your server, you may want to change this code so that it
can send simultaneous requests to your server. By launching `wclient`
multiple times, you can test how your server handles concurrent requests.
- [`spin.c`](https://github.com/remzi-arpacidusseau/ostep-projects/blob/master/concurrency-webserver/src/spin.c): A simple CGI program. Basically, it spins for a fixed amount
of time, which you may useful in testing various aspects of your server.
of time, which you may useful in testing various aspects of your server.
- [`Makefile`](https://github.com/remzi-arpacidusseau/ostep-projects/blob/master/concurrency-webserver/src/Makefile): We also provide you with a sample Makefile that creates
`wserver`, `wclient`, and `spin.cgi`. You can type make to create all of
`wserver`, `wclient`, and `spin.cgi`. You can type make to create all of
these programs. You can type make clean to remove the object files and the
executables. You can type make server to create just the server program,
etc. As you create new files, you will need to add them to the Makefile.
Expand All @@ -355,5 +355,5 @@ We anticipate that you will find the following routines useful for creating
and synchronizing threads: `pthread_create()`, `pthread_mutex_init()`,
`pthread_mutex_lock()`, `pthread_mutex_unlock()`, `pthread_cond_init()`,
`pthread_cond_wait()`, `pthread_cond_signal()`. To find information on these
library routines, read the man pages (RTFM).
library routines, read the man pages (RTFM).

6 changes: 3 additions & 3 deletions concurrency-webserver/src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@

CC = gcc
CFLAGS = -Wall
OBJS = wserver.o wclient.o request.o io_helper.o
OBJS = wserver.o wclient.o request.o io_helper.o

.SUFFIXES: .c .o
.SUFFIXES: .c .o

all: wserver wclient spin.cgi

wserver: wserver.o request.o io_helper.o
$(CC) $(CFLAGS) -o wserver wserver.o request.o io_helper.o
$(CC) $(CFLAGS) -o wserver wserver.o request.o io_helper.o

wclient: wclient.o io_helper.o
$(CC) $(CFLAGS) -o wclient wclient.o io_helper.o
Expand Down
32 changes: 16 additions & 16 deletions concurrency-webserver/src/io_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,52 +27,52 @@ int open_client_fd(char *hostname, int port) {
int client_fd;
struct hostent *hp;
struct sockaddr_in server_addr;

if ((client_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
return -1;
// Fill in the server's IP address and port
return -1;

// Fill in the server's IP address and port
if ((hp = gethostbyname(hostname)) == NULL)
return -2; // check h_errno for cause of error
return -2; // check h_errno for cause of error
bzero((char *) &server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
bcopy((char *) hp->h_addr,
bcopy((char *) hp->h_addr,
(char *) &server_addr.sin_addr.s_addr, hp->h_length);
server_addr.sin_port = htons(port);
// Establish a connection with the server

// Establish a connection with the server
if (connect(client_fd, (sockaddr_t *) &server_addr, sizeof(server_addr)) < 0)
return -1;
return client_fd;
}

int open_listen_fd(int port) {
// Create a socket descriptor
// Create a socket descriptor
int listen_fd;
if ((listen_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
fprintf(stderr, "socket() failed\n");
return -1;
}

// Eliminates "Address already in use" error from bind
int optval = 1;
if (setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, (const void *) &optval, sizeof(int)) < 0) {
fprintf(stderr, "setsockopt() failed\n");
return -1;
}

// Listen_fd will be an endpoint for all requests to port on any IP address for this host
struct sockaddr_in server_addr;
bzero((char *) &server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
server_addr.sin_port = htons((unsigned short) port);
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
server_addr.sin_port = htons((unsigned short) port);
if (bind(listen_fd, (sockaddr_t *) &server_addr, sizeof(server_addr)) < 0) {
fprintf(stderr, "bind() failed\n");
return -1;
}
// Make it a listening socket ready to accept connection requests

// Make it a listening socket ready to accept connection requests
if (listen(listen_fd, 1024) < 0) {
fprintf(stderr, "listen() failed\n");
return -1;
Expand Down
Loading