mtarch.c
00001
00002 #include <stdio.h>
00003 #include "sys/mt.h"
00004
00005 #ifndef __WORDSIZE
00006 #define __WORDSIZE 32
00007 #endif
00008
00009 #ifndef ON_64BIT_ARCH
00010 #if __WORDSIZE == 64
00011 #define ON_64BIT_ARCH 1
00012 #else
00013 #define ON_64BIT_ARCH 0
00014 #endif
00015 #endif
00016
00017 struct frame {
00018 unsigned long flags;
00019 #if ON_64BIT_ARCH
00020 unsigned long rbp;
00021 unsigned long rdi;
00022 unsigned long rsi;
00023 unsigned long rdx;
00024 unsigned long rcx;
00025 unsigned long rbx;
00026 unsigned long rax;
00027 #else
00028 unsigned long ebp;
00029 unsigned long edi;
00030 unsigned long esi;
00031 unsigned long edx;
00032 unsigned long ecx;
00033 unsigned long ebx;
00034 unsigned long eax;
00035 #endif
00036 unsigned long retaddr;
00037 unsigned long retaddr2;
00038 unsigned long data;
00039 };
00040
00041 void
00042 mtarch_init(void)
00043 {
00044 }
00045
00046 void
00047 mtarch_start(struct mtarch_thread *t,
00048 void (*function)(void *), void *data)
00049 {
00050 struct frame *f = (struct frame *)&t->stack[MTARCH_STACKSIZE - sizeof(struct frame)/sizeof(unsigned long)];
00051 int i;
00052
00053 for(i = 0; i < MTARCH_STACKSIZE; ++i) {
00054 t->stack[i] = i;
00055 }
00056
00057 memset(f, 0, sizeof(struct frame));
00058 f->retaddr = (unsigned long)function;
00059 f->data = (unsigned long)data;
00060 t->sp = (unsigned long)&f->flags;
00061 #if ON_64BIT_ARCH
00062 f->rbp = (unsigned long)&f->rax;
00063 #else
00064 f->ebp = (unsigned long)&f->eax;
00065 #endif
00066 }
00067
00068 static struct mtarch_thread *running_thread;
00069
00070 static void
00071 sw(void)
00072 {
00073
00074 #if ON_64BIT_ARCH
00075 __asm__ (
00076 "pushq %rax\n\t"
00077 "pushq %rbx\n\t"
00078 "pushq %rcx\n\t"
00079 "pushq %rdx\n\t"
00080 "pushq %rsi\n\t"
00081 "pushq %rdi\n\t"
00082 "pushq %rbp\n\t"
00083 "pushq %rbp\n\t");
00084 #else
00085 __asm__ (
00086 "pushl %eax\n\t"
00087 "pushl %ebx\n\t"
00088 "pushl %ecx\n\t"
00089 "pushl %edx\n\t"
00090 "pushl %esi\n\t"
00091 "pushl %edi\n\t"
00092 "pushl %ebp\n\t"
00093 "pushl %ebp\n\t");
00094 #endif
00095
00096
00097 #if ON_64BIT_ARCH
00098 __asm__ ("movq %0, %%rax\n\t" : : "m" (running_thread));
00099 __asm__ (
00100 "movq (%rax), %rbx\n\t"
00101 "movq %rsp, (%rax)\n\t"
00102 "movq %rbx, %rsp\n\t"
00103 );
00104 #else
00105 __asm__ ("movl %0, %%eax\n\t" : : "m" (running_thread));
00106 __asm__ (
00107 "movl (%eax), %ebx\n\t"
00108 "movl %esp, (%eax)\n\t"
00109 "movl %ebx, %esp\n\t"
00110 );
00111 #endif
00112
00113
00114 #if ON_64BIT_ARCH
00115 __asm__ (
00116 "popq %rbp\n\t"
00117 "popq %rbp\n\t"
00118 "popq %rdi\n\t"
00119 "popq %rsi\n\t"
00120 "popq %rdx\n\t"
00121 "popq %rcx\n\t"
00122 "popq %rbx\n\t"
00123 "popq %rax\n\t"
00124
00125 "leave\n\t"
00126 "ret\n\t"
00127 );
00128 #else
00129 __asm__ (
00130 "popl %ebp\n\t"
00131 "popl %ebp\n\t"
00132 "popl %edi\n\t"
00133 "popl %esi\n\t"
00134 "popl %edx\n\t"
00135 "popl %ecx\n\t"
00136 "popl %ebx\n\t"
00137 "popl %eax\n\t"
00138
00139 "leave\n\t"
00140 "ret\n\t"
00141 );
00142 #endif
00143
00144 }
00145
00146
00147 void
00148 mtarch_exec(struct mtarch_thread *t)
00149 {
00150 running_thread = t;
00151 sw();
00152 running_thread = NULL;
00153 }
00154
00155 void
00156 mtarch_remove(void)
00157 {
00158 }
00159
00160 void
00161 mtarch_yield(void)
00162 {
00163 sw();
00164 }
00165
00166 void
00167 mtarch_pstop(void)
00168 {
00169 }
00170
00171 void
00172 mtarch_pstart(void)
00173 {
00174 }
00175
00176 int
00177 mtarch_stack_usage(struct mt_thread *t)
00178 {
00179 int i;
00180 for(i = 0; i < MTARCH_STACKSIZE; ++i) {
00181 if(t->thread.stack[i] != i) {
00182 return MTARCH_STACKSIZE - i;
00183 }
00184 }
00185 return -1;
00186 }
00187