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

Sp16 hw2 start #3

Open
wants to merge 9 commits 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
7 changes: 5 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ LD = $(TOOLPREFIX)ld
OBJCOPY = $(TOOLPREFIX)objcopy
OBJDUMP = $(TOOLPREFIX)objdump
#CFLAGS = -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall -MD -ggdb -m32 -Werror -fno-omit-frame-pointer
CFLAGS = -fno-pic -static -fno-builtin -fno-strict-aliasing -fvar-tracking -fvar-tracking-assignments -O0 -g -Wall -MD -gdwarf-2 -m32 -Werror -fno-omit-frame-pointer
CFLAGS = -fno-pic -static -fno-builtin -fno-strict-aliasing -fvar-tracking -fvar-tracking-assignments -O0 -g -Wall -MD -gdwarf-2 -m32 -Werror -fno-omit-frame-pointer -Wno-return-type
CFLAGS += $(shell $(CC) -fno-stack-protector -E -x c /dev/null >/dev/null 2>&1 && echo -fno-stack-protector)
ASFLAGS = -m32 -gdwarf-2 -Wa,-divide
# FreeBSD ld wants ``elf_i386_fbsd''
Expand Down Expand Up @@ -134,7 +134,7 @@ tags: $(OBJS) entryother.S _init
vectors.S: vectors.pl
perl vectors.pl > vectors.S

ULIB = ulib.o usys.o printf.o umalloc.o
ULIB = ulib.o usys.o printf.o umalloc.o pthread.o

_%: %.o $(ULIB)
$(LD) $(LDFLAGS) -N -e main -Ttext 0 -o $@ $^
Expand Down Expand Up @@ -173,6 +173,9 @@ UPROGS=\
_wc\
_zombie\
_shutdown\
# _test_clone\
# _test_pthread\
# _test_mutex\

fs.img: mkfs README $(UPROGS)
./mkfs fs.img README $(UPROGS)
Expand Down
9 changes: 9 additions & 0 deletions pthread.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#include "types.h"
#include "stat.h"
#include "user.h"
#include "fs.h"
#include "fcntl.h"
#include "pthread.h"

// Implement your pthreads library here.

7 changes: 7 additions & 0 deletions pthread.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#ifndef XV6_PTHREAD
#define XV6_PTHREAD

// Define all functions and types for pthreads here.
// This can be included in both kernel and user code.

#endif
96 changes: 96 additions & 0 deletions test_clone.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
#include "types.h"
#include "stat.h"
#include "user.h"
#include "fs.h"
#include "fcntl.h"

#define NUM_THREADS 16
#define TARGET_COUNT_PER_THREAD 100000

void *thread(void *arg)
{
int i;
int counter;

sleep(10);
printf(1, "thread %d: started...\n", *(int*)arg);

for (i=0; i<TARGET_COUNT_PER_THREAD; i++) {
sleep(0);
counter++;
sleep(0);
}

texit(arg);
}

int main(int argc, char **argv)
{
int i;
int passed = 1;

// Set up thread stuff
// Pids
int pids[NUM_THREADS];
// Stacks
void *stacks[NUM_THREADS];
// Args
int *args[NUM_THREADS];

// Allocate stacks and args and make sure we have them all
// Bail if something fails
for (i=0; i<NUM_THREADS; i++) {
stacks[i] = (void*) malloc(4096);
if (!stacks[i]) {
printf(1, "main: could not get stack for thread %d, exiting...\n");
exit();
}

args[i] = (int*) malloc(sizeof(int));
if (!args[i]) {
printf(1, "main: could not get memory (for arg) for thread %d, exiting...\n");
exit();
}

*args[i] = i;
}

printf(1, "main: running with %d threads...\n", NUM_THREADS);

// Start all children
for (i=0; i<NUM_THREADS; i++) {
pids[i] = clone(thread, args[i], stacks[i]);
printf(1, "main: created thread with pid %d\n", pids[i]);
}

// Wait for all children
for (i=0; i<NUM_THREADS; i++) {
void *joinstack;
void *retval;
int r;
r = join(pids[i], &joinstack, &retval);
if (r < 0) {
passed = 0;
}
if (*(int*)retval != i) {
passed = 0;
}
printf(1, "main: thread %d joined...retval=%d\n", i, *(int*)retval);
}

if (passed) {
printf(1, "TEST PASSED!\n");
}
else {
printf(1, "TEST FAILED!\n");
}

// Clean up memory
for (i=0; i<NUM_THREADS; i++) {
free(stacks[i]);
free(args[i]);
}

// Exit
exit();
}
106 changes: 106 additions & 0 deletions test_mutex.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
#include "types.h"
#include "stat.h"
#include "user.h"
#include "fs.h"
#include "fcntl.h"
#include "pthread.h"

#define NUM_THREADS 16
#define TARGET_COUNT_PER_THREAD 32000

uint g_counter;
pthread_mutex_t mutex;

void *thread(void *arg)
{
int i;
int counter;

sleep(10);
printf(1, "thread %d: started...\n", *(int*)arg);

for (i=0; i<TARGET_COUNT_PER_THREAD; i++) {
pthread_mutex_lock(&mutex);

counter = g_counter;
sleep(0);
counter++;
sleep(0);
g_counter = counter;

pthread_mutex_unlock(&mutex);
}

pthread_exit(arg);
}

int main(int argc, char **argv)
{
int i;
int final_counter;
int final_target = NUM_THREADS*TARGET_COUNT_PER_THREAD;

// Initialize mutex
if (pthread_mutex_init(&mutex, 0) < 0)
{
printf(1, "main: error initializing mutex...\n");
exit();
}

// Initialize counter
g_counter = 0;

// Set up thread stuff

// Stacks
pthread_t threads[NUM_THREADS];
// Args
int *args[NUM_THREADS];

// Allocate stacks and args and make sure we have them all
// Bail if something fails
for (i=0; i<NUM_THREADS; i++) {
args[i] = (int*) malloc(sizeof(int));
if (!args[i]) {
printf(1, "main: could not get memory (for arg) for thread %d, exiting...\n");
exit();
}

*args[i] = i;
}

printf(1, "main: running with %d threads...\n", NUM_THREADS);

// Start all children
for (i=0; i<NUM_THREADS; i++) {
pthread_create(&threads[i], 0, thread, args[i]);
printf(1, "main: created thread with pid %d\n", threads[i].pid);
}

// Wait for all children
for (i=0; i<NUM_THREADS; i++) {
void *retval;
pthread_join(threads[i], &retval);
printf(1, "main: thread %d joined...retval=%d\n", i, *(int*)retval);
}

// Check the result
final_counter = g_counter;
printf(1, "Final counter is %d, target is %d\n", final_counter, final_target);

if (final_counter == final_target)
printf(1, "TEST PASSED!\n");
else
printf(1, "TEST FAILED!\n");

// Clean up mutex
pthread_mutex_destroy(&mutex);

// Clean up memory
for (i=0; i<NUM_THREADS; i++) {
free(args[i]);
}

// Exit
exit();
}
87 changes: 87 additions & 0 deletions test_pthread.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
#include "types.h"
#include "stat.h"
#include "user.h"
#include "fs.h"
#include "fcntl.h"
#include "pthread.h"

#define NUM_THREADS 16
#define TARGET_COUNT_PER_THREAD 100000

void *thread(void *arg)
{
int i;
int counter;

sleep(10);
printf(1, "thread %d: started...\n", *(int*)arg);

for (i=0; i<TARGET_COUNT_PER_THREAD; i++) {
sleep(0);
counter++;
sleep(0);
}

pthread_exit(arg);
}

int main(int argc, char **argv)
{
int i;
int passed = 1;

// Set up thread stuff
// Threads
pthread_t threads[NUM_THREADS];
// Args
int *args[NUM_THREADS];

// Allocate stacks and args and make sure we have them all
// Bail if something fails
for (i=0; i<NUM_THREADS; i++) {
args[i] = (int*) malloc(sizeof(int));
if (!args[i]) {
printf(1, "main: could not get memory (for arg) for thread %d, exiting...\n");
exit();
}

*args[i] = i;
}

printf(1, "main: running with %d threads...\n", NUM_THREADS);

// Start all children
for (i=0; i<NUM_THREADS; i++) {
pthread_create(&threads[i], 0, thread, args[i]);
printf(1, "main: created thread with pid %d\n", threads[i].pid);
}

// Wait for all children
for (i=0; i<NUM_THREADS; i++) {
void *retval;
int r;
r = pthread_join(threads[i], &retval);
if (r < 0) {
passed = 0;
}
if (*(int*)retval != i) {
passed = 0;
}
printf(1, "main: thread %d joined...retval=%d\n", i, *(int*)retval);
}

if (passed) {
printf(1, "TEST PASSED!\n");
}
else {
printf(1, "TEST FAILED!\n");
}

// Clean up memory
for (i=0; i<NUM_THREADS; i++) {
free(args[i]);
}

// Exit
exit();
}