Browse files

almost **

  • Loading branch information...
1 parent 93eaedd commit 667cfa2e272902bc1f9654064b6233237f447e56 @lxmonk committed May 11, 2012
Showing with 129 additions and 76 deletions.
  1. +2 −2 user.h
  2. +94 −59 uthread.c
  3. +13 −3 uthread.h
  4. +20 −12 uthread_sanity.c
View
4 user.h
@@ -37,7 +37,7 @@ void* malloc(uint);
void free(void*);
int atoi(const char*);
-#define DEBUG_PRINT(fmt, ...) \
- do { if (T_A_DEBUG) printf(2, "<%s>:%d:[%s()]: " fmt "\n", \
+#define DEBUG_PRINT(level, fmt, ...) \
+ do { if (T_A_DEBUG >= level) printf(2, "<%s>:%d:[%s()]: " fmt "\n", \
__FILE__, __LINE__, __func__, \
__VA_ARGS__); } while (0)
View
153 uthread.c
@@ -3,7 +3,7 @@
#include "fcntl.h"
#include "uthread.h"
-#define T_A_DEBUG 1
+#define T_A_DEBUG 3
#define ROUND_ROBIN 0
#define PRIORITY_BASED 1
@@ -26,7 +26,7 @@ print_tinfo() {
for (i = 0; i < MAX_UTHREADS; i++) {
cur = ut_table.threads[i];
if (cur != 0) {
- DEBUG_PRINT("%d) tid=%d, ss_sp=%x, ss_esp=%x, priority=%d",
+ DEBUG_PRINT(4, "%d) tid=%d, ss_sp=%x, ss_esp=%x, priority=%d",
i, cur->tid, cur->ss_sp, cur->ss_esp,
cur->priority);
}
@@ -35,11 +35,11 @@ print_tinfo() {
int uthread_create(void (*start_func)(), int priority){
int ut_id;
- void* current_esp;
+ /* void* current_esp; */
- DEBUG_PRINT("inside uthread_create", 999);
+ DEBUG_PRINT(4, "inside uthread_create", 999);
if (first_uthread) { /* initialize the uthreads table */
- DEBUG_PRINT("inside 'first_uthread' loop", 999);
+ DEBUG_PRINT(4, "inside 'first_uthread' loop", 999);
ut_table.cur_threads = 0;
ut_table.highest_p = 9;
ut_table.running_tid = -1;
@@ -67,9 +67,11 @@ int uthread_create(void (*start_func)(), int priority){
previous malloc */
return -1;
}
- ut_table.threads[ut_id]->ss_sp += (UTHREAD_STACK_SIZE);
+ ut_table.threads[ut_id]->ss_esp = (ut_table.threads[ut_id]->ss_sp +
+ (UTHREAD_STACK_SIZE - 4));
+ ut_table.threads[ut_id]->ss_ebp = ut_table.threads[ut_id]->ss_esp;
- DEBUG_PRINT("%d: ss_sp is %x," /* stack will be at %x" */, ut_id,
+ DEBUG_PRINT(4, "%d: ss_sp is %x," /* stack will be at %x" */, ut_id,
ut_table.threads[ut_id]->ss_sp);
/* mallocs were successful */
@@ -78,73 +80,95 @@ int uthread_create(void (*start_func)(), int priority){
ut_table.highest_p = priority;
ut_table.threads[ut_id]->priority = priority;
ut_table.threads[ut_id]->tid = ut_id;
- DEBUG_PRINT("ut_id=%d, ut_table.threads[ut_id]=%x, "
+ DEBUG_PRINT(4, "ut_id=%d, ut_table.threads[ut_id]=%x, "
"ut_table.threads[ut_id]->tid=%d, "
"&ut_table.threads[ut_id]->tid=%x",
ut_id, ut_table.threads[ut_id],
ut_table.threads[ut_id]->tid,
&(ut_table.threads[ut_id]->tid));
- if (T_A_DEBUG) {
- print_tinfo();
- }
- STORE_ESP(current_esp);
+ ut_table.threads[ut_id]->entryfunc = start_func;
+ ut_table.threads[ut_id]->virgin = 1;
+ /* if (T_A_DEBUG) { */
+ /* print_tinfo(); */
+ /* } */
+ /* STORE_ESP(current_esp); */
/* create the initial stack for the new thread */
- LOAD_ESP(ut_table.threads[ut_id]->ss_sp);
+ /* LOAD_ESP(ut_table.threads[ut_id]->ss_esp); */
+
+ /* PUSH(wrap_function); */
- PUSH(wrap_function);
/* PUSH(start_func); */
/* PUSH(uthread_exit); */
/* the 'return address' will be calling uthread_exit (after
start_func is done). on later calls, this will be the next
function to call. */
- PUSH(ut_table.threads[ut_id]->ss_sp);
+ /* PUSH(ut_table.threads[ut_id]->ss_sp); */
/* update the ss_esp */
- ut_table.threads[ut_id]->ss_esp = ut_table.threads[ut_id]->ss_sp - 8;
- LOAD_ESP(current_esp); /* restore the calling thread's stack */
+ /* ut_table.threads[ut_id]->ss_esp = ut_table.threads[ut_id]->ss_sp - 8; */
+ /* LOAD_ESP(current_esp); /\* restore the calling thread's stack *\/ */
return ut_id; /* these will be recycled */
}
uthread_t* next_thread(int start) {
uthread_t *next;
- DEBUG_PRINT("inside next", 900);
+ DEBUG_PRINT(4, "inside next", 900);
for (;;start = (start + 1) % MAX_UTHREADS) {
- DEBUG_PRINT("start=%d", start);
+ DEBUG_PRINT(4, "start=%d", start);
next = ut_table.threads[start];
- DEBUG_PRINT("next=%x, next->tid=%d", next, next->tid);
+ DEBUG_PRINT(4, "next=%x, next->tid=%d", next, next->tid);
if (next != 0) {
if (sched == ROUND_ROBIN ||
next->priority == ut_table.highest_p) {
- DEBUG_PRINT("returning thread with tid=%d", next->tid);
+ DEBUG_PRINT(4, "returning thread with tid=%d", next->tid);
return next;
}
}
}
}
uthread_t uthread_self() {
- return *ut_table.threads[ut_table.running_tid];
+ DEBUG_PRINT(3, "returning ut_table.running_tid=%d", ut_table.running_tid);
+ DEBUG_PRINT(3,"ut_table.threads[ut_table.running_tid]->tid=%d",ut_table.threads[ut_table.running_tid]->tid);
+ return *(ut_table.threads[ut_table.running_tid]);
}
+static uthread_t *s_self;
+static uthread_t *s_next;
void uthread_yield() {
/* save_esp */
- uthread_t self;
- uthread_t *next;
-
- self = uthread_self();
- DEBUG_PRINT("self.tid=%d", self.tid);
- STORE_ESP(self.ss_esp);
+ DEBUG_PRINT(3, "inside uthread_yield", 178);
+ s_self = ut_table.threads[uthread_self().tid];
+ DEBUG_PRINT(3, "inside yield s_self->tid=%d", s_self->tid);
+ /* DEBUG_PRINT(4, "self.tid=%d", self.tid); */
+ DEBUG_PRINT(3, "BEFORE STORE_ESP/EBP: s_self->ss_esp=%x, "
+ "s_self->ss_ebp=%x", s_self->ss_esp, s_self->ss_ebp);
+ STORE_ESP(s_self->ss_esp);
+ STORE_EBP(s_self->ss_ebp);
+
+ DEBUG_PRINT(3, "AFTER STORE_ESP/EBP: s_self->ss_esp=%x, "
+ "s_self->ss_ebp=%x", s_self->ss_esp, s_self->ss_ebp);
/* correct uthread_t (self, next), old_epb, return address, (no
function Args) */
- self.ss_esp += (8 + (2 * (sizeof(uthread_t))));
- next = next_thread((self.tid + 1) % MAX_UTHREADS);
- DEBUG_PRINT("next->tid=%d", next->tid);
- ut_table.running_tid = next->tid;
- LOAD_ESP(next->ss_esp);
+ /* s_self->ss_esp += (8 + (2 * (sizeof(uthread_t)))); */
+ s_next = next_thread((s_self->tid + 1) % MAX_UTHREADS);
+ DEBUG_PRINT(3, "next->tid=%d", s_next->tid);
+ ut_table.running_tid = s_next->tid;
+ LOAD_ESP(s_next->ss_esp);
+ LOAD_EBP(s_next->ss_ebp);
+ DEBUG_PRINT(3, "s_next->ss_esp=%x, s_next->ss_ebp=%x",
+ s_next->ss_esp, s_next->ss_ebp);
+ if (s_next->virgin) {
+ /* DEBUG_PRINT(3, "virgin thread\n", 111); */
+ s_next->virgin = 0;
+ PUSH(s_next->entryfunc);
+ CALL(wrap_function);
+ }
/* return to the chosen uthread */
+ return;
}
int get_highest_p() {
@@ -159,18 +183,18 @@ int get_highest_p() {
return cur_max;
}
+static int s_self_tid;
+
void uthread_exit() {
/* very similar to yield, but removing self from the threads table */
- uthread_t self;
- uthread_t *next;
- int self_tid;
- self = uthread_self();
- self_tid = self.tid;
+ /* s_self = uthread_self(); */
+ s_self = ut_table.threads[uthread_self().tid];
+ s_self_tid = s_self->tid;
/* cleanup this thread */
- free(self.ss_sp);
- free(ut_table.threads[self_tid]);
- ut_table.threads[self.tid] = 0;
+ free(s_self->ss_sp);
+ free(ut_table.threads[s_self_tid]);
+ ut_table.threads[s_self->tid] = 0;
ut_table.cur_threads--;
ut_table.highest_p = get_highest_p(); /* now without this thread - who is highest? */
@@ -179,17 +203,23 @@ void uthread_exit() {
}
/* ELSE, pass control to the next thread */
- next = next_thread((self_tid + 1) % MAX_UTHREADS);
- ut_table.running_tid = next->tid;
- LOAD_ESP(next->ss_esp);
+
+ s_next = next_thread((s_self_tid + 1) % MAX_UTHREADS);
+ ut_table.running_tid = s_next->tid;
+
+ LOAD_ESP(s_next->ss_esp);
+ LOAD_EBP(s_next->ss_ebp);
+ if (s_next->virgin) {
+ s_next->virgin = 0;
+ PUSH(s_next->entryfunc);
+ CALL(wrap_function);
+ }
/* return to the chosen uthread */
+ return;
}
int uthread_start_all() {
- uthread_t *next;
- int esp;
-
- DEBUG_PRINT("inside.", 999);
+ DEBUG_PRINT(4, "inside.", 999);
if (first_uthread)
return -1; /* uthread_create wasn't called at all */
@@ -198,17 +228,22 @@ int uthread_start_all() {
if (ut_table.running_tid != -1)
return -1; /* uthread_start_all was already
called before. */
- DEBUG_PRINT("didn't fail - let's do it", 101);
+ DEBUG_PRINT(4, "didn't fail - let's do it", 101);
/* let's do it. */
- next = next_thread(0); /* start with the 1st thread */
- STORE_ESP(esp);
- DEBUG_PRINT("got next thread. tid=%d ESP=%x ss_esp=%x",
- next->tid, esp, next->ss_esp);
- ut_table.running_tid = next->tid;
- DEBUG_PRINT("running thread updated", 78);
- LOAD_ESP(next->ss_esp);
- STORE_ESP(esp);
- DEBUG_PRINT("ESP loaded. ESP=%x ss_esp=%x", esp, next->ss_esp);
+ s_next = next_thread(0); /* start with the 1st thread */
+ /* STORE_ESP(esp); */
+ /* DEBUG_PRINT(4, "got next thread. tid=%d ESP=%x ss_esp=%x", */
+ /* next->tid, esp, next->ss_esp); */
+ ut_table.running_tid = s_next->tid;
+ DEBUG_PRINT(4, "running thread updated", 78);
+ LOAD_ESP(s_next->ss_esp);
+ LOAD_EBP(s_next->ss_ebp);
+
+ s_next->virgin = 0;
+ PUSH(s_next->entryfunc);
+ CALL(wrap_function);
+ /* STORE_ESP(esp); */
+ /* DEBUG_PRINT(4, "ESP loaded. ESP=%x ss_esp=%x", esp, next->ss_esp); */
/* pass control to the chosen uthread */
return 0; /* this should never be reached :) */
}
@@ -228,7 +263,7 @@ int uthread_getpr() {
}
void wrap_function(void (*entry)()) {
- DEBUG_PRINT("wrap_function called", 999);
+ DEBUG_PRINT(4, "wrap_function called", 999);
entry();
uthread_exit();
/* implicitly return to the address stored on the stack.
View
16 uthread.h
@@ -10,10 +10,17 @@
#define LOAD_ESP(var) asm("movl %0, %%esp;" : : "r" ( var ))
// Calls the function func
-#define CALL(addr) asm("call *%0;" : : "r" ( addr ))
+#define CALL(addr) asm("call *%0;" : : "r" ( addr ))
// Pushes the contents of var to the stack
-#define PUSH(var) asm("movl %0, %%edi; push %%edi;" : : "r" ( var ))
+#define PUSH(var) asm("movl %0, %%edi; push %%edi;" : : "r" ( var ))
+
+
+/* A&T macros for EBP */
+#define STORE_EBP(var) asm("movl %%ebp, %0;" : "=r" ( var ))
+
+#define LOAD_EBP(var) asm("movl %0, %%ebp;" : : "r" ( var ))
+/* A&T - end of macros */
#define MAX_UTHREADS 64
@@ -25,8 +32,11 @@ typedef struct
{
int tid; // A unique thread ID within the process
void *ss_sp; // Stack base or pointer
- void *ss_esp; // Stack size
+ void *ss_esp; // Stack pointer
+ void *ss_ebp; /* stack BASE pointer */
int priority; // The priority of the thread 0...9 (0 is highest)
+ void (*entryfunc)();
+ int virgin;
} uthread_t;
typedef struct
View
32 uthread_sanity.c
@@ -2,23 +2,30 @@
#include "types.h"
#include "user.h"
-#define T_A_DEBUG 1
+#define T_A_DEBUG 3
static int k_stat = 0;
void
thread_do() {
- int i, tid;
-
- tid = uthread_self().tid;
- DEBUG_PRINT("inside thread %d", tid);
- for (i=0; i<k_stat; i++) {
- printf(2, "thread %d iteration %d\n", uthread_self().tid, i);
+ int s_i, s_tid;
+ s_tid = uthread_self().tid;
+ for (s_i=0; s_i<k_stat; s_i++) {
+ DEBUG_PRINT(3, "inside thread %d", s_tid);
+ printf(2, "thread %d iteration %d\n", uthread_self().tid, s_i);
uthread_yield();
}
+ DEBUG_PRINT(3, "thread tid=%d exiting. s_i=%d", uthread_self().tid,
+ s_i);
uthread_exit();
}
+void
+show_esp() {
+ int esp;
+ STORE_ESP(esp);
+ DEBUG_PRINT(4, "ESP=%x", esp);
+}
int
main(int argc, char** argv) {
int n;
@@ -28,18 +35,19 @@ main(int argc, char** argv) {
n = atoi(argv[1]);
k_stat = atoi(argv[2]);
- DEBUG_PRINT("n=%d k=%d", n, k_stat);
+ DEBUG_PRINT(4, "n=%d k=%d", n, k_stat);
for (c=0; c < n; c++) {
ret = uthread_create(thread_do, 0);
- DEBUG_PRINT("creating thread %d. ret=%d", c, ret);
+ DEBUG_PRINT(4, "creating thread %d. ret=%d", c, ret);
}
STORE_ESP(esp);
- DEBUG_PRINT("Before 'uthread_start_all' ESP=%x", esp);
- DEBUG_PRINT("calling uthread_start_all", 999);
+ DEBUG_PRINT(4, "Before 'uthread_start_all' ESP=%x", esp);
+ show_esp();
+ DEBUG_PRINT(4, "calling uthread_start_all", 999);
uthread_start_all();
STORE_ESP(esp);
- DEBUG_PRINT("After 'uthread_start_all' ESP=%x", esp);
+ DEBUG_PRINT(4, "After 'uthread_start_all' ESP=%x", esp);
printf(2, "this will not be printed\n");
return 0;
}

0 comments on commit 667cfa2

Please sign in to comment.