/*
 * POSIX.4 cpu clocks support
 *
 * Written by J. Vidal
 * Copyright (C) Dec, 2003 OCERA Consortium.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation version 2.
 *
 */

#include <rtl_cpuclocks.h>

#ifdef CONFIG_OC_EXECTIMERS

static int cpuclock_init (struct rtl_clock *c) { 
    	rtl_printf("cpuclock_init called from %p\n", __builtin_return_address(0));
	return -1; 
}

static void cpuclock_uninit (struct rtl_clock *c) {

    if (!c) {
	errno=EINVAL;
	return ;
    }
    
    if ((pthread_self() != pthread_linux())) {
	return ;
    }
    
    kfree(c);
    
    return; 
    
}

static hrtime_t cpuclock_gethrtime (struct rtl_clock *c)
{
	/* no error checking for performance issues */	
		return c->value;
}

static int cpuclock_sethrtime(struct rtl_clock *c, hrtime_t t)
{
	/* no error checking for performance issues */	
  	c->value=t;	
	return 0;
}

static int defsettimer(struct rtl_clock *c, hrtime_t interval)
{
	rtl_printf("defsettimer called from %p\n", __builtin_return_address(0));
	return -1;
}

static int defsettimermode (struct rtl_clock *c, int mode)
{
	rtl_printf("defsettimermode called from %p\n", __builtin_return_address(0));
	return -1;
}

static void default_handler( struct pt_regs *regs) { return ; }

int init_cpuclock(clockid_t *c) {

       *c=(struct rtl_clock *)kmalloc(sizeof(struct rtl_clock), GFP_KERNEL);

       if (!(*c)){
	   rtl_printf("Can't allocate memory for cpu clock during thread creation\n");
	   return EAGAIN ;
       } /*
	 else { rtl_printf("init_cpuclock: kmalloc task->cpuclock: %p \n",*c); } 
	*/       

	(*c)->init= cpuclock_init;
	(*c)->uninit=cpuclock_uninit;
	(*c)->gethrtime= cpuclock_gethrtime;
	(*c)->sethrtime= cpuclock_sethrtime;
	(*c)->settimer= defsettimer;
	(*c)->settimermode= defsettimermode ;
	(*c)->handler=default_handler;
        (*c)->mode = RTL_CLOCK_MODE_EXECTIME;
	(*c)->resolution= 0;
	(*c)->value = 0;
	(*c)->delta = 0;
/*	(*c)->lock = PTHREAD_SPINLOCK_INITIALIZER;
	(*c)->arch = RTL_CLOCK_ARCH_INITIALIZER;
*/
	return 0;
}

int pthread_getcpuclockid(pthread_t thread_id, clockid_t *clock_id){

        if ( thread_id && thread_id->magic == RTL_THREAD_MAGIC){
	    *clock_id=thread_id->cpuclock;
	    return 0;
	} else /* not a valid thread */ {
	    return ESRCH;
	}

}

#endif
