提交 4ce84865 创建 作者: Silas Boyd-Wickizer's avatar Silas Boyd-Wickizer

Merge branch 'scale-amd64' of git+ssh://amsterdam.csail.mit.edu/home/am0/6.828/xv6 into scale-amd64

......@@ -11,7 +11,6 @@ UPROGS= \
mapbench \
maptest \
sh \
thrtest \
halt \
time \
sleep \
......
......@@ -4,12 +4,13 @@
#include "mtrace.h"
#include "amd64.h"
#include "uspinlock.h"
#include "pthread.h"
enum { readaccess = 0 };
enum { verbose = 0 };
enum { npg = 1 };
void
void*
thr(void *arg)
{
u64 tid = (u64)arg;
......@@ -34,6 +35,7 @@ thr(void *arg)
exit();
}
}
return 0;
}
int
......@@ -50,11 +52,9 @@ main(int ac, char **av)
// fprintf(1, "mapbench[%d]: start esp %x, nthread=%d\n", getpid(), rrsp(), nthread);
for(int i = 0; i < nthread; i++) {
sbrk(8192);
void *tstack = sbrk(0);
// fprintf(1, "tstack %lx\n", tstack);
int tid = forkt(tstack, (void*) thr, (void *)(u64)i);
for(u64 i = 0; i < nthread; i++) {
pthread_t tid;
pthread_create(&tid, 0, thr, (void*) i);
if (0) fprintf(1, "mapbench[%d]: child %d\n", getpid(), tid);
}
......
......@@ -4,6 +4,7 @@
#include "mtrace.h"
#include "amd64.h"
#include "uspinlock.h"
#include "pthread.h"
static volatile char *p;
static struct uspinlock l;
......@@ -17,8 +18,8 @@ spin(void)
;
}
void
thr(void)
void*
thr(void*)
{
for (;;) {
acquire(&l);
......@@ -54,8 +55,8 @@ main(void)
exit();
}
sbrk(4096);
forkt(sbrk(0), (void*) thr, 0);
pthread_t tid;
pthread_create(&tid, 0, thr, 0);
acquire(&l);
state = 1;
......
#include "types.h"
#include "stat.h"
#include "user.h"
#include "mtrace.h"
#include "amd64.h"
#include "uspinlock.h"
static struct uspinlock l;
static volatile int tcount;
enum { nthread = 8 };
void
thr(void *arg)
{
acquire(&l);
fprintf(1, "thrtest[%d]: arg 0x%lx rsp %lx\n", getpid(), arg, rrsp());
tcount++;
release(&l);
exit();
}
int
main(void)
{
acquire(&l);
fprintf(1, "thrtest[%d]: start esp %x\n", getpid(), rrsp());
for(int i = 0; i < nthread; i++) {
sbrk(8192);
void *tstack = sbrk(0);
int tid = forkt(tstack, (void*) thr, (void*)(u64)(0xc0ffee00|i));
fprintf(1, "thrtest[%d]: child %d\n", getpid(), tid);
}
for(;;){
int lastc = tcount;
fprintf(1, "thrtest[%d]: tcount=%d\n", getpid(), lastc);
release(&l);
if(lastc==nthread)
break;
while(tcount==lastc)
__asm __volatile("");
acquire(&l);
}
release(&l);
fprintf(1, "thrtest[%d]: done\n", getpid());
for(int i = 0; i < nthread; i++)
wait();
exit();
}
......@@ -5,6 +5,7 @@
#include "fcntl.h"
#include "syscall.h"
#include "traps.h"
#include "pthread.h"
char buf[2048];
char name[3];
......@@ -1600,6 +1601,7 @@ preads(void)
void
tls_test(void)
{
printf("tls_test\n");
u64 buf[128];
for (int i = 0; i < sizeof(buf) / sizeof(buf[0]); i++)
......@@ -1626,6 +1628,49 @@ tls_test(void)
fprintf(1, "tls_test ok\n");
}
static pthread_key_t tkey;
static pthread_barrier_t bar0, bar1;
enum { nthread = 8 };
static void*
thr(void *arg)
{
pthread_setspecific(tkey, arg);
pthread_barrier_wait(&bar0);
u64 x = (u64) arg;
if ((x >> 8) != 0xc0ffee)
fprintf(2, "thr: x 0x%lx\n", x);
if (arg != pthread_getspecific(tkey))
fprintf(2, "thr: arg %p getspec %p\n", arg, pthread_getspecific(tkey));
pthread_barrier_wait(&bar1);
return 0;
}
void
thrtest(void)
{
printf("thrtest\n");
pthread_key_create(&tkey, 0);
pthread_barrier_init(&bar0, 0, nthread);
pthread_barrier_init(&bar1, 0, nthread+1);
for(int i = 0; i < nthread; i++) {
pthread_t tid;
pthread_create(&tid, 0, &thr, (void*) (0xc0ffee00ULL | i));
}
pthread_barrier_wait(&bar1);
for(int i = 0; i < nthread; i++)
wait();
printf("thrtest ok\n");
}
int
main(int argc, char *argv[])
{
......@@ -1674,6 +1719,7 @@ main(int argc, char *argv[])
exectest();
tls_test();
thrtest();
exit();
}
......@@ -133,6 +133,20 @@ ltr(u16 sel)
}
static inline void
writefs(u16 v)
{
__asm volatile("movw %0, %%fs" : : "r" (v));
}
static inline u16
readfs(void)
{
u16 v;
__asm volatile("movw %%fs, %0" : "=r" (v));
return v;
}
static inline void
writegs(u16 v)
{
__asm volatile("movw %0, %%gs" : : "r" (v));
......
#pragma once
/*
* Our minimal version of pthreads
*/
#include "atomic.hh"
typedef int pthread_t;
typedef int pthread_attr_t;
typedef int pthread_key_t;
typedef int pthread_barrierattr_t;
typedef std::atomic<unsigned> pthread_barrier_t;
int pthread_create(pthread_t* tid, const pthread_attr_t* attr,
void* (*start)(void*), void* arg);
pthread_t pthread_self(void);
int pthread_key_create(pthread_key_t* key, void (*destructor)(void*));
void* pthread_getspecific(pthread_key_t key);
int pthread_setspecific(pthread_key_t key, void* value);
int pthread_barrier_init(pthread_barrier_t *b,
const pthread_barrierattr_t *attr,
unsigned count);
int pthread_barrier_wait(pthread_barrier_t *b);
......@@ -50,6 +50,7 @@ int atoi(const char*);
// uthread.S
int forkt(void *sp, void *pc, void *arg);
void forkt_setup(u64 pid);
// printf.c
void printf(const char*, ...);
......
......@@ -127,6 +127,8 @@ switchvm(struct proc *p)
lcr3(v2p(p->vmap->pml4)); // switch to new address space
else
switchkvm();
writefs(UDSEG);
writemsr(MSR_FS_BASE, p->user_fs_);
popcli();
......
ULIB = ulib.o usys.o printf.o umalloc.o uthread.o fmt.o stream.o ipc.o
ULIB = ulib.o usys.o printf.o umalloc.o uthread.o fmt.o stream.o ipc.o \
threads.o
ULIB := $(addprefix $(O)/lib/, $(ULIB))
.PRECIOUS: $(O)/lib/%.o
......
#include "types.h"
#include "pthread.h"
#include "user.h"
#include "atomic.hh"
enum { stack_size = 8192 };
static std::atomic<int> nextkey;
struct tlsdata {
void* buf[128];
};
void
forkt_setup(u64 pid)
{
tlsdata* t = (tlsdata*) sbrk(sizeof(*t));
setfs((u64) t);
}
int
pthread_create(pthread_t* tid, const pthread_attr_t* attr,
void* (*start)(void*), void* arg)
{
char* base = (char*) sbrk(stack_size);
int t = forkt(base + stack_size, (void*) start, arg);
if (t < 0)
return t;
*tid = t;
return 0;
}
pthread_t
pthread_self()
{
return getpid();
}
int
pthread_key_create(pthread_key_t *key, void (*destructor)(void*))
{
// Ignore the destructor for now.
*key = nextkey++;
return 0;
}
void*
pthread_getspecific(pthread_key_t key)
{
u64 v;
__asm volatile("movq %%fs:(%1), %0" : "=r" (v) : "r" ((u64) key * 8));
return (void*) v;
}
int
pthread_setspecific(pthread_key_t key, void* value)
{
__asm volatile("movq %0, %%fs:(%1)" : : "r" (value), "r" ((u64) key * 8));
return 0;
}
int
pthread_barrier_init(pthread_barrier_t *b,
const pthread_barrierattr_t *attr, unsigned count)
{
b->store(count);
return 0;
}
int
pthread_barrier_wait(pthread_barrier_t *b)
{
(*b)--;
while (*b != 0)
; // spin
return 0;
}
......@@ -8,20 +8,23 @@ forkt:
pushq %r12
andq $(~0xf), %rdi # new stack ptr amd64 ABI alignment
movq %rdi, %r12
movq %rdx, -16(%r12) # arg
movq %rsi, -8(%r12) # function ptr
subq $0x10, %r12
movq %rdx, 0x00(%r12) # arg
movq %rsi, 0x08(%r12) # function ptr
movq $1, %rdi # flag for sys_fork
movq $SYS_fork, %rax
int $T_SYSCALL
syscall
cmpq $0, %rax # pid/tid
jne 1f
# child
movq -8(%r12), %rax
movq -16(%r12), %rdi
movq %r12, %rsp
movq %rax, %rdi
call forkt_setup
popq %rdi
popq %rax
call *%rax
call exit
1: # parent
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论