Commit 14d1b52b authored by Adam Blank's avatar Adam Blank
Browse files

Merge branch 'submit' into 'master'

submission

See merge request !1
1 merge request!1submission
Pipeline #17840 canceled with stage
Showing with 187 additions and 18 deletions
+187 -18
...@@ -9,8 +9,13 @@ CFLAGS = -Wall -g -std=c99 -pedantic ...@@ -9,8 +9,13 @@ CFLAGS = -Wall -g -std=c99 -pedantic
ASFLAGS = -g ASFLAGS = -g
all: test all: test test_arg test_ret
test_arg: sthread.o queue.o glue.o test_arg.o
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^
test_ret: sthread.o queue.o glue.o test_ret.o
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^
# The simple test program # The simple test program
test: sthread.o queue.o glue.o test.o test: sthread.o queue.o glue.o test.o
...@@ -19,7 +24,7 @@ test: sthread.o queue.o glue.o test.o ...@@ -19,7 +24,7 @@ test: sthread.o queue.o glue.o test.o
# pseudo-target to clean up # pseudo-target to clean up
clean: clean:
$(RM) -f *.o core* *~ test $(RM) -f *.o core* *~ test test_arg test_ret
.PHONY: all clean .PHONY: all clean
......
...@@ -28,7 +28,24 @@ scheduler_context: .quad 0 ...@@ -28,7 +28,24 @@ scheduler_context: .quad 0
__sthread_switch: __sthread_switch:
# Save the process state onto its stack # Save the process state onto its stack
# TODO pushq %rax
pushq %rbx
pushq %rcx
pushq %rdx
pushq %rsi
pushq %rdi
pushq %rbp
pushq %r8
pushq %r9
pushq %r10
pushq %r11
pushq %r12
pushq %r13
pushq %r14
pushq %r15
pushf
# Call the high-level scheduler with the current context as an argument # Call the high-level scheduler with the current context as an argument
movq %rsp, %rdi movq %rsp, %rdi
...@@ -39,7 +56,27 @@ __sthread_switch: ...@@ -39,7 +56,27 @@ __sthread_switch:
# Restore the context to resume the thread. # Restore the context to resume the thread.
__sthread_restore: __sthread_restore:
# TODO # returned context is new stack
movq %rax, %rsp
popf
popq %r15
popq %r14
popq %r13
popq %r12
popq %r11
popq %r10
popq %r9
popq %r8
popq %rbp
popq %rdi
popq %rsi
popq %rdx
popq %rcx
popq %rbx
popq %rax
ret ret
...@@ -62,11 +99,29 @@ __sthread_restore: ...@@ -62,11 +99,29 @@ __sthread_restore:
.globl __sthread_initialize_context .globl __sthread_initialize_context
__sthread_initialize_context: __sthread_initialize_context:
# TODO # %rdi - stackp, %rsi - f, %rdx - arg
# return value in %rax is the stack pointer,
# TODO - Make sure you completely document every part of your # leave 144 bytes for thread context details and return address.
# thread context; what it is, and why you set each value movq %rdi, %rax
# to what you choose. subq $144, %rax
leaq __sthread_finish(%rip), %rdi
movq %rdi, 136(%rax) # kill thread when done with f
movq %rsi, 128(%rax) # address of f to come back to
movq $0, 120(%rax) # rax = 0
movq $0, 112(%rax) # rcx = 0
movq $0, 96(%rax) # rdx = 0
movq $0, 88(%rax) # rsi = 0
movq %rdx, 80(%rax) # rdi = arg
movq $0, 72(%rax) # rbp = 0
movq $0, 64(%rax) # r9 = 0
movq $0, 48(%rax) # r10 = 0
movq $0, 40(%rax) # r11 = 0
movq $0, 32(%rax) # r12 = 0
movq $0, 24(%rax) # r13 = 0
movq $0, 16(%rax) # r14 = 0
movq $0, 8(%rax) # r15 = 0
movq $0, (%rax) # rflags = 0
ret ret
......
...@@ -129,8 +129,43 @@ static void enqueue_thread(Thread *threadp) { ...@@ -129,8 +129,43 @@ static void enqueue_thread(Thread *threadp) {
*/ */
ThreadContext *__sthread_scheduler(ThreadContext *context) { ThreadContext *__sthread_scheduler(ThreadContext *context) {
/* TODO: Replace these lines with your implementation */ if (context != NULL) {
/* TODO */ assert(0); /* TODO */ /* Save the context argument into the current thread. */
current->context = context;
/* Either queue up or deallocate the current thread, based on its state. */
switch(current->state) {
case ThreadRunning:
current->state = ThreadReady; //change to ready and enqueue
enqueue_thread(current);
break;
case ThreadBlocked:
enqueue_thread(current); // enqueue to blocked queue
break;
case ThreadFinished:
__sthread_delete(current); // delete thread
break;
default:
fprintf(stderr, "Thread state has been corrupted: %d\n",
current->state);
exit(1);
}
}
Thread *next = queue_take(&ready_queue); // get next ready thread
// if next exists set current to next and set it to running
if (next != NULL) {
current = next;
current->state = ThreadRunning;
} else {
// otherwise if no blocked threads done, if blocked threads deadlock
if (queue_empty(&blocked_queue)) {
printf("All threads completed successfully\n");
exit(0);
} else {
fprintf(stderr, "System deadlock\n");
exit(1);
}
}
/* Return the next thread to resume executing. */ /* Return the next thread to resume executing. */
return current->context; return current->context;
...@@ -156,9 +191,32 @@ void sthread_start(void) ...@@ -156,9 +191,32 @@ void sthread_start(void)
* structure, and it adds the thread to the Ready queue. * structure, and it adds the thread to the Ready queue.
*/ */
Thread * sthread_create(void (*f)(void *arg), void *arg) { Thread * sthread_create(void (*f)(void *arg), void *arg) {
/* TODO: Replace this function's body with your implementation */ // allocate stack space for thread
/* TODO */ assert(0); /* TODO */ void *memory = (void *) malloc(DEFAULT_STACKSIZE);
return NULL; if (memory == NULL) {
fprintf(stderr, "No memory to allocate thread stack\n");
exit(1);
}
// allocate thread struct
Thread *threadp = (Thread *) malloc(sizeof(Thread));
if (threadp == NULL) {
fprintf(stderr, "No memory to allocate thread struct\n");
free(memory); // no leaks
exit(1);
}
// set state and memory
threadp->state = ThreadReady;
threadp->memory = memory;
// stack pointer at start of region allocated for stack
void *stackp = (void *) ((char *) memory + DEFAULT_STACKSIZE);
threadp->context = __sthread_initialize_context(stackp, f, arg);
// enqueue to ready queue
enqueue_thread(threadp);
return threadp;
} }
...@@ -183,8 +241,10 @@ void __sthread_finish(void) { ...@@ -183,8 +241,10 @@ void __sthread_finish(void) {
* context, as well as the memory for the Thread struct. * context, as well as the memory for the Thread struct.
*/ */
void __sthread_delete(Thread *threadp) { void __sthread_delete(Thread *threadp) {
/* TODO: Replace this function's body with your implementation */ // free memory for context
/* TODO */ assert(0); /* TODO */ free(threadp->memory);
// free thread struct
free(threadp);
} }
......
#include <stdio.h>
#include <stdint.h>
#include "sthread.h"
/* thread prints int arg */
static void test(void *arg) {
printf("%zd\n", (intptr_t) arg);
}
int main(int argc, char **argv) {
sthread_create(test, (void *) 3);
sthread_start();
return 0;
}
\ No newline at end of file
#include <stdio.h>
#include <stdint.h>
#include "sthread.h"
/* print HELLO! arg times yield thread each time */
static void loop(void *arg) {
int i;
for (i = 0; i < (intptr_t) arg; i++) {
printf("HELLO!\n");
sthread_yield();
}
}
int main(int argc, char **argv) {
/* threads with different lifetimes */
sthread_create(loop, (void *) 1);
sthread_create(loop, (void *) 2);
sthread_create(loop, (void *) 3);
sthread_create(loop, (void *) 4);
sthread_start();
return 0;
}
\ No newline at end of file
...@@ -4,6 +4,9 @@ CFLAGS = -Wall -Werror -g -O0 ...@@ -4,6 +4,9 @@ CFLAGS = -Wall -Werror -g -O0
all: greeting all: greeting
greeting.o: greeting.c
output.o: output.s
greeting: greeting.o output.o greeting: greeting.o output.o
$(CC) $(CFLAGS) greeting.o output.o -o greeting $(LDFLAGS) $(CC) $(CFLAGS) greeting.o output.o -o greeting $(LDFLAGS)
......
File added
#include <stdint.h> #include <stdint.h>
int64_t output(void *data, uint64_t size); extern int64_t output(void *data, uint64_t size);
/* INCOMING TRANSMISSION... */ /* INCOMING TRANSMISSION... */
int main() { int main() {
......
# function outputs alien message (writes msg to stdout)
# arg1 (msg address) at %rdi, arg2 (msg size) at %rsi
# returns size of outputted msg stored in %rax
.globl output
output:
movq $1, %rax # syscall write is 1
movq %rsi, %rdx # write arg3 (count) is sizeof(msg)
movq %rdi, %rsi # write arg2 (*buf) is msg
movq $1, %rdi # write arg1 (fd) is 1
syscall # make syscall
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment