//sys Stat(path string, stat *Stat_t) (errno int)
//sys Write(fd int, p []byte) (n int, errno int)
+//sys MultimediaInit(subsys int) (errno int)
+//sys MultimediaShutdown() (errno int)
+
+//sys CondCreate() (cv int, errno int)
+//sys CondWait(cv int, mutex int) (errno int)
+//sys CondSignal(cv int) (errno int)
+//sys CondBroadcast(cv int) (errno int)
+//sys CondTimedWaitAbs(cv int, mutex int, abstime *Timespec) (errno int)
+//sys MutexCreate() (mutex int, errno int)
+//sys MutexLock(mutex int) (errno int)
+//sys MutexUnlock(mutex int) (errno int)
+//sys MutexTryLock(mutex int) (errno int) = SYS_MUTEX_TRYLOCK
+//sys SemCreate() (sema int, errno int)
+//sys SemWait(sema int) (errno int)
+//sys SemPost(sema int) (errno int)
+//sys VideoInit(dx int, dy int) (errno int)
+//sys VideoUpdate(data *uint32) (errno int)
+//sys VideoPollEvent(ev *byte) (errno int)
+//sys VideoShutdown() (errno int)
+//sys AudioInit(fmt int, nreq int, data *int) (errno int)
+//sys AudioShutdown() (errno int)
+//sys AudioStream(data *uint16, size *uintptr) (errno int)
+
// Hand-written
func Seek(fd int, offset int64, whence int) (newoffset int64, errno int) {
return int64(o), int(e);
}
-// Implemented in NaCl but not here:
+// Sleep by waiting on a condition variable that will never be signaled.
+// TODO(rsc): Replace when NaCl adds a proper sleep system call.
+var tcv, tmu int
+
+func init() {
+ tmu, _ = MutexCreate();
+ tcv, _ = CondCreate();
+}
+
+func Sleep(ns int64) (errno int) {
+ ts := NsecToTimespec(ns);
+ var tv Timeval;
+ if errno = Gettimeofday(&tv); errno != 0 {
+ return;
+ }
+ ts.Sec += tv.Sec;
+ ts.Nsec += tv.Usec*1000;
+ switch {
+ case ts.Nsec >= 1e9:
+ ts.Nsec -= 1e9;
+ ts.Sec++;
+ case ts.Nsec <= -1e9:
+ ts.Nsec += 1e9;
+ ts.Sec--;
+ }
+ if errno = MutexLock(tmu); errno != 0 {
+ return;
+ }
+ errno = CondTimedWaitAbs(tcv, tmu, &ts);
+ if e := MutexUnlock(tmu); e != 0 && errno == 0 {
+ errno = e;
+ }
+ return;
+}
+
+// Implemented in NaCl but not here; maybe later:
// SYS_IOCTL
+// SYS_IMC_*
+// SYS_MMAP ???
+// SYS_SRPC_*
+// SYS_SYSCONF
+
+// Implemented in NaCl but not here; used by runtime instead:
// SYS_SYSBRK
// SYS_MMAP
// SYS_MUNMAP
-// SYS_MULTIMEDIA_*
-// SYS_VIDEO_*
-// SYS_AUDIO_*
-// SYS_IMC_*
-// SYS_MUTEX_*
-// SYS_COND_*
// SYS_THREAD_*
// SYS_TLS_*
-// SYS_SRPC_*
-// SYS_SEM_*
// SYS_SCHED_YIELD
-// SYS_SYSCONF
// Not implemented in NaCl but needed to compile other packages.
return ENACL;
}
-// TODO(rsc): There must be a way to sleep, perhaps
-// via the multimedia system calls.
-
-func Sleep(ns int64) (errno int) {
- return ENACL;
-}
-
// NaCL doesn't actually implement Getwd, but it also
// don't implement Chdir, so the fallback algorithm
// fails worse than calling Getwd does.
return;
}
+func MultimediaInit(subsys int) (errno int) {
+ _, _, e1 := Syscall(SYS_MULTIMEDIA_INIT, uintptr(subsys), 0, 0);
+ errno = int(e1);
+ return;
+}
+
+func MultimediaShutdown() (errno int) {
+ _, _, e1 := Syscall(SYS_MULTIMEDIA_SHUTDOWN, 0, 0, 0);
+ errno = int(e1);
+ return;
+}
+
+func CondCreate() (cv int, errno int) {
+ r0, _, e1 := Syscall(SYS_COND_CREATE, 0, 0, 0);
+ cv = int(r0);
+ errno = int(e1);
+ return;
+}
+
+func CondWait(cv int, mutex int) (errno int) {
+ _, _, e1 := Syscall(SYS_COND_WAIT, uintptr(cv), uintptr(mutex), 0);
+ errno = int(e1);
+ return;
+}
+
+func CondSignal(cv int) (errno int) {
+ _, _, e1 := Syscall(SYS_COND_SIGNAL, uintptr(cv), 0, 0);
+ errno = int(e1);
+ return;
+}
+
+func CondBroadcast(cv int) (errno int) {
+ _, _, e1 := Syscall(SYS_COND_BROADCAST, uintptr(cv), 0, 0);
+ errno = int(e1);
+ return;
+}
+
+func CondTimedWaitAbs(cv int, mutex int, abstime *Timespec) (errno int) {
+ _, _, e1 := Syscall(SYS_COND_TIMED_WAIT_ABS, uintptr(cv), uintptr(mutex), uintptr(unsafe.Pointer(abstime)));
+ errno = int(e1);
+ return;
+}
+
+func MutexCreate() (mutex int, errno int) {
+ r0, _, e1 := Syscall(SYS_MUTEX_CREATE, 0, 0, 0);
+ mutex = int(r0);
+ errno = int(e1);
+ return;
+}
+
+func MutexLock(mutex int) (errno int) {
+ _, _, e1 := Syscall(SYS_MUTEX_LOCK, uintptr(mutex), 0, 0);
+ errno = int(e1);
+ return;
+}
+
+func MutexUnlock(mutex int) (errno int) {
+ _, _, e1 := Syscall(SYS_MUTEX_UNLOCK, uintptr(mutex), 0, 0);
+ errno = int(e1);
+ return;
+}
+
+func MutexTryLock(mutex int) (errno int) {
+ _, _, e1 := Syscall(SYS_MUTEX_TRYLOCK, uintptr(mutex), 0, 0);
+ errno = int(e1);
+ return;
+}
+
+func SemCreate() (sema int, errno int) {
+ r0, _, e1 := Syscall(SYS_SEM_CREATE, 0, 0, 0);
+ sema = int(r0);
+ errno = int(e1);
+ return;
+}
+
+func SemWait(sema int) (errno int) {
+ _, _, e1 := Syscall(SYS_SEM_WAIT, uintptr(sema), 0, 0);
+ errno = int(e1);
+ return;
+}
+
+func SemPost(sema int) (errno int) {
+ _, _, e1 := Syscall(SYS_SEM_POST, uintptr(sema), 0, 0);
+ errno = int(e1);
+ return;
+}
+
+func VideoInit(dx int, dy int) (errno int) {
+ _, _, e1 := Syscall(SYS_VIDEO_INIT, uintptr(dx), uintptr(dy), 0);
+ errno = int(e1);
+ return;
+}
+
+func VideoUpdate(data *uint32) (errno int) {
+ _, _, e1 := Syscall(SYS_VIDEO_UPDATE, uintptr(unsafe.Pointer(data)), 0, 0);
+ errno = int(e1);
+ return;
+}
+
+func VideoPollEvent(ev *byte) (errno int) {
+ _, _, e1 := Syscall(SYS_VIDEO_POLL_EVENT, uintptr(unsafe.Pointer(ev)), 0, 0);
+ errno = int(e1);
+ return;
+}
+
+func VideoShutdown() (errno int) {
+ _, _, e1 := Syscall(SYS_VIDEO_SHUTDOWN, 0, 0, 0);
+ errno = int(e1);
+ return;
+}
+
+func AudioInit(fmt int, nreq int, data *int) (errno int) {
+ _, _, e1 := Syscall(SYS_AUDIO_INIT, uintptr(fmt), uintptr(nreq), uintptr(unsafe.Pointer(data)));
+ errno = int(e1);
+ return;
+}
+
+func AudioShutdown() (errno int) {
+ _, _, e1 := Syscall(SYS_AUDIO_SHUTDOWN, 0, 0, 0);
+ errno = int(e1);
+ return;
+}
+
+func AudioStream(data *uint16, size *uintptr) (errno int) {
+ _, _, e1 := Syscall(SYS_AUDIO_STREAM, uintptr(unsafe.Pointer(data)), uintptr(unsafe.Pointer(size)), 0);
+ errno = int(e1);
+ return;
+}
+