// Copyright 2010 The Go Authors.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#include "runtime.h"
#include "os.h"

int8 *goos = "plan9";

void
runtime·minit(void)
{
}

void
runtime·osinit(void)
{
}

void
runtime·goenvs(void)
{
}

void
runtime·initsig(int32 queue)
{
}

extern Tos *_tos;
void
runtime·exit(int32)
{
	int32 fd;
	uint8 buf[128];
	uint8 tmp[16];
	uint8 *p, *q;
	int32 pid;
	
	runtime·memclr(buf, sizeof buf);
	runtime·memclr(tmp, sizeof tmp);
	pid = _tos->pid;

	/* build path string /proc/pid/notepg */
	for(q=tmp; pid > 0;) {
		*q++ = '0' + (pid%10);
		pid = pid/10;
	}
	p = buf;
	runtime·mcpy((void*)p, (void*)"/proc/", 6);
	p += 6;
	for(q--; q >= tmp;)
		*p++ = *q--;
	runtime·mcpy((void*)p, (void*)"/notepg", 7);
	
	/* post interrupt note */
	fd = runtime·open(buf, OWRITE);
	runtime·write(fd, "interrupt", 9);
	runtime·exits(nil);
}

void
runtime·newosproc(M *m, G *g, void *stk, void (*fn)(void))
{
	m->tls[0] = m->id;	// so 386 asm can find it
	if(0){
		runtime·printf("newosproc stk=%p m=%p g=%p fn=%p rfork=%p id=%d/%d ostk=%p\n",
			stk, m, g, fn, runtime·rfork, m->id, m->tls[0], &m);
	}        
	
	if (runtime·rfork(RFPROC|RFMEM|RFNOWAIT, stk, m, g, fn) < 0 )
		runtime·throw("newosproc: rfork failed");
}

// Blocking locks.

// Implement Locks, using semaphores.
// l->key is the number of threads who want the lock.
// In a race, one thread increments l->key from 0 to 1
// and the others increment it from >0 to >1.  The thread
// who does the 0->1 increment gets the lock, and the
// others wait on the semaphore.  When the 0->1 thread
// releases the lock by decrementing l->key, l->key will
// be >0, so it will increment the semaphore to wake up
// one of the others.  This is the same algorithm used
// in Plan 9's user-level locks.

void
runtime·lock(Lock *l)
{
	if(m->locks < 0)
		runtime·throw("lock count");
	m->locks++;
	
	if(runtime·xadd(&l->key, 1) == 1)
		return; // changed from 0 -> 1; we hold lock
	// otherwise wait in kernel
	while(runtime·plan9_semacquire(&l->sema, 1) < 0) {
		/* interrupted; try again */
	}
}

void
runtime·unlock(Lock *l)
{
	m->locks--;
	if(m->locks < 0)
		runtime·throw("lock count");

	if(runtime·xadd(&l->key, -1) == 0)
		return; // changed from 1 -> 0: no contention
	
	runtime·plan9_semrelease(&l->sema, 1);
}


void 
runtime·destroylock(Lock *l)
{
	// nothing
}

// User-level semaphore implementation:
// try to do the operations in user space on u,
// but when it's time to block, fall back on the kernel semaphore k.
// This is the same algorithm used in Plan 9.
void
runtime·usemacquire(Usema *s)
{
	if((int32)runtime·xadd(&s->u, -1) < 0)
		while(runtime·plan9_semacquire(&s->k, 1) < 0) {
			/* interrupted; try again */
		}
}

void
runtime·usemrelease(Usema *s)
{
	if((int32)runtime·xadd(&s->u, 1) <= 0)
		runtime·plan9_semrelease(&s->k, 1);
}


// Event notifications.
void
runtime·noteclear(Note *n)
{
	n->wakeup = 0;
}

void
runtime·notesleep(Note *n)
{
	while(!n->wakeup)
		runtime·usemacquire(&n->sema);
}

void
runtime·notewakeup(Note *n)
{
	n->wakeup = 1;
	runtime·usemrelease(&n->sema);
}

void
os·sigpipe(void)
{
	runtime·throw("too many writes on closed pipe");
}
