#include <9pm/u.h>
#include <9pm/libc.h>
#include <9pm/ns.h>
#include <9pm/thread.h>
#include <9pm/threadimpl.h>

int _threaddebuglevel = 0;

static long	totalmalloc;
void*
_threadmalloc(long size, int z)
{
	void *m;

	m = malloc(size);
	if (m == nil)
		sysfatal("Malloc of size %ld failed: %r\n", size);
	setmalloctag(m, getcallerpc(&size));
	totalmalloc += size;
	if (size > 1000000) {
		fprint(2, "Malloc of size %ld, total %ld\n", size, totalmalloc);
		abort();
	}
	if (z)
		memset(m, 0, size);
	return m;
}

int
threadprint(int fd, char *fmt, ...)
{
	int n;
	va_list arg;
	char *buf;

	buf = _threadmalloc(2048, 0);
	if(buf == nil)
		return -1;
	va_start(arg, fmt);
	doprint(buf, buf+2048, fmt, arg);
	va_end(arg);
	n = write(fd, buf, strlen(buf));
	free(buf);
	return n;
}

void
_threadsysfatal(char *fmt, va_list arg)
{
	char buf[1024];

	doprint(buf, buf+sizeof(buf), fmt, arg);
	if(argv0)
		threadprint(2, "%s: %s\n", argv0, buf);
	else
		threadprint(2, "%s\n", buf);
	threadexitsall(buf);
}

ulong
_threadswtch(jmp_buf from, jmp_buf to, ulong val)
{
	ulong r;

	if((r = setjmp(from)) == 0)
		longjmp(to, val);
	return r;
}
