/**********************************************************************
 
	Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
	This program is free software; you can redistribute it 
	and/or modify it under the terms of the GLOBALBASE 
	Library General Public License (G-LGPL) as published by 

	http://www.globalbase.org/
 
	This program is distributed in the hope that it will be 
	useful, but WITHOUT ANY WARRANTY; without even the 
	implied warranty of MERCHANTABILITY or FITNESS FOR A 
	PARTICULAR PURPOSE.

**********************************************************************/


#include	<stdlib.h>
#include	"utils.h"
#include	"memory_debug.h"
#include	"xl.h"


#define BUFFER_THREAD_LEN	11

typedef struct buffer {
	THREAD_AREA_HEADER	h;
	int			type;
	int			pos;
} BUFFER;

THREAD_AREA	cpu_ta;

void
set_cpu_msg_close_gc(BUFFER * bf)
{
}

void
init_cpu_msg()
{
THREAD_AREA param;
	param.ent_size = BUFFER_THREAD_LEN;
	param.area_size = sizeof(BUFFER);
	param.close_gc = set_cpu_msg_close_gc;
	init_thread_area(&cpu_ta,&param);
}

void
set_cpu_msg(int pos)
{
BUFFER * bf;
	init_cpu_msg();
	bf = get_my_area(&cpu_ta);
	bf->pos = pos;
}


void
set_cpu_thr_type(int type)
{
BUFFER * bf;
	init_cpu_msg();
	bf = get_my_area(&cpu_ta);
	bf->pos = 0;
	bf->type = type;
}

typedef struct buf_list {
	BUFFER			b;
	struct buf_list *	next;
} BUF_LIST;

typedef struct cpu_w {
	BUF_LIST *		ret;
} CPU_W;


XL_SEXP * gv_cpu();

void
init_gv_cpu(XLISP_ENV * e)
{
	set_env(e,l_string(std_cm,"gv-cpu"),
		get_func_prim(gv_cpu,FO_APPLICATIVE,0,1,1));
}

int
gv_cpu_func(BUFFER * th,CPU_W * w)
{
BUF_LIST * b;
	b = d_alloc(sizeof(*b));
	b->b = *th;
	b->next = w->ret;
	w->ret = b;
	return 0;
}

XL_SEXP *
gv_cpu()
{
CPU_W w;
XL_SEXP * ret;
BUF_LIST * bp, * bpp;
	w.ret = 0;
	scan_ta(&cpu_ta,gv_cpu_func,&w);

	ret = 0;
	for ( bp = w.ret ; bp ; bp = bp->next ) {
		ret = cons(
			List(get_integer(bp->b.h.tid,0),
				get_integer(bp->b.type,0),
				get_integer(bp->b.pos,0),
				-1),
			ret);
	}
	bp = w.ret;
	for ( ; bp ; ) {
		bpp = bp;
		bp = bp->next;
		d_f_ree(bpp);
	}

	return cons(
		List(n_get_symbol("fd"),
			get_integer(s_check_resource2(0),0),
			-1),
		ret);
}

int
gv_cpu_direct_func(BUFFER * th,CPU_W * w)
{
	printf("(i:%i t:%i p:%i)",
		th->h.tid,
		th->type,
		th->pos);
	return 0;
}

void
gv_cpu_direct()
{
CPU_W w;
	w.ret = 0;
	printf("TH ==> ");
	scan_ta(&cpu_ta,gv_cpu_direct_func,&w);
	printf("END\n");
}
