]> Cypherpunks.ru repositories - gostls13.git/commitdiff
more 386 runtime fixes.
authorRuss Cox <rsc@golang.org>
Thu, 4 Jun 2009 18:16:03 +0000 (11:16 -0700)
committerRuss Cox <rsc@golang.org>
Thu, 4 Jun 2009 18:16:03 +0000 (11:16 -0700)
can pass many tests;
current stumbling block is an 8l bug.

R=r
DELTA=122  (83 added, 8 deleted, 31 changed)
OCL=29872
CL=29876

12 files changed:
src/cmd/clean.bash
src/cmd/gobuild/Makefile
src/cmd/make.bash
src/lib/net/fd_darwin.go
src/lib/syscall/asm_darwin_386.s
src/lib/syscall/syscall_darwin_386.go
src/lib/syscall/syscall_darwin_amd64.go
src/runtime/darwin/386/sys.s
src/runtime/darwin/amd64/sys.s
src/runtime/darwin/thread.c
src/runtime/runtime.h
test/env.go

index 81cbbec1e700f8e8d6cfb191c1eede181c5af578..262bcca1fdadb9c053f51c7050a87ee2f162573e 100644 (file)
@@ -3,7 +3,7 @@
 # Use of this source code is governed by a BSD-style
 # license that can be found in the LICENSE file.
 
-for i in cc 6l 6a 6c 8l 8a 8c 5l 5a 5c gc 6g ar db nm acid cov gobuild godefs prof gotest
+for i in cc 6l 6a 6c 8l 8a 8c 8g 5l 5a 5c 5g gc 6g ar db nm acid cov gobuild godefs prof gotest
 do
        cd $i
        make clean
index 8c0eb523b065f1a20f0de537b9a3e51c441c1a23..cb326c24f7658f8c9b4ca81412f6d6b1847e09c1 100644 (file)
@@ -2,10 +2,14 @@
 # Use of this source code is governed by a BSD-style
 # license that can be found in the LICENSE file.
 
-# sadly, not auto-generated
+# ironically, not auto-generated
 
-O=6
-OS=568vqo
+O_arm=5
+O_amd64=6
+O_386=8
+OS=568vq
+
+O=$(O_$(GOARCH))
 GC=$(O)g
 CC=$(O)c -FVw
 AS=$(O)a
index 08cffbb9b0161b668882fb54e91c697ff49313ac..f406e358af2e0796c2b4a3fbe48ae1befdaa0811 100644 (file)
@@ -7,12 +7,21 @@ set -e
 
 bash clean.bash
 
-cd 6l
+case "$GOARCH" in
+386)   O=8;;
+amd64) O=6;;
+arm)   O=5;;
+*)
+       echo 'unknown $GOARCH' 1>&2
+       exit 1
+esac
+
+cd ${O}l
 bash mkenam
 make enam.o
 cd ..
 
-for i in cc 6l 6a 6c gc 6g ar db nm acid cov godefs prof gotest
+for i in cc ${O}l ${O}a ${O}c gc ${O}g ar db nm acid cov godefs prof gotest
 do
        echo; echo; echo %%%% making $i %%%%; echo
        cd $i
index 3d1025d516b6bc8a4671536621bcab11e7585142..42bf512210063a062b5e53c1b8fefd865959c28a 100644 (file)
@@ -31,7 +31,7 @@ func newpollster() (p *pollster, err os.Error) {
 }
 
 func (p *pollster) AddFD(fd int, mode int, repeat bool) os.Error {
-       var kmode int16;
+       var kmode int;
        if mode == 'r' {
                kmode = syscall.EVFILT_READ
        } else {
@@ -39,23 +39,21 @@ func (p *pollster) AddFD(fd int, mode int, repeat bool) os.Error {
        }
        var events [1]syscall.Kevent_t;
        ev := &events[0];
-       ev.Ident = uint64(fd);
-       ev.Filter = kmode;
-
        // EV_ADD - add event to kqueue list
        // EV_RECEIPT - generate fake EV_ERROR as result of add,
        //      rather than waiting for real event
        // EV_ONESHOT - delete the event the first time it triggers
-       ev.Flags = syscall.EV_ADD | syscall.EV_RECEIPT;
+       flags := syscall.EV_ADD | syscall.EV_RECEIPT;
        if !repeat {
-               ev.Flags |= syscall.EV_ONESHOT
+               flags |= syscall.EV_ONESHOT
        }
+       syscall.SetKevent(ev, fd, kmode, flags);
 
        n, e := syscall.Kevent(p.kq, &events, &events, nil);
        if e != 0 {
                return os.ErrnoToError(e)
        }
-       if n != 1 || (ev.Flags & syscall.EV_ERROR) == 0 || ev.Ident != uint64(fd) || ev.Filter != kmode {
+       if n != 1 || (ev.Flags & syscall.EV_ERROR) == 0 || int(ev.Ident) != fd || int(ev.Filter) != kmode {
                return kqueuePhaseError
        }
        if ev.Data != 0 {
@@ -65,7 +63,7 @@ func (p *pollster) AddFD(fd int, mode int, repeat bool) os.Error {
 }
 
 func (p *pollster) DelFD(fd int, mode int) {
-       var kmode int16;
+       var kmode int;
        if mode == 'r' {
                kmode = syscall.EVFILT_READ
        } else {
@@ -73,13 +71,10 @@ func (p *pollster) DelFD(fd int, mode int) {
        }
        var events [1]syscall.Kevent_t;
        ev := &events[0];
-       ev.Ident = uint64(fd);
-       ev.Filter = kmode;
-
        // EV_DELETE - delete event from kqueue list
        // EV_RECEIPT - generate fake EV_ERROR as result of add,
        //      rather than waiting for real event
-       ev.Flags = syscall.EV_DELETE | syscall.EV_RECEIPT;
+       syscall.SetKevent(ev, fd, kmode, syscall.EV_DELETE | syscall.EV_RECEIPT);
        syscall.Kevent(p.kq, &events, &events, nil);
 }
 
@@ -90,9 +85,7 @@ func (p *pollster) WaitFD(nsec int64) (fd int, mode int, err os.Error) {
                        if t == nil {
                                t = new(syscall.Timespec);
                        }
-                       t.Sec = nsec / 1e9;
-                       t.Nsec = int64(nsec % 1e9);
-//                     *t = syscall.NsecToTimespec(nsec);
+                       *t = syscall.NsecToTimespec(nsec);
                }
                nn, e := syscall.Kevent(p.kq, nil, &p.eventbuf, t);
                if e != 0 {
index 7fb90c28a51b769c2ae0dbfdb7252d1aeaff81c1..a8ec5b00cf64efa9fc940c57e8614e07f5beb6ee 100644 (file)
@@ -48,7 +48,7 @@ TEXT  syscall·Syscall6(SB),7,$0
        MOVSL
        MOVSL
        INT     $0x80
-       JAE     ok
+       JAE     ok6
        MOVL    $-1, 32(SP)     // r1
        MOVL    $-1, 36(SP)     // r2
        MOVL    AX, 40(SP)              // errno
index 6f82e04e48c38b971d1b44b63bf7f7644694d2d1..5633d7c034fa3e0e0f39454299197ea7ac60a6b9 100644 (file)
@@ -6,6 +6,10 @@ package syscall
 
 import "syscall"
 
+func Getpagesize() int {
+       return 4096
+}
+
 func TimespecToNsec(ts Timespec) int64 {
        return int64(ts.Sec)*1e9 + int64(ts.Nsec);
 }
@@ -38,3 +42,8 @@ func Gettimeofday(tv *Timeval) (errno int) {
        return err;
 }
 
+func SetKevent(k *Kevent_t, fd, mode, flags int) {
+       k.Ident = uint32(fd);
+       k.Filter = int16(mode);
+       k.Flags = uint16(flags);
+}
index 86202322306963b486f1469797391fee4f7983ab..f7a93f1216901237e1165fa97a747a13723f321a 100644 (file)
@@ -42,3 +42,8 @@ func Gettimeofday(tv *Timeval) (errno int) {
        return err;
 }
 
+func SetKevent(k *Kevent_t, fd, mode, flags int) {
+       k.Ident = uint64(fd);
+       k.Filter = int16(mode);
+       k.Flags = uint16(flags);
+}
index 1ad6d2acebc1154297969238edf19915acdfadee..bbcb622d5f44261638dc9b761ab28b90b6b9d628 100644 (file)
@@ -88,25 +88,76 @@ TEXT sigaltstack(SB),7,$0
        CALL    notok(SB)
        RET
 
-TEXT bsdthread_create(SB),7,$0
+// void bsdthread_create(void *stk, M *m, G *g, void (*fn)(void))
+// System call args are: func arg stack pthread flags.
+TEXT bsdthread_create(SB),7,$32
        MOVL    $360, AX
+       // 0(SP) is where the caller PC would be; kernel skips it
+       MOVL    func+12(FP), BX
+       MOVL    BX, 4(SP)       // func
+       MOVL    m+4(FP), BX
+       MOVL    BX, 8(SP)       // arg
+       MOVL    stk+0(FP), BX
+       MOVL    BX, 12(SP)      // stack
+       MOVL    g+8(FP), BX
+       MOVL    BX, 16(SP)      // pthread
+       MOVL    $0x1000000, 20(SP)      // flags = PTHREAD_START_CUSTOM
        INT     $0x80
        JAE     2(PC)
        CALL    notok(SB)
        RET
 
+// The thread that bsdthread_create creates starts executing here,
+// because we registered this function using bsdthread_register
+// at startup.
+//     AX = "pthread" (= g)
+//     BX = mach thread port
+//     CX = "func" (= fn)
+//     DX = "arg" (= m)
+//     DI = stack top
+//     SI = flags (= 0x1000000)
+//     SP = stack - C_32_STK_ALIGN
 TEXT bsdthread_start(SB),7,$0
-       CALL    notok(SB)
+       // set up ldt 7+id to point at m->tls.
+       // m->tls is at m+40.  newosproc left
+       // the m->id in tls[0].
+       LEAL    40(DX), BP
+       MOVL    0(BP), DI
+       ADDL    $7, DI  // m0 is LDT#7. count up.
+       // setldt(tls#, &tls, sizeof tls)
+       PUSHAL  // save registers
+       PUSHL   $32     // sizeof tls
+       PUSHL   BP      // &tls
+       PUSHL   DI      // tls #
+       CALL    setldt(SB)
+       POPL    AX
+       POPL    AX
+       POPL    AX
+       POPAL
+       SHLL    $3, DI  // segment# is ldt*8 + 7.
+       ADDL    $7, DI
+       MOVW    DI, FS
+
+       // Now segment is established.  Initialize m, g.
+       MOVL    AX, 0(FS)       // g
+       MOVL    DX, 4(FS)       // m
+       MOVL    BX, 20(DX)      // m->procid = thread port (for debuggers)
+       CALL    CX      // fn()
+       CALL    exit1(SB)
        RET
 
+// void bsdthread_register(void)
+// registers callbacks for threadstart (see bsdthread_create above
+// and wqthread and pthsize (not used).  returns 0 on success.
 TEXT bsdthread_register(SB),7,$40
        MOVL    $366, AX
-       MOVL    $bsdthread_start(SB), 0(SP)     // threadstart
-       MOVL    $0, 4(SP)       // wqthread, not used by us
-       MOVL    $0, 8(SP)       // pthsize, not used by us
-       MOVL    $0, 12(SP)      // paranoia
-       MOVL    $0, 16(SP)
+       // 0(SP) is where kernel expects caller PC; ignored
+       MOVL    $bsdthread_start(SB), 4(SP)     // threadstart
+       MOVL    $0, 8(SP)       // wqthread, not used by us
+       MOVL    $0, 12(SP)      // pthsize, not used by us
+       MOVL    $0, 16(SP)      // paranoia
        MOVL    $0, 20(SP)
+       MOVL    $0, 24(SP)
        INT     $0x80
        JAE     2(PC)
        CALL    notok(SB)
index 4238cd185882a77041889162c16ed63c7edea8ff..b46c823ae4f9d1a9d63bfa627711240cfa7c88ba 100644 (file)
@@ -157,6 +157,7 @@ TEXT bsdthread_create(SB),7,$-8
        MOVQ    m+16(SP), SI    // "arg"
        MOVQ    stk+8(SP), DX   // stack
        MOVQ    g+24(SP), R10   // "pthread"
+// TODO(rsc): why do we get away with 0 flags here but not on 386?
        MOVQ    $0, R8  // flags
        MOVQ    $(0x2000000+360), AX    // bsdthread_create
        SYSCALL
index c780e1619721fb8be6db29a8e487693fa48c627f..79267085eda7fb1f415f660aa0ec898c83a69ff7 100644 (file)
@@ -144,13 +144,15 @@ notewakeup(Note *n)
 void
 osinit(void)
 {
-       // Register our thread-creation callback (see sys_amd64_darwin.s).
+       // Register our thread-creation callback (see {amd64,386}/sys.s).
        bsdthread_register();
 }
 
 void
 newosproc(M *m, G *g, void *stk, void (*fn)(void))
 {
+       // printf("newosproc m=%p g=%p stk=%p fn=%p\n", m, g, stk, fn);
+       m->tls[0] = m->id;      // so 386 asm can find it
        bsdthread_create(stk, m, g, fn);
 }
 
index 8b92c446c8219f962ab2a7b0d22e266997be8eab..8c20c1d02177c6475d1e8a989a0ad62ec23ea87f 100644 (file)
@@ -168,7 +168,8 @@ struct      M
        uint64  procid;         // for debuggers - must not move
        G*      gsignal;        // signal-handling G - must not move
        G*      curg;           // current running goroutine - must not move
-       G*      lastg;          // last running goroutine - to emulate fifo
+       G*      lastg;          // last running goroutine - to emulate fifo - must not move
+       uint32  tls[8];         // thread-local storage (for 386 extern register) - must not move
        Gobuf   sched;
        Gobuf   morestack;
        byte*   moresp;
index 88cec4546b83b2b99d29a3521aa7bddd0fda1a1c..db76ee49f31d903aac93ad21f8dd331a3fa11e80 100644 (file)
@@ -14,7 +14,7 @@ func main() {
                print("$GOARCH: ", e0.String(), "\n");
                os.Exit(1);
        }
-       if ga != "amd64" {
+       if ga != "amd64" && ga != "386" && ga != "arm" {
                print("$GOARCH=", ga, "\n");
                os.Exit(1);
        }