// Copyright 2009 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.

#define _GNU_SOURCE
#include <stdio.h>
#include <errno.h>
#include <linux/futex.h>
#include <sys/syscall.h>
#include <sys/time.h>
#include <pthread.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>

#define nil ((void*)0)

/*
 * gcc implementation of src/pkg/runtime/linux/thread.c
 */
typedef struct Lock Lock;
typedef struct Note Note;
typedef uint32_t uint32;

struct Lock
{
	uint32 key;
	uint32 sema;	// ignored
};

struct Note
{
	Lock lock;
	uint32 pad;
};

static struct timespec longtime =
{
	1<<30,	// 34 years
	0
};

static int
cas(uint32 *val, uint32 old, uint32 new)
{
	int ret;

	__asm__ __volatile__(
		"lock; cmpxchgl %2, 0(%3)\n"
		"setz %%al\n"
	:	"=a" (ret)
	:	"a" (old),
		"r" (new),
		"r" (val)
	:	"memory", "cc"
	);

	return ret & 1;
}

static void
futexsleep(uint32 *addr, uint32 val)
{
	int ret;

	ret = syscall(SYS_futex, (int*)addr, FUTEX_WAIT, val, &longtime, nil, 0);
	if(ret >= 0 || errno == EAGAIN || errno == EINTR)
		return;
	fprintf(stderr, "futexsleep: %s\n", strerror(errno));
	*(int*)0 = 0;
}

static void
futexwakeup(uint32 *addr)
{
	int ret;

	ret = syscall(SYS_futex, (int*)addr, FUTEX_WAKE, 1, nil, nil, 0);
	if(ret >= 0)
		return;
	fprintf(stderr, "futexwakeup: %s\n", strerror(errno));
	*(int*)0 = 0;
}

static void
futexlock(Lock *l)
{
	uint32 v;

again:
	v = l->key;
	if((v&1) == 0){
		if(cas(&l->key, v, v|1)){
			// Lock wasn't held; we grabbed it.
			return;
		}
		goto again;
	}

	if(!cas(&l->key, v, v+2))
		goto again;

	futexsleep(&l->key, v+2);
	for(;;){
		v = l->key;
		if((int)v < 2) {
			fprintf(stderr, "futexsleep: invalid key %d\n", (int)v);
			*(int*)0 = 0;
		}
		if(cas(&l->key, v, v-2))
			break;
	}
	goto again;
}

static void
futexunlock(Lock *l)
{
	uint32 v;

again:
	v = l->key;
	if((v&1) == 0)
		*(int*)0 = 0;
	if(!cas(&l->key, v, v&~1))
		goto again;

	// If there were waiters, wake one.
	if(v & ~1)
		futexwakeup(&l->key);
}

static void
lock(Lock *l)
{
	futexlock(l);
}

static void
unlock(Lock *l)
{
	futexunlock(l);
}

void
noteclear(Note *n)
{
	n->lock.key = 0;
	futexlock(&n->lock);
}

static void
notewakeup(Note *n)
{
	futexunlock(&n->lock);
}

static void
notesleep(Note *n)
{
	futexlock(&n->lock);
	futexunlock(&n->lock);
}

/*
 * runtime Cgo server.
 * gcc half of src/pkg/runtime/cgocall.c
 */

typedef struct CgoWork CgoWork;
typedef struct CgoServer CgoServer;
typedef struct Cgo Cgo;

struct Cgo
{
	Lock lock;
	CgoServer *idle;
	CgoWork *whead;
	CgoWork *wtail;
};

struct CgoServer
{
	CgoServer *next;
	Note note;
	CgoWork *work;
};

struct CgoWork
{
	CgoWork *next;
	Note note;
	void (*fn)(void*);
	void *arg;
};

Cgo cgo;

static void newserver(void);

void
initcgo(void)
{
	newserver();
}

static void* go_pthread(void*);

/*
 * allocate servers to handle any work that has piled up
 * and one more server to sit idle and wait for new work.
 */
static void
newserver(void)
{
	CgoServer *f;
	CgoWork *w, *next;
	pthread_t p;

	lock(&cgo.lock);
	// kick off new servers with work to do
	for(w=cgo.whead; w; w=next) {
		next = w;
		w->next = nil;
		f = malloc(sizeof *f);
		memset(f, 0, sizeof *f);
		f->work = w;
		noteclear(&f->note);
		notewakeup(&f->note);
		if(pthread_create(&p, nil, go_pthread, f) < 0) {
			fprintf(stderr, "pthread_create: %s\n", strerror(errno));
			*(int*)0 = 0;
		}
	}
	cgo.whead = nil;
	cgo.wtail = nil;

	// kick off one more server to sit idle
	if(cgo.idle == nil) {
		f = malloc(sizeof *f);
		memset(f, 0, sizeof *f);
		f->next = cgo.idle;
		noteclear(&f->note);
		cgo.idle = f;
		if(pthread_create(&p, nil, go_pthread, f) < 0) {
			fprintf(stderr, "pthread_create: %s\n", strerror(errno));
			*(int*)0 = 0;
		}
	}
	unlock(&cgo.lock);
}

static void*
go_pthread(void *v)
{
	CgoServer *f;
	CgoWork *w;

	// newserver queued us; wait for work
	f = v;
	goto wait;

	for(;;) {
		// kick off new server to handle requests while we work
		newserver();

		// do work
		w = f->work;
		w->fn(w->arg);
		notewakeup(&w->note);
		f->work = nil;

		// take some work if available
		lock(&cgo.lock);
		if((w = cgo.whead) != nil) {
			cgo.whead = w->next;
			if(cgo.whead == nil)
				cgo.wtail = nil;
			unlock(&cgo.lock);
			f->work = w;
			continue;
		}

		// otherwise queue
		f->work = nil;
		noteclear(&f->note);
		f->next = cgo.idle;
		cgo.idle = f;
		unlock(&cgo.lock);

wait:
		// wait for work
		notesleep(&f->note);
	}
}

