diff -Nupr linux-2.6.13.2.orig/Makefile linux-2.6.13.2/Makefile
--- linux-2.6.13.2.orig/Makefile	2005-09-17 10:02:12.000000000 +0900
+++ linux-2.6.13.2/Makefile	2005-09-28 03:15:21.741495760 +0900
@@ -607,7 +607,9 @@ libs-y		:= $(libs-y1) $(libs-y2)
 # symbols to the kernel.
 #
 # System.map is generated to document addresses of all kernel symbols
-
+ifeq ($(strip $(CONFIG_CABI)),y)
+libgcc=$(shell $(CC) -print-libgcc-file-name)
+endif
 vmlinux-init := $(head-y) $(init-y)
 vmlinux-main := $(core-y) $(libs-y) $(drivers-y) $(net-y)
 vmlinux-all  := $(vmlinux-init) $(vmlinux-main)
@@ -618,7 +620,7 @@ vmlinux-lds  := arch/$(ARCH)/kernel/vmli
 quiet_cmd_vmlinux__ ?= LD      $@
       cmd_vmlinux__ ?= $(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) -o $@ \
       -T $(vmlinux-lds) $(vmlinux-init)                          \
-      --start-group $(vmlinux-main) --end-group                  \
+      --start-group $(vmlinux-main) $(libgcc) --end-group        \
       $(filter-out $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) FORCE ,$^)
 
 # Generate new vmlinux version
diff -Nupr linux-2.6.13.2.orig/arch/arm/Kconfig linux-2.6.13.2/arch/arm/Kconfig
--- linux-2.6.13.2.orig/arch/arm/Kconfig	2005-09-17 10:02:12.000000000 +0900
+++ linux-2.6.13.2/arch/arm/Kconfig	2005-09-28 03:15:21.742495529 +0900
@@ -438,6 +438,12 @@ config ALIGNMENT_TRAP
 	  correct operation of some network protocols. With an IP-only
 	  configuration it is safe to say N, otherwise say Y.
 
+config CABI
+	bool 'CPU Accounting and Binding Interface support' 
+	default n
+	---help---
+	CPU Accounting and Binding Interface support.
+
 endmenu
 
 menu "Boot options"
diff -Nupr linux-2.6.13.2.orig/arch/arm/kernel/calls.S linux-2.6.13.2/arch/arm/kernel/calls.S
--- linux-2.6.13.2.orig/arch/arm/kernel/calls.S	2005-09-17 10:02:12.000000000 +0900
+++ linux-2.6.13.2/arch/arm/kernel/calls.S	2005-09-28 03:15:21.742495529 +0900
@@ -10,9 +10,9 @@
  *  This file is included twice in entry-common.S
  */
 #ifndef NR_syscalls
-#define NR_syscalls 320
+#define NR_syscalls 328
 #else
-
+	
 __syscall_start:
 /* 0 */		.long	sys_restart_syscall
 		.long	sys_exit
@@ -333,6 +333,15 @@ __syscall_start:
 		.long	sys_inotify_init
 		.long	sys_inotify_add_watch
 		.long	sys_inotify_rm_watch
+#ifdef  CONFIG_CABI
+ 		.long	sys_cabi_account_create    /* 319 */
+ 		.long	sys_cabi_account_destroy   /* 320 */
+ 		.long	sys_cabi_account_bind_pid  /* 321 */
+ 		.long	sys_cabi_account_bind_pgid /* 322 */
+ 		.long	sys_cabi_account_unbind    /* 323 */
+ 		.long	sys_cabi_account_get       /* 324 */
+ 		.long	sys_cabi_account_set       /* 325 */
+#endif  /* CONFIG_CABI */
 __syscall_end:
 
 		.rept	NR_syscalls - (__syscall_end - __syscall_start) / 4
diff -Nupr linux-2.6.13.2.orig/arch/arm/kernel/entry-common.S linux-2.6.13.2/arch/arm/kernel/entry-common.S
--- linux-2.6.13.2.orig/arch/arm/kernel/entry-common.S	2005-09-17 10:02:12.000000000 +0900
+++ linux-2.6.13.2/arch/arm/kernel/entry-common.S	2005-09-28 03:15:21.743495297 +0900
@@ -23,6 +23,12 @@
 ret_fast_syscall:
 	disable_irq				@ disable interrupts
 	ldr	r1, [tsk, #TI_FLAGS]
+#ifdef	CONFIG_CABI
+	ldr	r3, __cabi_hook_func
+	ldr	r3, [r3, #0]		/* cabi_ret_with_reschedule_hook */
+	teq	r3, #0			/* if (hook != 0) */
+	bne	fast_work_pending	/* and jump to slow: */
+#endif /* CONFIG_CABI */
 	tst	r1, #_TIF_WORK_MASK
 	bne	fast_work_pending
 
@@ -40,6 +46,12 @@ ret_fast_syscall:
  */
 fast_work_pending:
 	str	r0, [sp, #S_R0+S_OFF]!		@ returned r0
+#ifdef	CONFIG_CABI
+	ldr	r3, __cabi_hook_func
+	ldr	r3, [r3, #0]		/* cabi_ret_with_reschedule_hook */
+	teq	r3, #0			/* if (hook != 0) */
+	bne	ret_slow_syscall	/* and jump to slow: */
+#endif /* CONFIG_CABI */
 work_pending:
 	tst	r1, #_TIF_NEED_RESCHED
 	bne	work_resched
@@ -59,6 +71,21 @@ work_resched:
 ENTRY(ret_to_user)
 ret_slow_syscall:
 	disable_irq				@ disable interrupts
+#ifdef	CONFIG_CABI
+	ldr	r2, __cabi_hook_func
+	ldr	r1, [r2, #0]
+	cmp	r1, #0			/* if (hook == 0) */
+	beq	__cabi_hook_exit	/* yes, then skip it */
+	mov	lr, pc			/* no, then ... */
+	mov	pc, r1			/*     call hook */
+	cmp	r0, #0			/* if (ret != 0) */
+	bne	ret_slow_syscall	/* yes, then jump back */
+	b	__cabi_hook_exit	/* no, then jump out */
+__cabi_hook_func:
+	.align	2
+	.word	cabi_ret_with_reschedule_hook
+__cabi_hook_exit:
+#endif /* CONFIG_CABI */
 	ldr	r1, [tsk, #TI_FLAGS]
 	tst	r1, #_TIF_WORK_MASK
 	bne	work_pending
diff -Nupr linux-2.6.13.2.orig/arch/i386/Kconfig linux-2.6.13.2/arch/i386/Kconfig
--- linux-2.6.13.2.orig/arch/i386/Kconfig	2005-09-17 10:02:12.000000000 +0900
+++ linux-2.6.13.2/arch/i386/Kconfig	2005-09-28 03:15:21.744495066 +0900
@@ -978,6 +978,13 @@ config CRASH_DUMP
 	depends on HIGHMEM
 	help
 	  Generate crash dump after being started by kexec.
+
+config CABI
+	bool 'CPU Accounting and Binding Interface support' 
+	default n
+	---help---
+	CPU Accounting and Binding Interface support.
+
 endmenu
 
 
diff -Nupr linux-2.6.13.2.orig/arch/i386/kernel/entry.S linux-2.6.13.2/arch/i386/kernel/entry.S
--- linux-2.6.13.2.orig/arch/i386/kernel/entry.S	2005-09-17 10:02:12.000000000 +0900
+++ linux-2.6.13.2/arch/i386/kernel/entry.S	2005-09-28 03:15:21.744495066 +0900
@@ -239,6 +239,15 @@ syscall_exit:
 	cli				# make sure we don't miss an interrupt
 					# setting need_resched or sigpending
 					# between sampling and the iret
+#ifdef	CONFIG_CABI
+	movl	cabi_ret_with_reschedule_hook,%eax
+	testl	%eax,%eax		/* if (hook == 0) */
+	je	1f			/* yes, then skip it */
+	call	*%eax			/* no, then call hook */
+	testl	%eax,%eax		/* if (ret != 0) */
+	jne	syscall_exit    	/* yes, then jump back */
+1:
+#endif
 	movl TI_flags(%ebp), %ecx
 	testw $_TIF_ALLWORK_MASK, %cx	# current->work
 	jne syscall_exit_work
diff -Nupr linux-2.6.13.2.orig/arch/i386/kernel/syscall_table.S linux-2.6.13.2/arch/i386/kernel/syscall_table.S
--- linux-2.6.13.2.orig/arch/i386/kernel/syscall_table.S	2005-09-17 10:02:12.000000000 +0900
+++ linux-2.6.13.2/arch/i386/kernel/syscall_table.S	2005-09-28 03:15:21.745494835 +0900
@@ -294,3 +294,12 @@ ENTRY(sys_call_table)
 	.long sys_inotify_init
 	.long sys_inotify_add_watch
 	.long sys_inotify_rm_watch
+#ifdef  CONFIG_CABI		
+ 	.long sys_cabi_account_create    /* 294 */
+        .long sys_cabi_account_destroy   /* 295 */
+        .long sys_cabi_account_bind_pid  /* 296 */
+        .long sys_cabi_account_bind_pgid /* 297 */
+        .long sys_cabi_account_unbind    /* 298 */
+        .long sys_cabi_account_get       /* 299 */
+        .long sys_cabi_account_set       /* 300 */
+#endif  /* CONFIG_CABI */
diff -Nupr linux-2.6.13.2.orig/arch/ppc/Kconfig linux-2.6.13.2/arch/ppc/Kconfig
--- linux-2.6.13.2.orig/arch/ppc/Kconfig	2005-09-17 10:02:12.000000000 +0900
+++ linux-2.6.13.2/arch/ppc/Kconfig	2005-09-28 03:15:21.746494604 +0900
@@ -279,6 +279,11 @@ config NOT_COHERENT_CACHE
 	depends on 4xx || 8xx || E200
 	default y
 
+config CABI
+	bool 'CPU Accounting and Binding Interface support' 
+	default n
+	---help---
+	CPU Accounting and Binding Interface support.
 endmenu
 
 menu "Platform options"
diff -Nupr linux-2.6.13.2.orig/arch/ppc/kernel/entry.S linux-2.6.13.2/arch/ppc/kernel/entry.S
--- linux-2.6.13.2.orig/arch/ppc/kernel/entry.S	2005-09-17 10:02:12.000000000 +0900
+++ linux-2.6.13.2/arch/ppc/kernel/entry.S	2005-09-28 03:15:21.747494372 +0900
@@ -660,7 +660,17 @@ user_exc_return:		/* r10 contains MSR_KE
 	lwz	r9,TI_FLAGS(r9)
 	andi.	r0,r9,(_TIF_SIGPENDING|_TIF_NEED_RESCHED)
 	bne	do_work
-
+#ifdef CONFIG_CABI
+	lis r5,cabi_ret_with_reschedule_hook@ha
+	lwz r9,cabi_ret_with_reschedule_hook@l(r5)
+	cmpwi cr0,r9,0
+	beq- cr0,__cabi_hook_exit
+	mtlr r9
+	blrl
+	cmpwi cr0,r3,0
+	bne+ cr0,ret_from_except
+__cabi_hook_exit:
+#endif /* CONFIG_CABI */
 restore_user:
 #if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
 	/* Check whether this process has its own DBCR0 value.  The single
diff -Nupr linux-2.6.13.2.orig/arch/ppc/kernel/misc.S linux-2.6.13.2/arch/ppc/kernel/misc.S
--- linux-2.6.13.2.orig/arch/ppc/kernel/misc.S	2005-09-17 10:02:12.000000000 +0900
+++ linux-2.6.13.2/arch/ppc/kernel/misc.S	2005-09-28 03:15:21.747494372 +0900
@@ -1455,3 +1455,12 @@ _GLOBAL(sys_call_table)
 	.long sys_inotify_init		/* 275 */
 	.long sys_inotify_add_watch
 	.long sys_inotify_rm_watch
+#ifdef  CONFIG_CABI	
+ 	.long sys_cabi_account_create    /* 278 */
+        .long sys_cabi_account_destroy   /* 279 */
+        .long sys_cabi_account_bind_pid  /* 280 */
+        .long sys_cabi_account_bind_pgid /* 281 */
+        .long sys_cabi_account_unbind    /* 282 */
+        .long sys_cabi_account_get       /* 283 */
+        .long sys_cabi_account_set       /* 284 */
+#endif  /* CONFIG_CABI */
diff -Nupr linux-2.6.13.2.orig/arch/sh/Kconfig linux-2.6.13.2/arch/sh/Kconfig
--- linux-2.6.13.2.orig/arch/sh/Kconfig	2005-09-17 10:02:12.000000000 +0900
+++ linux-2.6.13.2/arch/sh/Kconfig	2005-09-28 03:15:21.748494141 +0900
@@ -693,6 +693,11 @@ config RTC_9701JE
 	help
 	  Selecting this option will support EPSON RTC-9701JE.
 
+config CABI
+	bool 'CPU Accounting and Binding Interface support' 
+	default n
+	---help---
+
 endmenu
 
 config ISA_DMA_API
diff -Nupr linux-2.6.13.2.orig/arch/sh/kernel/entry.S linux-2.6.13.2/arch/sh/kernel/entry.S
--- linux-2.6.13.2.orig/arch/sh/kernel/entry.S	2005-09-17 10:02:12.000000000 +0900
+++ linux-2.6.13.2/arch/sh/kernel/entry.S	2005-09-28 03:15:21.749493910 +0900
@@ -574,6 +574,22 @@ syscall_call:
 syscall_exit:
 	CLI()
 	!
+#ifdef CONFIG_CABI
+	mov.l	__cabi_hook_func, r0
+	mov.l	@r0, r1
+	tst	r1, r1			/* if (hook == 0) */
+	bt	__cabi_hook_exit	/* yes, then skip it */
+	jsr	@r1			/* no, then call hook */
+	nop
+	tst	r0, r0			/* if (ret != 0) */
+	bf	syscall_exit		/* yes, then jump back */
+	bra	__cabi_hook_exit
+	nop
+	.align 2
+__cabi_hook_func:
+	.long	cabi_ret_with_reschedule_hook
+__cabi_hook_exit:
+#endif /* CONFIG_CABI */
 	GET_THREAD_INFO(r8)
 	mov.l	@(TI_FLAGS,r8), r0		! current_thread_info->flags
 	tst	#_TIF_ALLWORK_MASK, r0
@@ -1150,5 +1166,14 @@ ENTRY(sys_call_table)
 	.long sys_inotify_init		/* 290 */
 	.long sys_inotify_add_watch
 	.long sys_inotify_rm_watch
+#ifdef  CONFIG_CABI
+	.long sys_cabi_account_create	 /* 293 */
+	.long sys_cabi_account_destroy	 /* 294 */
+	.long sys_cabi_account_bind_pid  /* 295 */
+	.long sys_cabi_account_bind_pgid /* 296 */
+	.long sys_cabi_account_unbind	 /* 297 */
+	.long sys_cabi_account_get       /* 298 */
+	.long sys_cabi_account_set	 /* 299 */
+#endif  /* CONFIG_CABI */
 
 /* End of entry.S */
diff -Nupr linux-2.6.13.2.orig/drivers/Makefile linux-2.6.13.2/drivers/Makefile
--- linux-2.6.13.2.orig/drivers/Makefile	2005-09-17 10:02:12.000000000 +0900
+++ linux-2.6.13.2/drivers/Makefile	2005-09-28 03:15:21.749493910 +0900
@@ -65,3 +65,4 @@ obj-$(CONFIG_INFINIBAND)	+= infiniband/
 obj-$(CONFIG_SGI_IOC4)		+= sn/
 obj-y				+= firmware/
 obj-$(CONFIG_CRYPTO)		+= crypto/
+obj-$(CONFIG_CABI)		+= cabi/
diff -Nupr linux-2.6.13.2.orig/drivers/cabi/Makefile linux-2.6.13.2/drivers/cabi/Makefile
--- linux-2.6.13.2.orig/drivers/cabi/Makefile	1970-01-01 09:00:00.000000000 +0900
+++ linux-2.6.13.2/drivers/cabi/Makefile	2005-09-28 03:15:21.749493910 +0900
@@ -0,0 +1,14 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definitions are now in the main makefile...
+
+
+obj-$(CONFIG_CABI) = cabi_init.o cabi_account.o cabi_timer.o cabi_sched.o cabi_isr.o cabi_signal.o
+obj-$(CONFIG_PROC_FS) += cabi_procfs.o
+
+
diff -Nupr linux-2.6.13.2.orig/drivers/cabi/cabi_account.c linux-2.6.13.2/drivers/cabi/cabi_account.c
--- linux-2.6.13.2.orig/drivers/cabi/cabi_account.c	1970-01-01 09:00:00.000000000 +0900
+++ linux-2.6.13.2/drivers/cabi/cabi_account.c	2005-09-28 03:15:21.751493447 +0900
@@ -0,0 +1,1608 @@
+ /*
+  * linux/drivers/cabi/cabi_account.c 
+  * 
+  * CABI -- CPU Accounting and Blocking Interfaces.
+  * 
+  * Copyright (C) OS Research Group, Waseda University Nakajima Laboratory.
+  *               MontaVista Software, Inc. 
+  * 
+  * This software was developed by the Waseda University and Montavista Software,
+  * Inc. Funding for this project was provided by IPA (Information-technology
+  * Promotion Agency, Japan). This software may be used and distributed 
+  * according to the terms of the GNU Public License, incorporated herein by
+  * reference. 
+  * 
+  * This project was developed under the direction of Dr. Tatsuo Nakajima.
+  *
+  * Authors: Midori Sugaya, Hirotaka Ishikawa
+  *
+  * Porting to Kernel-2.6 Takeharu KATO
+  *
+  * Please send bug-reports/suggestions/comments to qos@dcl.info.waseda.ac.jp 
+  * 
+  * Futher details about this project can be obtained at
+  * http://dcl.info.waseda.ac.jp/osrg/
+  *             
+  * This is free software; you can redistribute it and/or modify it under
+  * the terms of the GNU Lesser General Public License as published by the
+  * Free Software Foundation; either version 2 of the License, or (at your
+  * option) any later version.
+  *
+  * This software 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.  See the GNU
+  * Lesser General Public License for more details.
+  *
+  * You should have received a copy of the GNU Lesser General Public
+  * License along with this software; if not, write to the Free Software
+  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+  *
+  * This file is derived from software distributed under the following terms:
+  */
+ /*
+  * Real-time and Multimedia Systems Laboratory
+  * Copyright (c) 1999 Carnegie Mellon University
+  * All Rights Reserved.
+  *
+  * Permission to use, copy, modify and distribute this software and its
+  * documentation is hereby granted, provided that both the copyright
+  * notice and this permission notice appear in all copies of the
+  * software, derivative works or modified versions, and any portions
+  * thereof, and that both notices appear in supporting documentation.
+  *
+  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+  *
+  * Carnegie Mellon requests users of this software to return to
+  *
+  *  Real-Time and Multimedia Systems Laboratory
+  *  Attn: Prof. Raj Rajkumar
+  *  Electrical and Computer Engineering, and Computer Science
+  *  Carnegie Mellon University
+  *  Pittsburgh PA 15213-3890
+  *
+  *  or via email to raj@ece.cmu.edu
+  *
+  * any improvements or extensions that they make and grant Carnegie Mellon
+  * the rights to redistribute these changes.
+  */
+
+#include <linux/version.h>
+#include <linux/time.h>
+#include <linux/random.h>
+#include <linux/spinlock.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <asm/processor.h>
+
+#include <cabi/cabi.h>
+#include <cabi/cabi_error.h>
+
+/*
+ * static variables for accounting
+ */
+cabi_account_t cabi_current_account;
+struct list_head cabi_account_head;
+cabi_account_t cabi_current_overload_account;
+cpu_capacity_t cabi_account_current_capacity;
+int overload_cabi;
+int last_cabi_id = 0;
+
+
+/* 
+ * struct regist list for process group.
+ */
+struct rglist {
+	int count;
+	pid_t pid;
+	struct task_struct *tsk;
+	struct list_head rg_link;
+};
+typedef struct rglist *rglist_t;
+struct list_head rglist_head;
+
+extern long sys_setpgid(pid_t pid, pid_t pgid);
+extern rwlock_t tasklist_lock;
+
+cabi_account_t
+search_cabi(unsigned long cabi_id)
+{
+	struct list_head *cabi_list;
+	cabi_account_t cabi = NULL_ACCOUNT;
+
+	cabi_list = &cabi_account_head;
+	while (!list_empty(cabi_list)) {
+		cabi = list_entry(cabi_list, struct cabi_account, cpu_link);
+		if (cabi->cabi_id == cabi_id)
+			break;
+
+		cabi_list = cabi_list->next;
+
+		if (cabi_list == &cabi_account_head) {
+			cabi = NULL_ACCOUNT;
+			break;
+		}
+	}
+	return cabi;
+}
+
+void
+cabi_account_init(void)
+{
+	INIT_LIST_HEAD(&cabi_account_head);
+	cabi_account_current_capacity = 0;
+	cabi_current_overload_account = NULL;
+}
+
+int
+get_cabi_id(void)
+{
+	struct list_head *cabi_list;
+	cabi_account_t cabi = NULL_ACCOUNT;
+	int begin_cabi_id, cabi_id_error;
+	cabi_id_error = -1;
+
+	begin_cabi_id = -1;
+	last_cabi_id++;
+
+	cabi_list = &cabi_account_head;
+	cabi_list = cabi_list->next;
+	if (cabi_list == &cabi_account_head) {	/* First AO create. */
+		last_cabi_id = FIRST_CABI_ID;
+		return last_cabi_id;
+	}
+	while (!list_empty(cabi_list)) {	/* Get cabi_id */
+		cabi = list_entry(cabi_list, struct cabi_account, cpu_link);
+		/* cabi_id is full */
+		if (last_cabi_id == begin_cabi_id)
+			return cabi_id_error;
+		/* selected cabi_id is for overload */
+		if (OVERLOAD_CABI_ID == last_cabi_id) {
+			if (begin_cabi_id == -1)
+				begin_cabi_id = last_cabi_id;
+			++last_cabi_id;
+			cabi_list = &cabi_account_head;
+			cabi_list = cabi_list->next;
+			continue;
+		}
+		/* selected cabi_id is already used */
+		if (cabi->cabi_id == last_cabi_id) {
+			if (begin_cabi_id == -1)
+				begin_cabi_id = last_cabi_id;
+			++last_cabi_id;
+			cabi_list = &cabi_account_head;
+			cabi_list = cabi_list->next;
+			continue;
+		}
+		/* selected cabi_id is MAX value */
+		if (last_cabi_id >= CABI_ID_MAX) {
+			if (begin_cabi_id == -1)
+				begin_cabi_id = last_cabi_id;
+			last_cabi_id = FIRST_CABI_ID;
+			cabi_list = &cabi_account_head;
+			cabi_list = cabi_list->next;
+			continue;
+		}
+		/* next cabi list */
+		cabi_list = cabi_list->next;
+
+		/* all lists were searched. */
+		if (cabi_list == &cabi_account_head)
+			break;
+	}
+	return last_cabi_id;
+}
+
+void
+overload_capacity(struct timespec *c, struct timespec *t, struct timespec *new_qc)
+{
+	cpu_capacity_quad_t qc, qt, new_nano_qc;
+	cpu_capacity_t capacity, new_capacity, sure;
+  
+	/* re-calculate requested capacity */
+	qc =  c->tv_sec;   
+	qc *= NANOSEC; 
+	qc += c->tv_nsec;
+	qt =  t->tv_sec; 
+	qt *= NANOSEC; 
+	qt += t->tv_nsec;
+
+	/* current requested capacity */	
+	capacity = CAPACITY_OF(qc, qt);
+
+#ifdef DEBUG_CABI	
+	printk("capacity(%lu.%02lu)\n", CAPACITY_INT(capacity), 
+	       CAPACITY_FRAC(capacity));
+#endif
+	new_capacity  =  PERCENT2CAPACITY(FULLCAPACITY) - capacity;
+
+#ifdef DEBUG_CABI
+	printk("new capacity is %lu.%02lu\n", 
+	       CAPACITY_INT(new_capacity), 
+	       CAPACITY_FRAC(new_capacity));
+#endif		
+	new_nano_qc = CAPACITY2INT(new_capacity*qt);
+	sure = CAPACITY_OF(new_nano_qc, qt);
+
+	memset (new_qc, 0x00, sizeof (struct timespec));
+	new_qc->tv_sec  = (long)(new_nano_qc / NANOSEC);
+	new_qc->tv_nsec = (long)(new_nano_qc - (cpu_capacity_quad_t)(new_qc->tv_sec * NANOSEC));
+
+#ifdef DEBUG_CABI
+	printk("new_time.tv_sec (%ld), new_time.tv_nsec (%ld)\n",
+	       new_qc->tv_sec, new_qc->tv_nsec);
+	printk("new_time(c) %lld /period %lld, new capacity(%lu.%02lu)\n",
+	       	new_nano_qc, qt, 
+		CAPACITY_INT(sure), CAPACITY_FRAC(sure));
+#endif
+}
+
+static cabi_account_t
+cabi_account_create(struct timespec *c, struct timespec *t,
+		    cabi_param_data_t * p)
+{
+	cabi_account_t cabi;
+	struct timespec new_qc;
+	cpu_capacity_t capacity;
+	cpu_capacity_quad_t qc, qt;
+	long get_id = 0;
+
+#ifdef	DEBUG_CABI
+	printk("cabi_account_create: c(%d,%d) t(%d,%d)\n",
+	       (int) c->tv_sec, (int) c->tv_nsec,
+	       (int) t->tv_sec, (int) t->tv_nsec);
+#endif
+
+	/* if this is overload cabi, re-calculate parameters. */
+	if (p->bind_proc_type == BIND_IDLE_PROC){
+		overload_capacity(c,t,&new_qc);
+		c->tv_sec = new_qc.tv_sec;
+		c->tv_nsec = new_qc.tv_nsec;
+	}
+
+	qc = c->tv_sec;
+	qc *= NANOSEC;
+	qc += c->tv_nsec;
+	qt = t->tv_sec;
+	qt *= NANOSEC;
+	qt += t->tv_nsec;
+	  
+	  capacity = CAPACITY_OF(qc, qt);
+	  cabi_account_current_capacity =
+	    capacity + cabi_account_current_capacity;
+	  
+#ifdef	DEBUG_CABI
+	  printk ("cabi_account_create: capacity(%lu.%02lu)\n",
+		  CAPACITY_INT(capacity), CAPACITY_FRAC(capacity));
+	  
+#endif
+	/* create an accounting object */
+	if((cabi = malloc(sizeof (struct cabi_account))) == NULL)
+		return NULL;
+	bzero(cabi, sizeof (struct cabi_account));
+
+	/* memory copy */
+	memcpy(&cabi->cabi_param, p, sizeof(cabi_param_data_t));
+        if (cabi->cabi_param.bind_proc_type | IDLE_PROCESS) {
+                /* have there been overload cabi */
+                if (!cabi_current_overload_account) {
+                        cabi->cabi_id = OVERLOAD_CABI_ID;
+                        cabi_current_overload_account = cabi;
+                } else {
+		  /*XXXX Fix me XXXX*/
+		  /* It should be removed. */
+                        /* already existed. */
+                        free(cabi);
+                        return NULL;
+                }
+        } else {
+                if((get_id = get_cabi_id()) < 0) {
+                        free(cabi);
+                        return NULL;
+                } else {
+                        cabi->cabi_id = (unsigned int)get_id;
+                }
+        }
+        INIT_LIST_HEAD(&cabi->cpu_proc_list);
+
+        memcpy (&cabi->cpu_time, c, sizeof(struct timespec));
+        memcpy (&cabi->cpu_period, t, sizeof(struct timespec));
+        cabi->cpu_capacity = capacity;
+
+	/* 
+	 * if this is the first call as the requirement of reservation,
+	 * we should set up cabi hooks. 
+	 */
+	if (list_empty(&cabi_account_head)) {
+		/* enable scheduling hook */
+		cabi_enable();
+	}
+	list_add(&cabi->cpu_link, &cabi_account_head);
+
+	/* calculate cpu ticks per capacity */
+	nanosec2tick(&qc, &cabi->cpu_time_ticks);
+	nanosec2tick(&qt, &cabi->cpu_period_ticks);
+
+#ifdef DEBUG_CABI
+	printk("cabi tick values : cpu_period_ticks(T) (%ld)"
+	       "cpu_time_ticks(C) (%ld)\n",
+	       (long) cabi->cpu_period_ticks, (long) cabi->cpu_time_ticks);
+#endif
+	/*
+	 * Let the account replenished from the next jiffy.
+	 * See also cabi_timer.c:cabi_replenish_timer_create().
+	 *      cpu_period_used_ticks = 0;
+	 *      cpu_period_available_ticks = 0;
+	 */
+
+	/* init waitqueue */
+	init_waitqueue_head(&cabi->depleted_wait);
+
+	/* create entry as /proc/cabi/<cabi_id> */
+	INIT_LIST_HEAD(&cabi->cpu_proc_list);
+	cabi->cpu_state = CABI_IS_DEPLETED;
+	cabi->signal_block = SIGNAL_OFF;
+#ifdef CONFIG_PROC_FS
+	cabi_proc_account_create(cabi);
+#endif	
+
+#ifdef DEBUG_CABI
+	printk("Signal : pid %d sig %d flag %d\n",
+	       (int) CABI_SIGPID(cabi), (int) CABI_SIGNUM(cabi),
+	       (int) CABI_SIGFLAG(cabi));
+#endif
+	if (cabi->cabi_param.term_act == CABI_TERM_SIGNAL) {
+		cabi->term_act_status = CABI_SIGNAL;
+
+		if (!CABI_SIGPID(cabi)) {
+			/* if null, send default process */
+			CABI_SIGFLAG(cabi) = CABI_SEND_DEFL;
+		} else {
+			CABI_SIGFLAG(cabi) = CABI_SEND_PID;
+		}
+
+		if (!CABI_SIGNUM(cabi)) {
+			/* 
+			 * if signal is null, set default signal which
+			 * will do nothing. 
+			 */
+			cabi->cabi_param.term_act = CABI_TERM_NONE;
+		}
+	} else if (cabi->cabi_param.term_act == CABI_TERM_BLOCK) {
+		cabi->term_act_status = CABI_UNBLOCK; 
+	} else {
+		/* error return */
+		free(cabi);
+		return NULL;
+	}
+
+	/* create a timer for it */
+	cabi_replenish_timer_init(cabi, &cabi->cpu_period_ticks);
+
+	return cabi;		/* success */
+}
+
+
+int
+cabi_account_set(unsigned long cabi_id, struct timespec *c,
+		 struct timespec *t, cabi_param_data_t * p)
+{
+	struct timespec new_qc;
+        cpu_capacity_t capacity;
+	cpu_capacity_quad_t qc, qt;
+	cabi_account_t cabi = NULL_ACCOUNT;
+
+	/* find the cabi address */
+	if (!(cabi = search_cabi(cabi_id))) {
+		/* cabi dose not exist. */
+		return CABI_ENOEXIST;
+	}
+
+#ifdef	DEBUG_CABI
+	printk("cabi_account_set: cabi(0x%x) "
+	       "OLD: c(%ld,%ld) t(%ld,%ld) NEW: c(%ld,%ld) t(%ld,%ld)\n",
+	       (int) cabi, cabi->cpu_time.tv_sec, cabi->cpu_time.tv_nsec,
+	       cabi->cpu_period.tv_sec, cabi->cpu_period.tv_nsec, c->tv_sec,
+	       c->tv_nsec, t->tv_sec, t->tv_nsec);
+#endif
+	/* cabi is depleted */
+	cabi->cpu_state = CABI_IS_DEPLETED;
+
+	/* set terminate action */
+	memcpy(&cabi->cabi_param, p, sizeof(cabi_param_data_t));
+
+	if(cabi->cabi_param.term_act == CABI_TERM_BLOCK) {
+		cabi->term_act_status = CABI_UNBLOCK;
+	} else { 
+		cabi->term_act_status = CABI_SIGNAL;
+		if (!CABI_SIGNUM(cabi)) {
+			cabi->cabi_param.term_act = CABI_TERM_NONE;
+		}
+	 }
+
+	/* if this is overload cabi, re-calculate parameters. */
+	if (cabi->cabi_param.bind_proc_type == BIND_IDLE_PROC){
+		overload_capacity(c,t,&new_qc);
+		c->tv_sec = new_qc.tv_sec;
+		c->tv_nsec = new_qc.tv_nsec;
+	}
+
+	qc = c->tv_sec;
+	qc *= NANOSEC;
+	qc += c->tv_nsec;
+	qt = t->tv_sec;
+	qt *= NANOSEC;
+	qt += t->tv_nsec;
+
+	/* calculate a new capacity */
+	capacity = CAPACITY_OF(qc, qt);
+
+	/* set current capacity */
+	cabi_account_current_capacity =
+	    capacity + cabi_account_current_capacity - cabi->cpu_capacity;
+
+#ifdef	DEBUG_CABI
+	printk("cabi_account_set: jiffies(%lu) "
+	       "capacity(%lu.%02lu) new total(%lu.%02lu)\n", jiffies,
+	       CAPACITY_INT(capacity), CAPACITY_FRAC(capacity),
+	       CAPACITY_INT(cabi_account_current_capacity),
+	       CAPACITY_FRAC(cabi_account_current_capacity));
+#endif
+
+	/* load the new parameters */
+	memcpy(&cabi->cpu_time, c, sizeof(struct timespec));
+	memcpy(&cabi->cpu_period, t, sizeof(struct timespec));
+	cabi->cpu_capacity = capacity;
+
+	/* initialize available ticks */
+	cabi->cpu_period_available_ticks = 0;
+
+	/* calculate cabi ticks per capacity */
+	nanosec2tick(&qc, &cabi->cpu_time_ticks);
+	nanosec2tick(&qt, &cabi->cpu_period_ticks);
+
+	/* cancel replenish timer */
+	cabi_replenish_timer_cancel(cabi);
+
+	/* reset a timer for it */
+	cabi_replenish_timer_init(cabi, &cabi->cpu_period_ticks);
+
+	return CABI_SUCCESS;	/* success */
+
+}
+
+static int
+cabi_account_destroy(unsigned long cabi_id)
+{
+	cabi_account_t cabi = NULL_ACCOUNT;
+
+	/* find the cabi address */
+	if (!(cabi = search_cabi(cabi_id)))
+		return CABI_ENOEXIST;
+
+	/* if account has attached processes */
+	if (!list_empty(&cabi->cpu_proc_list))
+		/* process is still attached. */
+		return CABI_EATTACHED;
+
+	/* destroy timer */
+	cabi_replenish_timer_cancel(cabi);
+
+	/* return capacity */
+	if (cabi->cpu_capacity >= cabi_account_current_capacity) {
+		cabi_account_current_capacity = 0;
+	} else {
+		cabi_account_current_capacity -= cabi_account_current_capacity;
+	}
+
+	/* delete cpu_link */
+	list_del(&cabi->cpu_link);
+	INIT_LIST_HEAD(&cabi->cpu_link);	/* for sure */
+	cabi->cabi_param.term_act = CABI_TERM_NONE;
+
+#ifdef CONFIG_PROC_FS
+	/* 
+	 * remove entry under /proc/cabi/
+	 * must be before cabi_resource_set_detach_account()
+	 * since resource_set is reffered in cabi_proc_account_destroy()
+	 */
+	cabi_proc_account_destroy(cabi);
+#endif
+
+	/* finally free a generic account object. */
+	free(cabi);
+
+	if (cabi_id == OVERLOAD_CABI_ID)
+		cabi_current_overload_account = NULL;
+
+	return CABI_SUCCESS;	/* success */
+}
+
+int
+cabi_account_check_overload(void)
+{
+	cabi_account_t cabi = NULL_ACCOUNT;
+
+	/* search overload cabi */
+	if (!cabi_current_overload_account) {
+		return CABI_ENOEXIST;
+	} else {
+		cabi = cabi_current_overload_account;
+	}
+
+	if (cabi != cabi_current_account)
+		return CABI_ENOAVLE;
+
+	/* compare the total used ticks with available ticks. */
+	if (cabi->cpu_period_used_ticks < cabi->cpu_period_available_ticks) {
+#ifdef DEBUG_CABI
+		printk("cabi_account_check_overload:"
+		       " cabi(0x%x) used(%lu) < available(%lu)\n",
+		       (int) cabi,
+		       (unsigned long) cabi->cpu_period_used_ticks,
+		       (unsigned long) cabi->cpu_period_available_ticks);
+#endif
+		if (cabi->cabi_id == OVERLOAD_CABI_ID) {
+			cabi->overload |= CABI_IS_OVERLOAD;
+#ifdef  DEBUG_CABI
+			printk("cabi state overload(0x%x), signal sent.\n",
+			       (int) cabi->overload);
+#endif
+			cabi_send_signal(cabi, CABI_SIGPID(cabi), CABI_SIGNUM(cabi));
+		}
+	} else {
+		if (cabi->cabi_id == OVERLOAD_CABI_ID) {
+#ifdef  DEBUG_CABI
+			printk("cabi state overload(0x%x), no signal sent.\n",
+			       (int) cabi->overload);
+#endif
+			cabi->overload = CABI_IS_NULL;
+		}
+	}
+	return CABI_SUCCESS;
+}
+
+static inline void
+cabi_account_summation_of_used_ticks(cabi_account_t cabi, cpu_tick_t now)
+{
+	cabi->cpu_period_used_ticks += (*now - cabi->cpu_period_start_ticks);
+	cabi->cpu_period_start_ticks = *now;
+}
+
+/*
+ * Replenish & Enforce a account
+ */
+void
+cabi_account_replenish(cabi_account_t cabi, struct timespec *period)
+{
+	cpu_capacity_t c;
+	int is_running = 0;
+	long long ticks;
+
+	*period = cabi->cpu_period;
+
+	if (cabi->cpu_state & CABI_IS_RUNNING) {
+		cpu_tick_data_t now;
+		cabi_rdticks(&now);
+		cabi_stop_account(cabi, &now);
+		is_running++;
+	}
+
+	/* check overload condition */
+	if (overload_cabi)
+		cabi_account_check_overload();
+
+	/* update statistics */
+	cabi->cpu_period_prev_used_ticks = cabi->cpu_period_used_ticks;
+	cabi->cpu_total_used_ticks += cabi->cpu_period_used_ticks;
+	c = CAPACITY_OF(cabi->cpu_period_used_ticks, cabi->cpu_period_ticks);
+
+	if (cabi->cpu_max_utilization < c) {
+		cabi->cpu_max_utilization = c;
+	} else if (cabi->cpu_min_utilization > c
+		   || cabi->cpu_min_utilization == 0) {
+		cabi->cpu_min_utilization = c;
+	}
+
+	/* summation for average */
+	cabi->cpu_average.total_utils += c;
+	cabi->cpu_average.total_count++;
+
+#ifdef	DEBUG_CABI
+	printk("cabi_account_replenish: cabi(0x%x) used(%lu/%lu)"
+	       "state(%x) next available(%lu)\n",
+	       (int) cabi,
+	       (unsigned long) cabi->cpu_period_used_ticks,
+	       (unsigned long) cabi->cpu_period_available_ticks,
+	       (int) cabi->cpu_state,
+	       (unsigned long) cabi->cpu_period_available_ticks);
+#endif
+	/* reset the used ticks */
+	cabi->cpu_period_used_ticks = 0;
+
+	/*
+	 * If account was depleted, its processes were stopped on its wait
+	 * list but remained in their original scheduling class.  Wake them
+	 * up if there are available ticks.
+	 */
+	if (cabi->cpu_period_available_ticks > 0) {
+		cabi->cpu_state &= ~CABI_IS_DEPLETED;
+		wake_up(&cabi->depleted_wait);
+
+		if (cabi->cabi_param.term_act == CABI_TERM_BLOCK) {
+			cabi->term_act_status = CABI_UNBLOCK;
+		}
+		return;
+	}
+
+	cabi->cpu_state &= ~CABI_IS_DEPLETED;
+	ticks = cabi->cpu_period_used_ticks - cabi->cpu_period_available_ticks;
+
+	/* when excessiblely used */
+	if (ticks > 0) {
+		cpu_tick_data_t next;
+		next = cabi->cpu_time_ticks - ticks;
+		if (next >= 0) {
+			cabi->cpu_period_available_ticks = next;
+		} else {
+			cabi->cpu_period_available_ticks = 0;
+		}
+	} else {
+		cabi->cpu_period_available_ticks = cabi->cpu_time_ticks;
+	}
+
+	if (is_running)
+		cabi_start_account(cabi);
+}
+
+void
+cabi_account_enforce(cabi_account_t cabi)
+{
+	if (cabi->cabi_id != OVERLOAD_CABI_ID &&
+	    !(cabi->cpu_state & CABI_IS_DEPLETED)) {
+#ifdef	DEBUG_CABI
+		printk("cabi_account_enforce: cabi(0x%x) state(%x)\n",
+		       (int) cabi, cabi->cpu_state);
+#endif
+		cabi->cpu_state |= CABI_IS_DEPLETED;
+	}
+	/*
+	 * Letting the depleted process sleep is done 
+	 * if depleted in cabi_isr.c:cabi_ret_with_reschedule(), 
+	 * which is called when a process exits the kernel. 
+	 */
+}
+
+void
+cabi_account_sleep_on(cabi_account_t cabi)
+{
+	sleep_on(&cabi->depleted_wait);
+}
+
+/*
+ * Start & Stop the account of CPU utilization.
+ */
+void
+cabi_start_account(cabi_account_t cabi)
+{
+	long long next;
+
+#ifdef DEBUG_CABI
+	printk("cabi_start_account cpu_period_available_ticks(%d)\n",
+	       (int) cabi->cpu_period_available_ticks);
+	printk("cabi_start_account cpu_period_used_ticks(%d)\n",
+	       (int) cabi->cpu_period_used_ticks);
+#endif
+	next = cabi->cpu_period_available_ticks - cabi->cpu_period_used_ticks;
+	cabi_rdticks(&cabi->cpu_period_start_ticks);
+
+	switch (cabi->cpu_state) {
+	case CABI_IS_NULL:
+		cabi->cpu_state = CABI_IS_RUNNING;
+		cabi_enforce_timer_start(cabi, &next);
+		break;
+	case CABI_IS_DEPLETED:
+		cabi->cpu_state |= CABI_IS_RUNNING;
+		/* it's illegal state */
+		break;
+	case CABI_IS_RUNNING:	/* must not be so */
+#ifdef DEBUG_CABI
+		printk("start_account: CABI_IS_RUNNING\n");
+		printk("cabi_start_account: cabi(0x%x) illegal state"
+		       "(RUNNING)\n", (int) cabi);
+#endif
+		cabi_enforce_timer_start(cabi, &next);
+		break;
+	case CABI_IS_RUNNING | CABI_IS_DEPLETED:	// must not be so 
+#ifdef DEBUG_CABI
+		printk("statr_account: CABI_IS_RUNNING|CABI_IS_DEPLETED\n");
+		printk("cabi_start_account: cabi(0x%x) illegal state"
+		       "(RUNNING|DEPLETED)\n", (int) cabi);
+#endif
+		break;
+
+	default:		/* unkown */
+#ifdef DEBUG_CABI
+		printk("cabi_start_account: "
+		       "cabi(0x%x) unkown state(0x%x) next available(%lu)\n",
+		       (int) cabi, (int) cabi->cpu_state, (unsigned long) next);
+#endif
+		cabi->cpu_state = CABI_IS_RUNNING;
+
+		if (next > 0) {
+			cabi_enforce_timer_start(cabi, &next);
+		} else {
+			cabi->cpu_state |= CABI_IS_DEPLETED;
+		}
+		break;
+	}
+}
+
+static inline void
+cabi_account_check_enforce(cabi_account_t cabi)
+{
+	if ((cabi->cabi_id != OVERLOAD_CABI_ID) &&
+	    cabi->cpu_period_used_ticks >= cabi->cpu_period_available_ticks) {
+#ifdef	DEBUG_CABI
+		printk("cabi_account_check_enforce: "
+		       "enforce cabi(0x%x) used(%lu/%lu)\n", (int) cabi,
+		       (unsigned long) cabi->cpu_period_used_ticks,
+		       (unsigned long) cabi->cpu_period_available_ticks);
+#endif
+		/* enforcing a account */
+		cabi_account_enforce(cabi);
+	}
+}
+
+void
+cabi_stop_account(cabi_account_t cabi, cpu_tick_t now)
+{
+
+	long long left;
+
+	cabi_account_summation_of_used_ticks(cabi, now);
+
+	switch (cabi->cpu_state) {
+	case CABI_IS_RUNNING:
+		cabi->cpu_state &= ~CABI_IS_RUNNING;
+		cabi_account_check_enforce(cabi);
+		break;
+	case CABI_IS_RUNNING | CABI_IS_DEPLETED:
+		cabi->cpu_state &= ~CABI_IS_RUNNING;
+		break;
+
+	case CABI_IS_NULL:	/* must not be so */
+#ifdef DEBUG_CABI
+		printk("stop_account: CABI_IS_NULL\n");
+		printk("cabi(0x%x) illegal state(NULL)\n", (int) cabi);
+#endif
+		cabi_account_check_enforce(cabi);
+		break;
+	case CABI_IS_DEPLETED:	/* must not be so */
+#ifdef DEBUG_CABI
+		printk("stop_account: CABI_IS_DEPLETED\n");
+		printk("cabi(0x%x) illegal state"
+		       "(NULL|DEPLETED)\n", (int) cabi);
+#endif
+		break;
+	default:		/* unkown */
+		left =
+		    cabi->cpu_period_available_ticks -
+		    cabi->cpu_period_used_ticks;
+#ifdef DEBUG_CABI
+		printk("stop_account: default\n");
+		printk("cabi_stop_account: cabi(0x%x) unkown state(0x%x) "
+		       "left available(%lu)\n",
+		       (int) cabi, (int) cabi->cpu_state, (unsigned long) left);
+#endif
+		cabi->cpu_state = CABI_IS_NULL;
+
+		if (left <= 0) {
+			cabi->cpu_state |= CABI_IS_DEPLETED;
+		}
+		break;
+	}
+}
+
+int
+cabi_account_attach(unsigned long cabi_id, struct task_struct *tsk)
+{
+	struct rs_proc_list *rs_proc;
+	cabi_account_t cabi = NULL_ACCOUNT;
+
+	/* find the cabi address */
+	if (!(cabi = search_cabi(cabi_id))) {
+		/* did not exist. */
+		return CABI_ENOEXIST;
+	}
+
+	/*
+	 * !!! Need to make sure cabi is really a account.
+	 */
+	LVAL_TASK_ACCOUNT(tsk) = cabi;
+
+	if((rs_proc = malloc(sizeof (struct rs_proc_list))) == NULL)
+		return CABI_ENOMEM;
+	bzero(rs_proc, sizeof (struct rs_proc_list));
+
+	rs_proc->rs_proc_task = tsk;
+	rs_proc->rs_proc_pid = tsk->pid;
+	{
+		unsigned long flags;
+		local_save_flags(flags);
+		local_irq_disable();
+		list_add(&rs_proc->rs_proc_list, &cabi->cpu_proc_list);
+		local_irq_restore(flags);
+	}
+
+	/* attach! */
+	if (cabi->cpu_period_start_ticks == 0 &&
+	    rs_proc->rs_proc_task == current) {
+		cabi_rdticks(&cabi->cpu_period_start_ticks);
+	}
+	/* if this is the current process,
+	 * make it the current account and start accouting now */
+	if (current == tsk) {
+		if (cabi_current_account != cabi) {
+			cabi_current_account = cabi;
+		}
+		cabi_start_account(cabi);
+
+		if (cabi->cpu_state & CABI_IS_DEPLETED) {
+			cabi_account_enforce(cabi);
+		}
+	}
+	if (cabi->cabi_id == OVERLOAD_CABI_ID)
+		overload_cabi++;
+
+	return CABI_SUCCESS;
+}
+
+int
+cabi_account_detach(struct task_struct *tsk)
+{
+	cabi_account_t cabi = TASK_ACCOUNT(tsk);
+	struct rs_proc_list *rs_proc = NULL;
+	struct list_head *proc_list;
+
+#ifdef DEBUG_CABI
+	printk("in detach_process: cabi(0x%x) id(%d)\n",
+	       (int) cabi, (int) cabi->cabi_id);
+#endif
+	/* find rs_proc */
+	proc_list = cabi->cpu_proc_list.next;
+	while (proc_list != &cabi->cpu_proc_list) {
+		rs_proc =
+		    list_entry(proc_list, struct rs_proc_list, rs_proc_list);
+		if (rs_proc->rs_proc_pid == tsk->pid) {
+			break;
+		}
+		/* next element */
+		proc_list = proc_list->next;
+	}
+
+	if (rs_proc && rs_proc->rs_proc_pid == tsk->pid) {
+#ifdef	DEBUG_CABI
+		printk("account_detach_process: rs_proc(0x%x) pid(%d,%d)\n",
+		       (int) rs_proc, tsk->pid, rs_proc->rs_proc_pid);
+#endif
+		/* remove rs_proc from the list */
+		list_del(&rs_proc->rs_proc_list);
+
+		/* free rs_proc */
+		INIT_LIST_HEAD(&rs_proc->rs_proc_list);
+		free(rs_proc);
+	}
+	/* detach resource set from task */
+	LVAL_TASK_ACCOUNT(tsk) = NULL_ACCOUNT;
+
+	if (tsk->state != TASK_RUNNING) {
+		wake_up(&cabi->depleted_wait);
+#ifdef DEBUG_CABI
+		printk("wakeup process %d\n", (int)tsk->pid);
+#endif
+	}
+
+	return CABI_SUCCESS;
+}
+
+/*
+ * Linux proc file system interface
+ */
+#include <asm/uaccess.h>
+asmlinkage int
+sys_cabi_account_create(struct cabi_uaccount *ucabi)
+{
+
+	struct timespec c, t;
+	struct cabi_param p;
+	struct cabi_uaccount user_cabi;
+	cabi_account_t cabi;
+	long time_sec, time_nsec, period_sec, period_nsec;
+	cpu_tick_data_t chk_min_time, get_min_time;
+
+	/* permission check */
+	if (current->euid) {
+		printk("cabi_create: Permission denied. EUID [%d], UID [%d]\n",
+		       current->euid, current->uid);
+		return CABI_EACCESS;
+	}
+
+	/* parameter copy */
+	if (copy_from_user(&user_cabi, ucabi, sizeof (struct cabi_uaccount)))
+		return CABI_EINVAL;
+
+	/* parameter check */
+	if (user_cabi.cabi_param.term_act <= CABI_TERM_NONE ||
+	    user_cabi.cabi_param.term_act >= CABI_TERM_UNKNOWN)
+		return CABI_EINVAL;
+
+	if (user_cabi.cabi_param.bind_proc_type < BIND_NORMAL_PROC ||
+	    user_cabi.cabi_param.bind_proc_type > BIND_IDLE_PROC)
+		return CABI_EINVAL;
+
+	if (user_cabi.cabi_param.term_act == CABI_TERM_SIGNAL) {
+		if (user_cabi.cabi_param.cabi_signal.pid < 0)
+			return CABI_EINVAL;
+		if (user_cabi.cabi_param.cabi_signal.sig < 0 ||
+		    user_cabi.cabi_param.cabi_signal.sig > 32)
+			return CABI_EINVAL;
+	}
+
+	if (user_cabi.cpu_time.tv_sec < 0 || user_cabi.cpu_time.tv_nsec < 0)
+		return CABI_EINVAL;
+	if (user_cabi.cpu_time.tv_sec == 0 && user_cabi.cpu_time.tv_nsec == 0)
+		return CABI_EINVAL;
+
+	if (user_cabi.cpu_period.tv_sec < 0 || user_cabi.cpu_period.tv_nsec < 0)
+		return CABI_EINVAL;
+	if (user_cabi.cpu_period.tv_sec == 0 && user_cabi.cpu_period.tv_nsec == 0)
+		return CABI_EINVAL;
+
+	time_sec = 0;
+	time_nsec = 0;
+	time_sec = user_cabi.cpu_time.tv_nsec / NANOSEC;
+	time_nsec = user_cabi.cpu_time.tv_nsec - time_sec * NANOSEC;
+	if (time_sec > (long)(CABI_TIME_SEC_MAX - user_cabi.cpu_time.tv_sec))
+		return CABI_EINVAL;
+	time_sec += user_cabi.cpu_time.tv_sec;
+
+	period_sec = 0;
+	period_nsec = 0;
+	period_sec = user_cabi.cpu_period.tv_nsec / NANOSEC;
+	period_nsec = user_cabi.cpu_period.tv_nsec - period_sec * NANOSEC;
+	if (period_sec > (long)(CABI_TIME_SEC_MAX - user_cabi.cpu_period.tv_sec))
+		return CABI_EINVAL;
+	period_sec += user_cabi.cpu_period.tv_sec;
+#ifdef DEBUG_CABI
+	printk("sys_cabi_create: time_sec(%ld), time_nsec(%ld)\n", time_sec, time_nsec);
+	printk("sys_cabi_create: period_sec(%ld), period_nsec(%ld)\n", period_sec, period_nsec);
+#endif
+	if (time_sec > period_sec) {
+		return CABI_EINVAL;
+	} else if (time_sec == period_sec) {
+		if (time_nsec > period_nsec) {
+			return CABI_EINVAL;
+		}
+	}
+	if (user_cabi.cpu_time.tv_sec == 0) {
+		nanosec2tick((cpu_tick_t)&user_cabi.cpu_time.tv_nsec, &chk_min_time);
+		if (chk_min_time == 0) {
+			printk("cabi_create: cpu_time(%ldns) is too small.\n",
+			       user_cabi.cpu_time.tv_nsec);
+			get_min_time = CABI_TICK_MIN;
+			user_cabi.cpu_time.tv_nsec = tick2nanosec(&get_min_time);
+			printk("cabi_create: cpu_time changes into the minimum value (%ldns) of this system.\n",
+			       user_cabi.cpu_time.tv_nsec);
+		}
+	}
+	if (user_cabi.cpu_period.tv_sec == 0) {
+		nanosec2tick((cpu_tick_t)&user_cabi.cpu_period.tv_nsec, &chk_min_time);
+		if (chk_min_time == 0) {
+			printk("cabi_create: cpu_period(%ldns) is too small.\n",
+			       user_cabi.cpu_period.tv_nsec);
+			get_min_time = CABI_TICK_MIN;
+			user_cabi.cpu_period.tv_nsec = tick2nanosec(&get_min_time);
+			printk("cabi_create: cpu_period changes into the minimum value (%ldns) of this system.\n",
+			       user_cabi.cpu_period.tv_nsec);
+		}
+	}
+	
+	/* 
+	 * for overload cabi, check parameters and set a new cpu_time.
+	 */
+	if (user_cabi.cabi_param.bind_proc_type == BIND_IDLE_PROC) {
+		if ((cabi = search_cabi(OVERLOAD_CABI_ID)) != NULL) {
+			return CABI_EINVAL;
+		}
+		if (user_cabi.cabi_param.term_act != CABI_TERM_SIGNAL) {
+			return CABI_EINVAL;
+		}
+	}
+
+	/* parameter copy */
+	memcpy (&c, &user_cabi.cpu_time, sizeof (struct timespec));
+	memcpy (&t, &user_cabi.cpu_period, sizeof (struct timespec));
+	memcpy (&p, &user_cabi.cabi_param, sizeof (struct cabi_param));
+
+#ifdef DEBUG_CABI
+	printk("sys_cabi_account_create: c(%d), t(%d), term_act(%x)"
+	       " bind_proc_type (%x)\n",
+	       (int) c.tv_nsec, (int) t.tv_nsec, p.term_act, p.bind_proc_type);
+#endif
+	if (!(cabi = cabi_account_create(&c, &t, &p)))
+		return CABI_CREATE_ERR;
+
+	copy_to_user(&ucabi->cabi_id, &cabi->cabi_id,
+		     sizeof (cabi_object_t));
+
+	return CABI_SUCCESS;
+}
+
+asmlinkage int
+sys_cabi_account_get(unsigned long cabi_id, struct cabi_uaccount *ucabi)
+{
+	struct timespec rev_qc;
+	cabi_account_t cabi = NULL_ACCOUNT;
+	struct list_head *proc_list;
+	struct rs_proc_list *rs_proc = NULL;
+
+	if (!ucabi)
+		return CABI_EINVAL;
+
+	if (cabi_id == 0)
+		return CABI_EINVAL;	/* invalid argument */
+
+	/* find cabi address */
+	if (!(cabi = search_cabi(cabi_id)))
+		return CABI_ENOEXIST;
+
+	proc_list = cabi->cpu_proc_list.next;
+	while (proc_list != &cabi->cpu_proc_list) {
+		/* get a rs_proc */
+		rs_proc =
+		    list_entry(proc_list, struct rs_proc_list, rs_proc_list);
+
+		/* next element */
+		proc_list = proc_list->next;
+	}
+
+        /* if this is overload cabi, re-calculate parameters. */
+        if (cabi->cabi_param.bind_proc_type == BIND_IDLE_PROC){
+                overload_capacity(&cabi->cpu_time, &cabi->cpu_period, &rev_qc);
+#ifdef DEBUG_CABI
+		printk("new_cpu_time:%lu cpu_period:%lu\n", 
+			rev_qc.tv_sec, rev_qc.tv_nsec);
+#endif
+		copy_to_user(&ucabi->cpu_time, &rev_qc,
+			     	sizeof (ucabi->cpu_time));
+	} else {
+		copy_to_user(&ucabi->cpu_time, &cabi->cpu_time, 
+				sizeof(ucabi->cpu_time));
+	}
+
+	copy_to_user(&ucabi->cpu_period, &cabi->cpu_period,
+		     	sizeof (ucabi->cpu_period));
+	copy_to_user(&ucabi->cabi_param, &cabi->cabi_param,
+		     	sizeof (ucabi->cabi_param));
+	copy_to_user(&ucabi->cabi_id, &cabi->cabi_id, 
+			sizeof (ucabi->cabi_id));
+
+	return CABI_SUCCESS;
+}
+
+asmlinkage int
+sys_cabi_account_set(unsigned long cabi_id, struct cabi_uaccount *ucabi)
+{
+	struct cabi_uaccount user_cabi;
+	cabi_account_t cabi;
+	struct timespec t, c;
+	cabi_param_data_t p;	
+	long time_sec, time_nsec, period_sec, period_nsec;
+	cpu_tick_data_t chk_min_time, get_min_time;
+
+	/* permission check */
+	if (current->euid) {
+		printk("cabi_set: Permission denied. EUID [%d], UID [%d]\n",
+		       current->euid, current->uid);
+		return CABI_EACCESS;
+	}
+
+	/* parameter copy */
+	if (copy_from_user(&user_cabi, ucabi, sizeof (struct cabi_uaccount)))
+		return CABI_EINVAL;
+
+	/* parameter check */
+	if (cabi_id == 0)
+		return CABI_EINVAL;	/* Invalid argument */
+
+	if (user_cabi.cabi_param.term_act <= CABI_TERM_NONE ||
+	    user_cabi.cabi_param.term_act >= CABI_TERM_UNKNOWN)
+		return CABI_EINVAL;
+
+	if (user_cabi.cabi_param.bind_proc_type < BIND_NORMAL_PROC ||
+	    user_cabi.cabi_param.bind_proc_type > BIND_IDLE_PROC)
+		return CABI_EINVAL;
+
+	if (user_cabi.cabi_param.term_act == CABI_TERM_SIGNAL) {
+		if (user_cabi.cabi_param.cabi_signal.pid < 0)
+			return CABI_EINVAL;
+		if (user_cabi.cabi_param.cabi_signal.sig < 0 ||
+		    user_cabi.cabi_param.cabi_signal.sig > 32)
+			return CABI_EINVAL;
+	}
+
+	if (user_cabi.cpu_time.tv_sec < 0 || user_cabi.cpu_time.tv_nsec < 0)
+		return CABI_EINVAL;
+	if (user_cabi.cpu_time.tv_sec == 0 && user_cabi.cpu_time.tv_nsec == 0)
+		return CABI_EINVAL;
+
+	if (user_cabi.cpu_period.tv_sec < 0 || user_cabi.cpu_period.tv_nsec < 0)
+		return CABI_EINVAL;
+	if (user_cabi.cpu_period.tv_sec == 0 && user_cabi.cpu_period.tv_nsec == 0)
+		return CABI_EINVAL;
+
+	time_sec = 0;
+	time_nsec = 0;
+	time_sec = user_cabi.cpu_time.tv_nsec / NANOSEC;
+	time_nsec = user_cabi.cpu_time.tv_nsec - time_sec * NANOSEC;
+	if (time_sec > (long)(CABI_TIME_SEC_MAX - user_cabi.cpu_time.tv_sec))
+		return CABI_EINVAL;
+	time_sec += user_cabi.cpu_time.tv_sec;
+
+	period_sec = 0;
+	period_nsec = 0;
+	period_sec = user_cabi.cpu_period.tv_nsec / NANOSEC;
+	period_nsec = user_cabi.cpu_period.tv_nsec - period_sec * NANOSEC;
+	if (period_sec > (long)(CABI_TIME_SEC_MAX - user_cabi.cpu_period.tv_sec))
+		return CABI_EINVAL;
+	period_sec += user_cabi.cpu_period.tv_sec;
+#ifdef DEBUG_CABI
+	printk("sys_cabi_set: time_sec(%ld), time_nsec(%ld)\n", time_sec, time_nsec);
+	printk("sys_cabi_set: period_sec(%ld), period_nsec(%ld)\n", period_sec, period_nsec);
+#endif
+
+	if (user_cabi.cpu_time.tv_sec == 0) {
+		nanosec2tick((cpu_tick_t)&user_cabi.cpu_time.tv_nsec, &chk_min_time);
+		if (chk_min_time == 0) {
+			printk("cabi_create: cpu_time(%ldns) is too small.\n",
+			       user_cabi.cpu_time.tv_nsec);
+			get_min_time = CABI_TICK_MIN;
+			user_cabi.cpu_time.tv_nsec = tick2nanosec(&get_min_time);
+			printk("cabi_create: cpu_time changes into the minimum value (%ldns) of this system.\n",
+			       user_cabi.cpu_time.tv_nsec);
+		}
+	}
+	if (user_cabi.cpu_period.tv_sec == 0) {
+		nanosec2tick((cpu_tick_t)&user_cabi.cpu_period.tv_nsec, &chk_min_time);
+		if (chk_min_time == 0) {
+			printk("cabi_create: cpu_period(%ldns) is too small.\n",
+			       user_cabi.cpu_period.tv_nsec);
+			get_min_time = CABI_TICK_MIN;
+			user_cabi.cpu_period.tv_nsec = tick2nanosec(&get_min_time);
+			printk("cabi_create: cpu_period changes into the minimum value (%ldns) of this system.\n",
+			       user_cabi.cpu_period.tv_nsec);
+		}
+	}
+
+	if (time_sec > period_sec) {
+		return CABI_EINVAL;
+	} else if (time_sec == period_sec) {
+		if (time_nsec > period_nsec) {
+			return CABI_EINVAL;
+		}
+	}
+
+	if ((cabi = search_cabi(cabi_id)) == NULL) {
+		return CABI_ENOEXIST;
+	} else {
+		if (user_cabi.cabi_param.bind_proc_type !=
+		    cabi->cabi_param.bind_proc_type)
+			return CABI_EINVAL;
+	}
+
+	/* 
+	 * for overload cabi, check parameters and set a new cpu_time.
+	 */
+	if (user_cabi.cabi_param.bind_proc_type == BIND_IDLE_PROC) {
+		if ((cabi = search_cabi(OVERLOAD_CABI_ID)) == NULL) {
+			return CABI_EINVAL;
+		}
+		if (user_cabi.cabi_param.term_act != CABI_TERM_SIGNAL) {
+			return CABI_EINVAL;
+		}
+	}
+
+	memcpy (&c, &user_cabi.cpu_time, sizeof (struct timespec));
+	memcpy (&t, &user_cabi.cpu_period, sizeof (struct timespec));
+	memcpy (&p, &user_cabi.cabi_param, sizeof (struct cabi_param));
+	
+	return cabi_account_set(cabi_id, &c, &t, &p);
+}
+
+
+asmlinkage int
+sys_cabi_account_destroy(unsigned long cabi_id)
+{
+	/* permission check */
+	if (current->euid) {
+		printk("cabi_destroy: Permission denied. EUID [%d], UID [%d]\n",
+		       current->euid, current->uid);
+		return CABI_EACCESS;
+	}
+
+	if (cabi_id <= 0)
+		return CABI_EINVAL;	/* invalid argument */
+
+	return cabi_account_destroy(cabi_id);
+}
+
+asmlinkage int
+sys_cabi_account_bind_pid(unsigned long cabi_id, pid_t pid)
+{
+	struct task_struct *tsk;
+
+	/* permission check */
+	if (current->euid) {
+		printk("cabi_bind_pid: Permission denied. EUID [%d], UID [%d]\n",
+		       current->euid, current->uid);
+		return CABI_EACCESS;
+	}
+
+	/* parameter check */
+	if (cabi_id == 0) {
+		printk("account_attach_process: invalid cabi_id(%d)\n",
+		       (int) cabi_id);
+		return CABI_EINVAL;	/* invalid argument */
+	}
+
+	if (pid < 0) {
+		printk("account_attach_process: invalid pid(%d)\n", (int) pid);
+		return CABI_EINVAL;	/* invalid argument */
+	}
+
+	/* find overload cabi address. */
+	if (cabi_id == OVERLOAD_CABI_ID) {
+		if (pid != IDLE_PROCESS) {
+			printk("account_bind_pid : overload AO can bind only idol process. pid(%d)\n", pid);
+			return CABI_EINVAL;
+		}
+		if (!(tsk = __cabi_find_idle_process(pid))) {
+			printk("account_bind_pid : idle (%d) failed.\n",
+			       (int) pid);
+			return CABI_EPNOEXIST;	/* PID(0) dose not exist. */
+		} else {
+			printk("idle proces(%d) (0x%x) attched.\n",
+			       tsk->pid, (int) tsk);
+		}
+	} else {
+		if (!(tsk = __cabi_find_process_by_pid(pid))) {
+			printk("account_bind_pid : invalid pid(%d)\n",
+			       (int) pid);
+			return CABI_EPNOEXIST;	/* PID dose not exist. */
+		}
+	}
+
+	if (TASK_ACCOUNT(tsk)) {
+		printk("account_attach_process: account already "
+		       "attached to this process. pid(%d) cabi(0x%x)\n",
+		       tsk->pid, (int) TASK_ACCOUNT(tsk));
+
+		printk("cabi_account_bind_pid : cabi_id (1) %d, (2) %d\n",
+		       (int) cabi_id, (int) TASK_ACCOUNT(tsk)->cabi_id);
+
+		if (cabi_id == TASK_ACCOUNT(tsk)->cabi_id) {
+			/* PID is already registered into AO. */
+			return CABI_EREGIST;
+		} else {
+			/* PID is registered into another AO. */
+			return CABI_ENOAVLE;
+		}
+	}
+#ifdef DEBUG_CABI
+	else {
+		printk("attach pid(%d) cabi(0x%x).\n",
+		       tsk->pid, (int) TASK_ACCOUNT(tsk));
+
+	}
+#endif
+	return cabi_account_attach(cabi_id, tsk);
+}
+
+asmlinkage int
+sys_cabi_account_bind_pgid(unsigned long cabi_id, pid_t pgid)
+{
+	cabi_account_t cabi;
+	struct rglist *rg, *tmp;
+	struct list_head *reg_list;
+	struct task_struct *tsk;
+	int i, ret;
+	int already_registered, shouldbe_registered, group_member, rglist_count;
+
+	/* permission check */
+	if (current->euid) {
+		printk("cabi_bind_pgid: Permission denied. EUID [%d], UID [%d].\n",
+		       current->euid, current->uid);
+		return CABI_EACCESS;
+	}
+
+	/* if pgid is 0, error return */
+	if (pgid == 0) {
+		printk("cabi_bind_pgid: Can not set 0 as pgid.\n");
+		return CABI_EINVAL;
+	}
+
+	already_registered = shouldbe_registered =
+	    group_member = rglist_count = 0;
+
+	INIT_LIST_HEAD(&rglist_head);
+
+	if (cabi_id == 0) {
+		printk("account_bind_pgid : invalid cabi_id(%d)\n",
+		       (int) cabi_id);
+		return CABI_EINVAL;	/* invalid argument */
+	} else if (cabi_id == OVERLOAD_CABI_ID) {
+		printk("account_bind_pgid : cabi_id(%d) is only overload.\n",
+		       (int) cabi_id);
+		return CABI_EINVAL;	/* invalid argument */
+	}
+
+	/* pigid check */
+	if (pgid < 0) {
+		printk("account_bind_pgid: invalid pgid(%d)\n", (int) pgid);
+		return CABI_EINVAL;	/* invalid argument */
+	}
+
+	/* current(caller) check */
+	if (TASK_ACCOUNT(current)) {
+		cabi = TASK_ACCOUNT(current);
+		if (cabi->cabi_id == cabi_id) {
+			already_registered++;
+		} else {
+			/* If the caller was already binded to other AO, we
+			 * return error. */
+			return CABI_ENOAVLE;
+		}
+	} else {
+		/* 
+		 * If the caller process has not bind any AO, we shoud
+		 * bind it to the requested AO. But we will not do 
+		 * anything here, because for_each_task() routine picks
+		 * up a process as a member of the target group process.
+		 */
+	}
+
+	/* 
+	 * If the process which is belong to the same group should be
+	 * bind the requested AO.
+	 */
+	read_lock(&tasklist_lock);
+	for_each_process(tsk) {
+		if (process_group(tsk) == pgid) {
+			group_member++;
+			printk("bind_pgid: tsk->pgid %d group_member %d\n",
+			       process_group(tsk), group_member);
+			/* 
+			 * The process which has the right pgid was found.
+			 * Next, we shoud check if this process has been 
+			 * already bind to other cabi, if so, error return.
+			 */
+			if (TASK_ACCOUNT(tsk)) {
+				printk("bind_pgid: this account already "
+				       "attached to this process. "
+				       " pid(%d) cabi(0x%x)\n",
+				       tsk->pid, (int) TASK_ACCOUNT(tsk));
+				/* 
+				 * If the process has been registered 
+				 * the requested cabi, count up, else
+				 * error return.
+				 */
+				cabi = TASK_ACCOUNT(tsk);
+				if (cabi->cabi_id == cabi_id) {
+					already_registered++;
+				} else {
+					read_unlock(&tasklist_lock);
+					return CABI_ENOAVLE;
+				}
+			} else {
+				/* If the process has not been registered yet,
+				 * we should bind it. But here, we only
+				 * registerd the list.
+				 */
+				if((rg = malloc(sizeof (struct rglist))) == NULL) {
+					read_unlock(&tasklist_lock);
+					return CABI_ENOMEM;
+				}
+				bzero(rg, sizeof (struct rglist));
+				INIT_LIST_HEAD(&rg->rg_link);
+
+				rg->pid = tsk->pid;
+				rg->tsk = tsk;
+
+				list_add(&rg->rg_link, &rglist_head);
+				rglist_count++;
+				shouldbe_registered++;
+			}
+		}
+	}
+	read_unlock(&tasklist_lock);
+
+	if (group_member == 0) {
+		return CABI_EPGNOEXIST;
+	} else if (group_member == already_registered) {
+		return CABI_EREGIST;
+	} else {
+		/* regist processes */
+		reg_list = &rglist_head;
+		for (i = 0; i < shouldbe_registered + 1; i++) {
+			if (reg_list == &rglist_head) {
+				reg_list = reg_list->next;
+			} else {
+				tmp = list_entry(reg_list, struct rglist,
+						 rg_link);
+#ifdef DEBUG_CABI
+				printk("rglist: pid[%d] 0x%x\n",
+				       (int) tmp->pid, (int) tmp->tsk);
+#endif
+				if ((ret =
+				     cabi_account_attach(cabi_id, tmp->tsk))
+				    != CABI_SUCCESS) {
+					printk
+					    ("count: %d bind_pgid attach error : %d\n",
+					     i, ret);
+					return ret;
+				}
+				reg_list = reg_list->next;
+			}
+		}
+	}
+	return CABI_SUCCESS;
+}
+
+asmlinkage int
+sys_cabi_account_unbind(pid_t pid)
+{
+	struct task_struct *tsk;
+
+	/* permission check */
+	if (current->euid) {
+		printk("cabi_unbind: Permission denied. EUID [%d], UID [%d]\n",
+		       current->euid, current->uid);
+		return CABI_EACCESS;
+	}
+
+	if (pid < 0) {
+		printk("account_attach_process: invalid pid(%d)\n", (int) pid);
+		return CABI_EINVAL;	/* Invalid argument */
+	}
+
+	/* find overload cabi address. */
+	if (pid == IDLE_PROCESS) {
+		printk("cabi_account_unbind: overload pid %d\n", pid);
+		if (!(tsk = __cabi_find_idle_process(pid))) {
+			printk("account_unbind: idle (%d) failed.\n", pid);
+			return CABI_EPNOEXIST;	/* PID(0) dose not exist. */
+		} else {
+			printk("unbind: idle task(%d) (0x%x)\n",
+			       tsk->pid, (int) tsk);
+		}
+	} else {
+		if (!(tsk = __cabi_find_process_by_pid(pid))) {
+			printk("cabi_account_unbind: invalid pid(%d)\n", pid);
+			return CABI_EPNOEXIST;	/* PID dose not exist. */
+		}
+	}
+
+	if (!TASK_ACCOUNT(tsk)) {
+		printk("account_unbind: no account attached to "
+		       "this process. pid(%d)\n", tsk->pid);
+		return CABI_ENOBIND;
+	}
+
+	return cabi_account_detach(tsk);
+}
+
+#ifdef CONFIG_PROC_FS
+int
+cabi_account_read_proc(cabi_account_t cabi, char *buf)
+{
+	char *p = buf;
+	unsigned long used_cpu_time;
+	cpu_capacity_t ave, cur, prv;
+	struct rs_proc_list *rs_proc = NULL;
+	struct list_head *proc_list;
+
+	used_cpu_time = TICK2USEC(&cabi->cpu_period_used_ticks);
+	cur = CAPACITY_OF(cabi->cpu_period_used_ticks, cabi->cpu_period_ticks);
+	prv =
+	    CAPACITY_OF(cabi->cpu_period_prev_used_ticks,
+			cabi->cpu_period_ticks);
+
+	if (cabi->cpu_average.total_count) {
+		ave =
+		    cabi->cpu_average.total_utils /
+		    cabi->cpu_average.total_count;
+	} else {
+		ave = cur;
+	}
+
+	/* 1st line: utilization statistics
+	 * reseved, previous, average, max, min */
+	p += sprintf(p, "%lu.%02lu %lu.%02lu %lu.%02lu %lu.%02lu %lu.%02lu\n",
+		     CAPACITY_INT(cabi->cpu_capacity),
+		     CAPACITY_FRAC(cabi->cpu_capacity),
+		     CAPACITY_INT(prv), CAPACITY_FRAC(prv),
+		     CAPACITY_INT(ave), CAPACITY_FRAC(ave),
+		     CAPACITY_INT(cabi->cpu_max_utilization),
+		     CAPACITY_FRAC(cabi->cpu_max_utilization),
+		     CAPACITY_INT(cabi->cpu_min_utilization),
+		     CAPACITY_FRAC(cabi->cpu_min_utilization));
+
+	/* 2nd line: current CPU usage 
+	 * used available requested */
+	p += sprintf(p, "%lu %lu %lu\n",
+		     used_cpu_time,
+		     TICK2USEC(&cabi->cpu_period_available_ticks),
+		     TICK2USEC(&cabi->cpu_time_ticks));
+	/* 3rd line: count of replenishment */
+	p += sprintf(p, "%lu\n", cabi->cpu_average.total_count);
+
+	/* 4th line: account object id */
+	p += sprintf(p, "%lu\n", cabi->cabi_id);
+
+	/* 5th line: process id */
+	/* find rs_proc */
+	proc_list = cabi->cpu_proc_list.next;
+	while (proc_list != &cabi->cpu_proc_list) {
+		/* get a rs_proc */
+		rs_proc = list_entry(proc_list, struct rs_proc_list,
+				     rs_proc_list);
+		p += sprintf(p, "%d ", rs_proc->rs_proc_pid);
+		/* next element */
+		proc_list = proc_list->next;
+	}
+	p += sprintf(p, "\n");
+
+	return (p - buf);
+}
+
+int
+cabi_account_read_bindpid_proc(cabi_account_t cabi, char *buf)
+{
+	char *p = buf;
+	struct rs_proc_list *rs_proc = NULL;
+	struct list_head *proc_list;
+
+	/* find rs_proc */
+	proc_list = cabi->cpu_proc_list.next;
+	while (proc_list != &cabi->cpu_proc_list) {
+		/* get a rs_proc */
+		rs_proc = list_entry(proc_list, struct rs_proc_list,
+				     rs_proc_list);
+		p += sprintf(p, "%d\n", rs_proc->rs_proc_pid);
+		/* next element */
+		proc_list = proc_list->next;
+	}
+
+	return (p - buf);
+}
+
+int
+cabi_account_status_proc(char *buf)
+{
+	char *p = buf;
+
+	/* cabi ticks per second, CPU capacity taken for accounts */
+	p += sprintf(p, "%lu\n",
+		     (unsigned long) cabi_cpu_ticks_per_second);
+
+	return (p - buf);
+}
+
+int
+cabi_account_base_status_proc(char *buf)
+{
+	return 0;
+}
+#endif /* CONFIG_PROC_FS */
diff -Nupr linux-2.6.13.2.orig/drivers/cabi/cabi_init.c linux-2.6.13.2/drivers/cabi/cabi_init.c
--- linux-2.6.13.2.orig/drivers/cabi/cabi_init.c	1970-01-01 09:00:00.000000000 +0900
+++ linux-2.6.13.2/drivers/cabi/cabi_init.c	2005-09-28 03:15:21.752493216 +0900
@@ -0,0 +1,148 @@
+ /*
+  * linux/drivers/cabi/cabi_init.c 
+  * 
+  * CABI -- CPU Accounting and Blocking Interfaces.
+  * 
+  * Copyright (C) OS Research Group, Waseda University Nakajima Laboratory.
+  *               MontaVista Software, Inc. 
+  * 
+  * This software was developed by the Waseda University and Montavista Software,
+  * Inc. Funding for this project was provided by IPA (Information-technology
+  * Promotion Agency, Japan). This software may be used and distributed 
+  * according to the terms of the GNU Public License, incorporated herein by
+  * reference. 
+  * 
+  * This project was developed under the direction of Dr. Tatsuo Nakajima.
+  *
+  * Authors: Midori Sugaya, Hirotaka Ishikawa
+  * 
+  * Please send bug-reports/suggestions/comments to qos@dcl.info.waseda.ac.jp 
+  * 
+  * Futher details about this project can be obtained at
+  * http://dcl.info.waseda.ac.jp/osrg/
+  * 
+  * This is free software; you can redistribute it and/or modify it under
+  * the terms of the GNU Lesser General Public License as published by the
+  * Free Software Foundation; either version 2 of the License, or (at your
+  * option) any later version.
+  *
+  * This software 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.  See the GNU
+  * Lesser General Public License for more details.
+  *
+  * You should have received a copy of the GNU Lesser General Public
+  * License along with this software; if not, write to the Free Software
+  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+  *
+  * This file is derived from software distributed under the following terms:
+  */
+ /*
+  * Real-time and Multimedia Systems Laboratory
+  * Copyright (c) 1999 Carnegie Mellon University
+  * All Rights Reserved.
+  *
+  * Permission to use, copy, modify and distribute this software and its
+  * documentation is hereby granted, provided that both the copyright
+  * notice and this permission notice appear in all copies of the
+  * software, derivative works or modified versions, and any portions
+  * thereof, and that both notices appear in supporting documentation.
+  *
+  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+  *
+  * Carnegie Mellon requests users of this software to return to
+  *
+  *  Real-Time and Multimedia Systems Laboratory
+  *  Attn: Prof. Raj Rajkumar
+  *  Electrical and Computer Engineering, and Computer Science
+  *  Carnegie Mellon University
+  *  Pittsburgh PA 15213-3890
+  *
+  *  or via email to raj@ece.cmu.edu
+  *
+  * any improvements or extensions that they make and grant Carnegie Mellon
+  * the rights to redistribute these changes.
+  */
+
+#include <linux/string.h>
+#include <cabi/cabi.h>
+
+extern void cabi_account_init(void);
+extern void cabi_proc_init(void);
+
+spinlock_t cabi_lock;
+cpu_tick_data_t cabi_cpu_ticks_per_second;
+cpu_tick_data_t cabi_cpu_ticks_per_jiffy;
+cpu_tick_data_t cabi_timer_adjust;
+
+#ifdef CONFIG_X86
+void
+cabi_cpu_calibration_i386(void)
+{
+	cpu_tick_data_t begin, end, err;
+	unsigned long first_jiffies;
+	int i = 5;
+
+	printk("cabi_cpu_calibration: Calibrating cpu ");
+
+	cabi_rdticks(&begin);
+	cabi_rdticks(&end);
+	err = end - begin;
+
+	/* wait for "start of" clock tick */
+	first_jiffies = jiffies;
+	while (first_jiffies == jiffies) {
+		/* nothing */
+	}
+	cabi_rdticks(&begin);
+	while (i-- > 0) {
+		first_jiffies = jiffies;
+		printk(".");
+		while (jiffies - first_jiffies < HZ) {
+			/* nothing */
+		}
+	}
+	cabi_rdticks(&end);
+	/* */
+	cabi_cpu_ticks_per_second = (end - begin - err) / 5;
+	{
+		cpu_tick_data_t t;
+		t = CABI_NANOSECS_PER_JIFFY;
+		nanosec2tick(&t, &cabi_cpu_ticks_per_jiffy);
+	}
+	/* */
+
+	printk(" %lu cycles per second.\n",
+	       (unsigned long) cabi_cpu_ticks_per_second);
+}
+#else	/* #ifdef CONFIG_X86 */
+void
+cabi_cpu_calibration(void)
+{
+	printk("cabi initialize...\n");
+	cabi_cpu_ticks_per_second = CABI_CLOCK;
+	{
+		cpu_tick_data_t t;
+		t = CABI_NANOSECS_PER_JIFFY;
+		nanosec2tick(&t, &cabi_cpu_ticks_per_jiffy);
+	}
+}
+#endif	/* #ifdef CONFIG_X86 */
+
+void
+cabi_init(void)
+{
+	spin_lock_init(&cabi_lock);
+	cabi_account_init();
+#ifdef CONFIG_X86
+	cabi_cpu_calibration_i386();
+#else
+	cabi_cpu_calibration();
+#endif	/* #ifdef CONFIG_X86 */
+
+#ifdef CONFIG_PROC_FS
+	cabi_proc_init();
+#endif
+}
diff -Nupr linux-2.6.13.2.orig/drivers/cabi/cabi_isr.c linux-2.6.13.2/drivers/cabi/cabi_isr.c
--- linux-2.6.13.2.orig/drivers/cabi/cabi_isr.c	1970-01-01 09:00:00.000000000 +0900
+++ linux-2.6.13.2/drivers/cabi/cabi_isr.c	2005-09-28 03:15:21.753492985 +0900
@@ -0,0 +1,270 @@
+/*
+  * linux/drivers/cabi/cabi_isr.c
+  * 
+  * CABI -- CPU Accounting and Blocking Interfaces.
+  * 
+  * Copyright (C) OS Research Group, Waseda University Nakajima Laboratory.
+  *               MontaVista Software, Inc. 
+  * 
+  * This software was developed by the Waseda University and Montavista Software,
+  * Inc. Funding for this project was provided by IPA (Information-technology
+  * Promotion Agency, Japan). This software may be used and distributed 
+  * according to the terms of the GNU Public License, incorporated herein by
+  * reference. 
+  * 
+  * This project was developed under the direction of Dr. Tatsuo Nakajima.
+  *
+  * Authors: Midori Sugaya, Hirotaka Ishikawa
+  * 
+  * Please send bug-reports/suggestions/comments to doly@dcl.info.waseda.ac.jp 
+  * 
+  * Futher details about this project can be obtained at
+  * http://dcl.info.waseda.ac.jp/osrg/
+  * 
+  * This is free software; you can redistribute it and/or modify it under
+  * the terms of the GNU Lesser General Public License as published by the
+  * Free Software Foundation; either version 2 of the License, or (at your
+  * option) any later version.
+  *
+  * This software 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.  See the GNU
+  * Lesser General Public License for more details.
+  *
+  * You should have received a copy of the GNU Lesser General Public
+  * License along with this software; if not, write to the Free Software
+  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+  *
+  * This file is derived from software distributed under the following terms:
+  */
+ /*
+  * Real-time and Multimedia Systems Laboratory
+  * Copyright (c) 1999 Carnegie Mellon University
+  * All Rights Reserved.
+  *
+  * Permission to use, copy, modify and distribute this software and its
+  * documentation is hereby granted, provided that both the copyright
+  * notice and this permission notice appear in all copies of the
+  * software, derivative works or modified versions, and any portions
+  * thereof, and that both notices appear in supporting documentation.
+  *
+  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+  *
+  * Carnegie Mellon requests users of this software to return to
+  *
+  *  Real-Time and Multimedia Systems Laboratory
+  *  Attn: Prof. Raj Rajkumar
+  *  Electrical and Computer Engineering, and Computer Science
+  *  Carnegie Mellon University
+  *  Pittsburgh PA 15213-3890
+  *
+  *  or via email to raj@ece.cmu.edu
+  *
+  * any improvements or extensions that they make and grant Carnegie Mellon
+  * the rights to redistribute these changes.
+  */
+
+#include <cabi/cabi_error.h>
+#include <cabi/cabi.h>
+#include <asm/system.h>
+#include <asm/io.h>
+
+#ifdef	DEBUG_CABI
+#include <linux/posix-timers.h>
+
+#ifdef  CONFIG_HIGH_RES_TIMERS
+#include <linux/hrtime.h>
+#endif
+#undef	DEBUG_CABI_ISR
+#endif				/*DEBUG_CABI */
+
+extern cabi_account_t cabi_current_account;
+/*
+ * Hooks
+ */
+int (*cabi_ret_with_reschedule_hook) (void);
+
+/*
+ * For "cabi_ret_with_reschedule_hook", cabi_ret_with_reschedule is called when
+ * a process exits from the kernel after processing a system call.
+ */
+asmlinkage int
+cabi_ret_with_reschedule(void)
+{
+	cabi_account_t cabi;
+
+#ifdef DEBUG_CABI
+	struct now_struct now;
+	posix_get_now(&now);
+#endif
+	if ((cabi = cabi_current_account)) {
+#ifdef DEBUG_CABI
+		printk("in ret_with_reschedule: cabi_current_account:%d\n",
+		       (int) cabi_current_account->cabi_id);
+#endif
+		if ((cabi_account_depleted(cabi)) ||
+		    (cabi_account_overload(cabi))) {
+
+			switch (cabi->cabi_param.term_act) {
+			case CABI_TERM_BLOCK:
+
+				if (cabi->term_act_status != CABI_UNBLOCK)
+					cabi->term_act_status = CABI_UNBLOCK;
+#if defined(DEBUG_CABI_ISR) || defined(DEBUG_CABI_ENFORCE)
+				printk
+				    ("cabi_ret_with_reschedule: depleted cabi(0x%x) "
+				     "pid(%d) current(%lu, %lu)\n", (int) cabi,
+				     current->pid, now.jiffies,
+				     (u_long) now.sub_jiffie);
+#endif				/* DEBUG_CABI_ENFORCE */
+				/* sleep_on only when hard enforcement */
+				local_irq_enable();
+				cabi->term_act_status = CABI_BLOCKED;
+				cabi->block_count++;
+				cabi_account_sleep_on(cabi);
+#ifdef DEBUG_CABI
+				printk("cabi_account_sleep_on\n");
+#endif
+				return 1;
+				break;
+
+			case CABI_TERM_SIGNAL:
+
+				if(cabi->term_act_status != CABI_SIGNAL) 
+					cabi->term_act_status = CABI_SIGNAL;
+
+				/* for overloaded process */
+				if (cabi_account_overload(cabi)) {
+#ifdef DEBUG_CABI
+					printk
+					    ("isr[1]: overload pid(%d) cpu_state(%x)\n",
+					     current->pid, cabi->cpu_state);
+#endif
+					if (!cabi->signal_block) {
+						cabi_send_signal(cabi, 
+							 CABI_SIGPID(cabi),
+							 CABI_SIGNUM(cabi));
+					} else {
+
+#ifdef DEBUG_CABI
+						printk("[1] Already sent signal. %d\n",
+							cabi->signal_block);
+#endif
+					}
+
+				/* if it is normal process */
+				}  else if (!CABI_SIGFLAG(cabi)) {
+#ifdef DEBUG_CABI
+					printk
+					    ("isr[2]: overload pid(%d) cpu_state(%x)\n",
+					     current->pid, cabi->cpu_state);
+#endif
+					/* current process will receive the signal. */
+					if (!cabi->signal_block) {
+						cabi_send_signal(cabi,  current->pid, CABI_SIGNUM(cabi));
+					} else { 
+#ifdef DEBUG_CABI
+						printk("[2] Already sent signal. %d\n",
+							cabi->signal_block);
+#endif
+				}
+				} else {
+#ifdef DEBUG_CABI
+					printk
+					    ("isr[3]: ret_with: signal\n");
+#endif
+					if (!cabi->signal_block) {
+						cabi_send_signal(cabi, CABI_SIGPID(cabi), CABI_SIGNUM(cabi));
+					} else {
+#ifdef DEBUG_CABI
+						printk("[3] Already sent signal. %d\n",
+							cabi->signal_block);
+#endif
+					}
+				}
+				break;
+			case CABI_TERM_UNKNOWN:
+			case CABI_TERM_NONE:
+				cabi_current_account = NULL_ACCOUNT;
+
+#ifdef DEBUG_CABI
+				printk("cabi_ret_with_reschedule : "
+				       "null account : term_act(%d)\n",
+				       cabi->cabi_param.term_act);
+#endif
+				break;
+			default:
+				cabi_current_account = NULL_ACCOUNT;
+#ifdef DEBUG_CABI
+				printk("cabi_ret_with_reschedule: cabi(0x%x)"
+				       "term_act(%d)\n",
+				       (int) cabi, cabi->cabi_param.term_act);
+#endif
+			}
+		}
+	}
+	return 0;
+}
+
+void
+cabi_enable_isr(void)
+{
+	unsigned long flags;
+
+	if (cabi_ret_with_reschedule_hook == cabi_ret_with_reschedule)
+		return;
+
+	cabi_spin_lock(flags);
+	{
+		/* install hooks */
+		cabi_ret_with_reschedule_hook = cabi_ret_with_reschedule;
+		/* start Rk timer */
+		cabi_timer_start();
+	}
+	cabi_spin_unlock(flags);
+#ifdef	DEBUG_CABI
+	printk("cabi_enable_isr: cabi kernel in/out hook enabled.\n");
+#endif
+}
+
+void
+cabi_disable_isr(void)
+{
+	unsigned long flags;
+
+	if (cabi_ret_with_reschedule_hook == (void *) 0)
+		return;
+
+	cabi_spin_lock(flags);
+	{
+		/* remove hooks */
+		cabi_ret_with_reschedule_hook = (void *) 0;
+	}
+	cabi_spin_unlock(flags);
+#ifdef	DEBUG_CABI
+	printk("cabi_disable_isr: cabi kernel in/out hook diabled.\n");
+#endif
+}
+
+
+#ifdef CONFIG_PROC_FS
+
+int 
+cabi_account_read_block_proc(cabi_account_t cabi, char *buf)
+{
+	char *p = buf;
+	
+	if (cabi->term_act_status == CABI_SIGNAL) {
+		p += sprintf(p, "%d\n%lu\n", cabi->term_act_status, 
+							cabi->signal_count);
+	} else {
+		printk("block status %d\n", cabi->term_act_status);
+		p += sprintf(p, "%d\n%lu\n", cabi->term_act_status, 
+							cabi->block_count);
+	}
+	return (p - buf);
+}
+
+#endif /* CONFIG_PROC_FS */
diff -Nupr linux-2.6.13.2.orig/drivers/cabi/cabi_procfs.c linux-2.6.13.2/drivers/cabi/cabi_procfs.c
--- linux-2.6.13.2.orig/drivers/cabi/cabi_procfs.c	1970-01-01 09:00:00.000000000 +0900
+++ linux-2.6.13.2/drivers/cabi/cabi_procfs.c	2005-09-28 03:15:21.753492985 +0900
@@ -0,0 +1,219 @@
+ /*
+  * linux/drivers/cabi/cabi_procfs.c - implements the interfaces for procfs.
+  * 
+  * CABI -- CPU Accounting and Blocking Interfaces.
+  * 
+  * Copyright (C) OS Research Group, Waseda University Nakajima Laboratory.
+  *               MontaVista Software, Inc. 
+  * 
+  * This software was developed by the Waseda University and Montavista Software,
+  * Inc. Funding for this project was provided by IPA (Information-technology
+  * Promotion Agency, Japan). This software may be used and distributed 
+  * according to the terms of the GNU Public License, incorporated herein by
+  * reference. 
+  * 
+  * This project was developed under the direction of Dr. Tatsuo Nakajima.
+  *
+  * Authors: Midori Sugaya, Hirotaka Ishikawa
+  * 
+  * Please send bug-reports/suggestions/comments to doly@dcl.info.waseda.ac.jp 
+  * 
+  * Futher details about this project can be obtained at
+  * http://dcl.info.waseda.ac.jp/osrg/
+  * 
+  * This is free software; you can redistribute it and/or modify it under
+  * the terms of the GNU Lesser General Public License as published by the
+  * Free Software Foundation; either version 2 of the License, or (at your
+  * option) any later version.
+  *
+  * This software 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.  See the GNU
+  * Lesser General Public License for more details.
+  *
+  * You should have received a copy of the GNU Lesser General Public
+  * License along with this software; if not, write to the Free Software
+  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+  *
+  * This file is derived from software distributed under the following terms:
+  */
+ /*
+  * Real-time and Multimedia Systems Laboratory
+  * Copyright (c) 1999 Carnegie Mellon University
+  * All Rights Reserved.
+  *
+  * Permission to use, copy, modify and distribute this software and its
+  * documentation is hereby granted, provided that both the copyright
+  * notice and this permission notice appear in all copies of the
+  * software, derivative works or modified versions, and any portions
+  * thereof, and that both notices appear in supporting documentation.
+  *
+  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+  *
+  * Carnegie Mellon requests users of this software to return to
+  *
+  *  Real-Time and Multimedia Systems Laboratory
+  *  Attn: Prof. Raj Rajkumar
+  *  Electrical and Computer Engineering, and Computer Science
+  *  Carnegie Mellon University
+  *  Pittsburgh PA 15213-3890
+  *
+  *  or via email to raj@ece.cmu.edu
+  *
+  * any improvements or extensions that they make and grant Carnegie Mellon
+  * the rights to redistribute these changes.
+  */
+#include <linux/init.h>
+#include <linux/proc_fs.h>
+#include <linux/stat.h>
+
+#include <cabi/cabi.h>
+
+#define MAX_LEN 10
+#define NR_CABI 1000
+#define ENTRIES 4
+
+
+#ifdef CONFIG_PROC_FS
+
+/* proc root directory */
+static struct proc_dir_entry *proc_cabi_dir; 
+/* proc object_id directories */
+static struct proc_dir_entry *cabi_id_dir [NR_CABI];
+
+static int
+proc_cabi_status_read(char *page, char **start, off_t off,
+		     int count, int *eof, void *data)
+{
+	cabi_account_t cabi = (cabi_account_t) data;
+	return cabi_account_read_proc(cabi, page);
+}
+
+static int
+proc_cabi_base_status_read (char *page, char **start, off_t off,
+			int count, int *eof, void *data)
+{
+	char *p = page;
+	extern int cabi_account_base_status_proc(char *);
+
+	p += cabi_account_base_status_proc(p);
+
+	return (p - page);
+}
+ 
+static int
+proc_cabi_block_read(char *page, char **start, off_t off,
+		      int count, int *eof, void *data)
+{
+	 cabi_account_t cabi = (cabi_account_t) data;	
+
+#ifdef DEBUG_CABI
+	printk("term_act_status %d\n", cabi->term_act_status);
+#endif
+	return cabi_account_read_block_proc(cabi, page);
+	
+}
+
+static int
+proc_cabi_bindpid_read(char *page, char **start, off_t off,
+		      int count, int *eof, void *data)
+{
+
+	cabi_account_t cabi = (cabi_account_t) data;
+	return cabi_account_read_bindpid_proc (cabi, page);
+
+}
+
+static int
+proc_cabi_time_read (char *page, char **start, off_t off,
+		int count, int *eof, void *data)
+{
+	cabi_account_t cabi = (cabi_account_t) data;
+	return cabi_account_read_time_proc(cabi, page);
+}
+
+void __init
+cabi_proc_init(void)
+{
+	struct proc_dir_entry *proc_cabi_status;
+	
+	/* proc directory entry */
+	proc_cabi_dir = create_proc_entry("cabi", S_IFDIR, 0);
+
+	if (!proc_cabi_dir) {
+	  printk("Cannot create /proc/cabi\n");
+	}
+
+	proc_cabi_status = create_proc_entry("cabi_status", S_IFREG | S_IRUGO,
+						proc_cabi_dir);
+	proc_cabi_status->read_proc = proc_cabi_base_status_read;
+}
+
+
+struct cabi_entry_list {
+  const char *name;
+  int (*f)(char *, char **, off_t, int, int *, void *);
+} CABI_PROC_ENTRY[] = { 
+  { "status",   proc_cabi_status_read},
+  { "term_act",    proc_cabi_block_read},
+  { "bind_pid",  proc_cabi_bindpid_read},
+  { "time_set", proc_cabi_time_read},
+};
+
+void 
+cabi_register_proc_account(cabi_account_t cabi)
+{
+	int i;
+	struct proc_dir_entry *entry;
+	unsigned char string[MAX_LEN];
+  
+	sprintf(string, "%d", (int) cabi->cabi_id);
+	cabi_id_dir[cabi->cabi_id] = proc_mkdir (string, proc_cabi_dir);
+  
+	if (!cabi_id_dir[cabi->cabi_id])
+		printk("Cannot create /proc/cabi/%d\n", (int)cabi->cabi_id);
+  
+  
+	for (i = 0; i < ENTRIES; i++) {
+    		entry = create_proc_entry (CABI_PROC_ENTRY[i].name, 
+			S_IFREG|S_IRUGO, cabi_id_dir[cabi->cabi_id]);
+
+		if (!entry)
+			printk("Cannot create /proc/cabi/%d/%s\n",
+				(int) cabi->cabi_id, CABI_PROC_ENTRY[i].name);
+    
+		entry->nlink = 1;
+		entry->data = cabi;
+		entry->read_proc = *CABI_PROC_ENTRY[i].f;
+	}
+}
+
+
+void
+cabi_proc_account_create(cabi_account_t cabi)
+{
+
+#ifdef	DEBUG_CABI
+	printk("cabi_proc_account_create: cabi(0x%x) cabi_id (%d) \n", 
+	       (int) cabi, (int) cabi->cabi_id);
+#endif
+	cabi_register_proc_account(cabi);
+
+
+}
+
+void
+cabi_proc_account_destroy(cabi_account_t cabi)
+{
+        char buf[16];
+
+#ifdef  DEBUG_CABI
+        printk("cabi_proc_account_destroy: cabi(%d)", (int) cabi->cabi_id);
+#endif
+        sprintf(buf, "%d", (int) cabi->cabi_id);
+        remove_proc_entry(buf, proc_cabi_dir);
+}
+
+#endif /* CONFIG_PROC_FS */
diff -Nupr linux-2.6.13.2.orig/drivers/cabi/cabi_sched.c linux-2.6.13.2/drivers/cabi/cabi_sched.c
--- linux-2.6.13.2.orig/drivers/cabi/cabi_sched.c	1970-01-01 09:00:00.000000000 +0900
+++ linux-2.6.13.2/drivers/cabi/cabi_sched.c	2005-09-28 03:15:21.754492754 +0900
@@ -0,0 +1,142 @@
+ /*
+  * linux/drivers/cabi/cabi_sched.c
+  * 
+  * CABI -- CPU Accounting and Blocking Interfaces.
+  * 
+  * Copyright (C) OS Research Group, Waseda University Nakajima Laboratory.
+  *               MontaVista Software, Inc. 
+  * 
+  * This software was developed by the Waseda University and Montavista Software,
+  * Inc. Funding for this project was provided by IPA (Information-technology
+  * Promotion Agency, Japan). This software may be used and distributed 
+  * according to the terms of the GNU Public License, incorporated herein by
+  * reference. 
+  * 
+  * This project was developed under the direction of Dr. Tatsuo Nakajima.
+  *
+  * Authors: Midori Sugaya, Hirotaka Ishikawa
+  * 
+  * Please send bug-reports/suggestions/comments to qos@dcl.info.waseda.ac.jp 
+  * 
+  * Futher details about this project can be obtained at
+  * http://dcl.info.waseda.ac.jp/osrg/
+  * 
+  * This is free software; you can redistribute it and/or modify it under
+  * the terms of the GNU Lesser General Public License as published by the
+  * Free Software Foundation; either version 2 of the License, or (at your
+  * option) any later version.
+  *
+  * This software 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.  See the GNU
+  * Lesser General Public License for more details.
+  *
+  * You should have received a copy of the GNU Lesser General Public
+  * License along with this software; if not, write to the Free Software
+  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+  *
+  * This file is derived from software distributed under the following terms:
+  */
+ /*
+  * Real-time and Multimedia Systems Laboratory
+  * Copyright (c) 1999 Carnegie Mellon University
+  * All Rights Reserved.
+  *
+  * Permission to use, copy, modify and distribute this software and its
+  * documentation is hereby granted, provided that both the copyright
+  * notice and this permission notice appear in all copies of the
+  * software, derivative works or modified versions, and any portions
+  * thereof, and that both notices appear in supporting documentation.
+  *
+  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+  *
+  * Carnegie Mellon requests users of this software to return to
+  *
+  *  Real-Time and Multimedia Systems Laboratory
+  *  Attn: Prof. Raj Rajkumar
+  *  Electrical and Computer Engineering, and Computer Science
+  *  Carnegie Mellon University
+  *  Pittsburgh PA 15213-3890
+  *
+  *  or via email to raj@ece.cmu.edu
+  *
+  * any improvements or extensions that they make and grant Carnegie Mellon
+  * the rights to redistribute these changes.
+  */
+
+#include <cabi/cabi.h>
+#include <linux/posix-timers.h>
+
+ /**/
+/* #undef	DEBUG_CABI_SCHED */
+ /**/ extern cabi_account_t cabi_current_account;
+
+void (*cabi_schedule_hook) (struct task_struct *, struct task_struct *);
+
+void
+cabi_schedule_cpu(struct task_struct *prev, struct task_struct *next)
+{
+	cpu_tick_data_t now;
+	cabi_account_t prev_cabi = TASK_ACCOUNT(prev);
+	cabi_account_t next_cabi = TASK_ACCOUNT(next);
+	struct now_struct pnow;
+	posix_get_now(&pnow);
+
+
+#ifdef DEBUG_CABI_SCHED
+	if (prev_cabi || next_cabi) {
+		printk
+		    ("cabi_schedule_cpu: pid(%d) cabi(0x%x) -> pid(%d) cabi(0x%x)\n",
+		     prev->pid, (int) prev_cabi, next->pid, (int) next_cabi);
+	}
+#endif
+	if (prev_cabi != next_cabi) {
+		cabi_enforce_timer_cancel();
+		/* if there is a current cabi, stop it */
+
+		if (prev_cabi == cabi_current_account) {
+			if (cabi_current_account) {
+				cabi_rdticks(&now);
+				cabi_stop_account(cabi_current_account, &now);
+			}
+		}
+		/* if there is a cabi for next, start it */
+		if ((cabi_current_account = next_cabi)) {
+#ifdef DEBUG_CABI
+			printk("cabi_schedule_cpu: cabi(0x%x) depleted. "
+			       "current(%lu, %lu) next_cabi_id[%d]\n",
+			       (int) next_cabi, pnow.jiffies,
+			       (u_long) pnow.sub_jiffie,
+			       (int) next_cabi->cabi_id);
+#endif
+			cabi_start_account(next_cabi);
+		}
+	}
+}
+
+void
+cabi_enable_schedule_cpu(void)
+{
+	if (!cabi_schedule_hook) {
+		cabi_schedule_hook = cabi_schedule_cpu;
+#ifdef	DEBUG_CABI
+		printk
+		    ("cabi_enable_schedule_cpu: cabi_schedule_hook enabled\n");
+#endif
+	}
+}
+
+void
+cabi_disable_schedule_cpu(void)
+{
+	if (cabi_schedule_hook) {
+		cabi_schedule_hook = (void *) 0;
+#ifdef	DEBUG_CABI
+		printk
+		    ("cabi_disable_schedule_cpu: cabi_schedule_hook disabled\n");
+#endif
+
+	}
+}
diff -Nupr linux-2.6.13.2.orig/drivers/cabi/cabi_signal.c linux-2.6.13.2/drivers/cabi/cabi_signal.c
--- linux-2.6.13.2.orig/drivers/cabi/cabi_signal.c	1970-01-01 09:00:00.000000000 +0900
+++ linux-2.6.13.2/drivers/cabi/cabi_signal.c	2005-09-28 03:15:21.755492522 +0900
@@ -0,0 +1,128 @@
+ /*
+  * linux/drivers/cabi/cabi_signal.c 
+  * 
+  * CABI -- CPU Accounting and Blocking Interfaces.
+  * 
+  * Copyright (C) OS Research Group, Waseda University Nakajima Laboratory.
+  *               MontaVista Software, Inc. 
+  * 
+  * This software was developed by the Waseda University and Montavista Software,
+  * Inc. Funding for this project was provided by IPA (Information-technology
+  * Promotion Agency, Japan). This software may be used and distributed 
+  * according to the terms of the GNU Public License, incorporated herein by
+  * reference. 
+  * 
+  * This project was developed under the direction of Dr. Tatsuo Nakajima.
+  *
+  * Authors: Midori Sugaya, Hirotaka Ishikawa
+  * 
+  * Please send bug-reports/suggestions/comments to qos@dcl.info.waseda.ac.jp 
+  * 
+  * Futher details about this project can be obtained at
+  * http://dcl.info.waseda.ac.jp/osrg/
+  * 
+  * This is free software; you can redistribute it and/or modify it under
+  * the terms of the GNU Lesser General Public License as published by the
+  * Free Software Foundation; either version 2 of the License, or (at your
+  * option) any later version.
+  *
+  * This software 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.  See the GNU
+  * Lesser General Public License for more details.
+  *
+  * You should have received a copy of the GNU Lesser General Public
+  * License along with this software; if not, write to the Free Software
+  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+  *
+  * This file is derived from software distributed under the following terms:
+  */
+ /*
+  * Real-time and Multimedia Systems Laboratory
+  * Copyright (c) 1999 Carnegie Mellon University
+  * All Rights Reserved.
+  *
+  * Permission to use, copy, modify and distribute this software and its
+  * documentation is hereby granted, provided that both the copyright
+  * notice and this permission notice appear in all copies of the
+  * software, derivative works or modified versions, and any portions
+  * thereof, and that both notices appear in supporting documentation.
+  *
+  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+  *
+  * Carnegie Mellon requests users of this software to return to
+  *
+  *  Real-Time and Multimedia Systems Laboratory
+  *  Attn: Prof. Raj Rajkumar
+  *  Electrical and Computer Engineering, and Computer Science
+  *  Carnegie Mellon University
+  *  Pittsburgh PA 15213-3890
+  *
+  *  or via email to raj@ece.cmu.edu
+  *
+  * any improvements or extensions that they make and grant Carnegie Mellon
+  * the rights to redistribute these changes.
+  */
+
+#include <cabi/cabi_error.h>
+#include <cabi/cabi.h>
+
+int
+cabi_send_signal(cabi_account_t cabi, int pid, int sig)
+{
+
+	int error;
+	struct siginfo info;
+	struct task_struct *tsk;
+
+	/* Set the siginfo */
+	info.si_signo = sig;
+	info.si_errno = 0;
+	info.si_code = SI_KERNEL;
+	info.si_pid = 0;
+	info.si_uid = 0;
+
+	if (sig <= 0)
+		return -EINVAL;  
+
+	/* This is only valid for normal process(not idle process). */
+	if (pid <= 0)
+		return -EINVAL;
+
+	error = -ESRCH;
+	
+	/* search process by pid */
+	if (!(tsk = __cabi_find_process_by_pid(pid))) {
+#ifdef DEBUG_CABI
+		printk("cabi_send_signal: invalid pid (%d).\n", pid);
+		printk("Cabi did not send signal, not exist received process. (%d)\n", pid);
+#endif
+		return error;
+	} else {
+#ifdef DEBUG_CABI
+		printk("cabi_send_signal: pid %d sig %d \n", pid, sig);
+                printk("[signal] pid %d status %d\n",
+                                (int) tsk->pid, (int)tsk->state);
+                printk("signal_struct: count %d\n", 
+				(int)tsk->sig->count.counter);
+#endif
+		error = send_sig_info(sig, &info, tsk);
+
+		if (error<0) {
+#ifdef DEBUG_CABI
+			printk("Could not send %d signal\n", sig);
+#endif
+		} else {
+#ifdef DEBUG_CABI
+			printk("Signal %d was sent.\n", sig);
+#endif
+			cabi->signal_block = SIGNAL_ON;
+			cabi->signal_count++;
+		}
+			
+	}
+	return error;
+
+}
diff -Nupr linux-2.6.13.2.orig/drivers/cabi/cabi_timer.c linux-2.6.13.2/drivers/cabi/cabi_timer.c
--- linux-2.6.13.2.orig/drivers/cabi/cabi_timer.c	1970-01-01 09:00:00.000000000 +0900
+++ linux-2.6.13.2/drivers/cabi/cabi_timer.c	2005-09-28 03:15:21.755492522 +0900
@@ -0,0 +1,315 @@
+ /*
+  * linux/drivers/cabi/cabi_timer.c 
+  * 
+  * CABI -- CPU Accounting and Blocking Interfaces.
+  * 
+  * Copyright (C) OS Research Group, Waseda University Nakajima Laboratory.
+  *               MontaVista Software, Inc. 
+  * 
+  * This software was developed by the Waseda University and Montavista Software,
+  * Inc. Funding for this project was provided by IPA (Information-technology
+  * Promotion Agency, Japan). This software may be used and distributed 
+  * according to the terms of the GNU Public License, incorporated herein by
+  * reference. 
+  * 
+  * This project was developed under the direction of Dr. Tatsuo Nakajima.
+  *
+  * Authors: Midori Sugaya, Hirotaka Ishikawa
+  * 
+  * Please send bug-reports/suggestions/comments to qos@dcl.info.waseda.ac.jp 
+  * 
+  * Futher details about this project can be obtained at
+  * http://dcl.info.waseda.ac.jp/osrg/
+  * 
+  * This is free software; you can redistribute it and/or modify it under
+  * the terms of the GNU Lesser General Public License as published by the
+  * Free Software Foundation; either version 2 of the License, or (at your
+  * option) any later version.
+  *
+  * This software 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.  See the GNU
+  * Lesser General Public License for more details.
+  *
+  * You should have received a copy of the GNU Lesser General Public
+  * License along with this software; if not, write to the Free Software
+  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+  *
+  * This file is derived from software distributed under the following terms:
+  */
+ /*
+  * Real-time and Multimedia Systems Laboratory
+  * Copyright (c) 1999 Carnegie Mellon University
+  * All Rights Reserved.
+  *
+  * Permission to use, copy, modify and distribute this software and its
+  * documentation is hereby granted, provided that both the copyright
+  * notice and this permission notice appear in all copies of the
+  * software, derivative works or modified versions, and any portions
+  * thereof, and that both notices appear in supporting documentation.
+  *
+  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+  *
+  * Carnegie Mellon requests users of this software to return to
+  *
+  *  Real-Time and Multimedia Systems Laboratory
+  *  Attn: Prof. Raj Rajkumar
+  *  Electrical and Computer Engineering, and Computer Science
+  *  Carnegie Mellon University
+  *  Pittsburgh PA 15213-3890
+  *
+  *  or via email to raj@ece.cmu.edu
+  *
+  * any improvements or extensions that they make and grant Carnegie Mellon
+  * the rights to redistribute these changes.
+  */
+
+#include <linux/time.h>
+#include <linux/timer.h>
+#include <linux/config.h>
+#include <linux/posix-timers.h>
+#include <cabi/cabi.h>
+#include <cabi/cabi_error.h>
+
+extern struct k_clock posix_clocks[MAX_CLOCKS];
+#ifdef CONFIG_HIGH_RES_TIMERS
+#include <linux/hrtime.h>
+#include <asm/hrtime.h>
+extern int nsec_to_arch_cycle(unsigned long nsec);
+
+int
+tstojiffie(struct timespec *tp, int res, unsigned long *jiff)
+{
+	unsigned long sec = tp->tv_sec;
+	long nsec = tp->tv_nsec + res - 1;
+
+	/*
+	 * A note on jiffy overflow: It is possible for the system to
+	 * have been up long enough for the jiffies quanity to overflow.
+	 * In order for correct timer evaluations we require that the
+	 * specified time be somewhere between now and now + (max
+	 * unsigned int/2).  Times beyond this will be truncated back to
+	 * this value.  This is done in the absolute adjustment code,
+	 * below.  Here it is enough to just discard the high order
+	 * bits.  
+	 */
+	*jiff = HZ * sec;
+	/*
+	 * Do the res thing. (Don't forget the add in the declaration of nsec) 
+	 */
+	nsec -= nsec % res;
+	/*
+	 * Split to jiffie and sub jiffie
+	 */
+	*jiff += nsec / (NSEC_PER_SEC / HZ);
+	/*
+	 * We trust that the optimizer will use the remainder from the 
+	 * above div in the following operation as long as they are close. 
+	 */
+
+	return (nsec_to_arch_cycle(nsec % (NSEC_PER_SEC / HZ)));
+}
+
+extern int tstojiffie(struct timespec *tp, int res, unsigned long *jiff);
+#else
+__inline__ void
+cabi_tstojiffie(struct timespec *tp, unsigned long *jiff)
+{
+	*jiff = HZ * tp->tv_sec;
+	*jiff += (tp->tv_nsec + (NANOSEC / HZ)) / (NANOSEC / HZ);
+} 
+#endif				/* CONFIG_HRES_TIMERS & !MONTAVISTA_LINUX */
+
+extern cabi_account_t cabi_current_account;
+
+/*
+ * cabi_replenish_timer_process(cabi_timer_t tmr)
+ */
+void
+cabi_replenish_timer_process(cabi_account_t cabi)
+{
+	struct timer_list *tmr = &cabi->cpu_replenish_tmr;
+	struct timespec period;
+	int res;
+
+
+	res = posix_clocks[CLOCK_REALTIME_HR].res;
+
+
+#ifdef	DEBUG_CABI_REPLENISH_TIMER
+	printk
+	    ("cabi_replenish_timer_process: current jiffies(%lu) cabi_state(%x)\n",
+	     jiffies, cabi->cpu_state);
+#endif
+	/* replenish it, and set timer expiration `ticks' later */
+	cabi_account_replenish(cabi, &period);
+#ifdef CONFIG_HIGH_RES_TIMERS
+	tmr->sub_expires = tstojiffie(&period, res, &tmr->expires);
+#else
+	cabi_tstojiffie(&period, &tmr->expires);
+#endif
+	tmr->expires += jiffies;
+
+#ifdef	DEBUG_CABI_REPLENISH_TIMER
+#ifdef	CONFIG_HIGH_RES_TIMERS
+	printk
+	    ("cabi_replenish_hres_timer_process: set next timer for cabi(0x%x) (%lu sec,%lu nsec) (%lu,%lu,%lu)\n",
+	     (int) cabi, period.tv_sec, period.tv_nsec, tmr->expires,
+	     tmr->sub_expires, jiffies);
+#else
+	printk
+	    ("cabi_replenish_timer_process: set next timer for cabi(0x%x) (%lu sec,%lu nsec) (%lu)\n",
+	     (int) cabi, period.tv_sec, period.tv_nsec, tmr->expires);
+#endif
+#endif
+	/* if there are bit in signal_block, off it */
+	if (cabi->cabi_param.term_act == CABI_TERM_SIGNAL &&
+						cabi->signal_block)
+		cabi->signal_block = SIGNAL_OFF;
+
+	/* Enqueue the timer */
+	add_timer(tmr);
+}
+
+/*
+ * cabi_replenish_timer_create():
+ * 	Create a timer to replenish a account, add it to the queue.
+ * 	Set a linux timer if necessary.
+ */
+void
+cabi_replenish_timer_init(cabi_account_t cabi, cpu_tick_t ticks)
+{
+
+	struct timer_list *tmr = &cabi->cpu_replenish_tmr;
+
+	/* initialize a (linux) timer for replenishment */
+	init_timer(tmr);
+
+	/* Always start from the next jiffy */
+	tmr->expires = jiffies + 1;
+	tmr->function = (void (*)(unsigned long)) cabi_replenish_timer_process;
+	tmr->data = (unsigned long) cabi;
+
+#ifdef	DEBUG_CABI_REPLENISH_TIMER
+#ifdef	CONFIG_HIGH_RES_TIMERS
+	printk
+	    ("cabi_replenish_timer_init(replenish_hres) set next timer for cabi(0x%x) (%lu,%lu)\n",
+	     (int) cabi, tmr->expires, tmr->sub_expires);
+#else
+	printk("cabi_replenish_timer_process: set next timer for cabi(0x%x) "
+	       "(%lu)\n", (int) cabi, tmr->expires);
+#endif
+#endif
+	/* Enqueue the timer */
+	add_timer(tmr);
+}
+
+void
+cabi_replenish_timer_cancel(cabi_account_t cabi)
+{
+	struct timer_list *tmr = &cabi->cpu_replenish_tmr;
+
+	del_timer(tmr);
+}
+
+/*
+ * Enforcement timer management
+ *
+ * cabi_start_account(cabi)
+ *	 -> cabi_timer_set_enforce_timer(cabi, ticks_expired);
+ *
+ * cabi_stop_account(cabi)
+ *	 -> cabi_timer_cancel_enforce_timer(cabi);
+ *
+ * "cabi_current_resource_set != 0" --> accounting is on
+ * "cabi_current_resource_set == 0" --> accounting is off
+ *
+ */
+extern void cabi_enforce_timer_process(cabi_account_t cabi);
+static struct timer_list cabi_enforce_timer = {
+      function:(void (*)(unsigned long)) cabi_enforce_timer_process
+};
+
+/* called from "cabi->cpu_ops->start_account()" */
+void
+cabi_enforce_timer_start(cabi_account_t cabi, cpu_tick_t next_available_ticks)
+{
+	struct timer_list *tmr = &cabi_enforce_timer;
+	struct now_struct now;
+	struct timespec ts;
+#if defined(CONFIG_HIGH_RES_TIMERS)
+	int res = posix_clocks[CLOCK_REALTIME_HR].res;
+#endif
+
+	posix_get_now(&now);
+	tick2ts(next_available_ticks, &ts);
+#if defined(CONFIG_HIGH_RES_TIMERS)
+	tmr->sub_expires = tstojiffie(&ts, res, &tmr->expires);
+#else
+	cabi_tstojiffie(&ts, &tmr->expires);
+#endif
+#ifdef	DEBUG_CABI_ENFORCE_TIMER_START
+
+	printk
+	    ("[cabi_enforce_hres_timer_start]: cabi(0x%x) (%lu usec) (%lu sec, %lu nsec) "
+	     "(%lu,%lu) curent(%lu, %lu)\n", (int) cabi,
+	     TICK2USEC(next_available_ticks), ts.tv_sec, ts.tv_nsec,
+	     tmr->expires, tmr->sub_expires, now.jiffies,
+	     (u_long) now.sub_jiffie);
+
+#endif
+	tmr->expires += jiffies;
+	tmr->data = (unsigned long) cabi;
+
+	/* Enqueue the timer */
+	add_timer(tmr);
+	return;
+}
+
+/*
+ * Cancel enforce_timer and set timer to next jiffy
+ */
+void
+cabi_enforce_timer_cancel(void)
+{
+	del_timer(&cabi_enforce_timer);
+}
+
+/*
+ * Process enforce timer expiration.
+ */
+void
+cabi_enforce_timer_process(cabi_account_t cabi)
+{
+
+#ifdef	DEBUG_CABI_ENFORCE_TIMER
+	struct now_struct now;
+	posix_get_now(&now);
+	printk("cabi_enforce_hres_timer_process: current jiffies(%lu, %lu)\n",
+	       now.jiffies, (u_long) now.sub_jiffie);
+#endif
+
+	/* make sure if cabi corresponds to the current cabi */
+	if (cabi_current_account == cabi) {
+		cabi_account_enforce(cabi_current_account);
+	}
+}
+
+void
+cabi_timer_start(void)
+{
+	init_timer(&cabi_enforce_timer);
+}
+
+int
+cabi_account_read_time_proc(cabi_account_t cabi, char *buf)
+{
+        char *p = buf;
+
+        p += sprintf(p, "timespec \n");
+
+        return (p - buf);
+}
+
diff -Nupr linux-2.6.13.2.orig/drivers/cabi/examples/Makefile linux-2.6.13.2/drivers/cabi/examples/Makefile
--- linux-2.6.13.2.orig/drivers/cabi/examples/Makefile	1970-01-01 09:00:00.000000000 +0900
+++ linux-2.6.13.2/drivers/cabi/examples/Makefile	2005-09-28 03:15:21.755492522 +0900
@@ -0,0 +1,44 @@
+CABIDIR  = ../..
+CC       = $(CROSS_COMPILE)gcc -g
+CFLAGS   = -O2 -Wall
+LIBS	 = -L../lib -lcabi 
+INCLUDES = -I../../../include -I/usr/include 
+
+OBJS = cabi_create cabi_destroy cabi_bind cabi_unbind cabi_set cabi_get \
+	cabi_overload_create cabi_overload_destroy \
+	cabi_create_bind cabi_exec_bind\
+
+all: cabi_create cabi_destroy cabi_bind cabi_unbind cabi_set cabi_get cabi_overload_create cabi_overload_destroy cabi_create_bind cabi_exec_bind
+
+cabi_create: cb_create.c
+	$(CC) -o cabi_create cb_create.c $(CFLAGS) $(INCLUDES) $(LIBS)
+
+cabi_destroy: cb_destroy.c
+	$(CC) -o cabi_destroy cb_destroy.c $(CFLAGS) $(INCLUDES) $(LIBS)
+
+cabi_bind: cb_bind.c
+	$(CC) -o cabi_bind cb_bind.c $(CFLAGS) $(INCLUDES) $(LIBS)
+
+cabi_unbind: cb_unbind.c
+	$(CC) -o cabi_unbind cb_unbind.c $(CFLAGS) $(INCLUDES) $(LIBS)
+
+cabi_set: cb_set.c
+	$(CC) -o cabi_set cb_set.c $(CFLAGS) $(INCLUDES) $(LIBS)
+
+cabi_get: cb_get.c
+	$(CC) -o cabi_get cb_get.c $(CFLAGS) $(INCLUDES) $(LIBS)
+
+cabi_overload_create: cb_overload_create.c
+	$(CC) -o cabi_overload_create cb_overload_create.c $(CFLAGS) $(INCLUDES) $(LIBS)
+
+cabi_overload_destroy: cb_overload_destroy.c
+	$(CC) -o cabi_overload_destroy cb_overload_destroy.c $(CFLAGS) $(INCLUDES) $(LIBS)
+
+cabi_create_bind: cb_create_bind.c
+	$(CC) -o cabi_create_bind cb_create_bind.c $(CFLAGS) $(INCLUDES) $(LIBS)
+
+cabi_exec_bind: cb_exec_bind.c
+	$(CC) -o cabi_exec_bind cb_exec_bind.c $(CFLAGS) $(INCLUDES) $(LIBS)
+
+clean:
+	rm -rf $(OBJS) *~
diff -Nupr linux-2.6.13.2.orig/drivers/cabi/examples/cb_bind.c linux-2.6.13.2/drivers/cabi/examples/cb_bind.c
--- linux-2.6.13.2.orig/drivers/cabi/examples/cb_bind.c	1970-01-01 09:00:00.000000000 +0900
+++ linux-2.6.13.2/drivers/cabi/examples/cb_bind.c	2005-09-28 03:15:21.756492291 +0900
@@ -0,0 +1,56 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <sched.h>
+#include <cabi/cabi.h>
+#include <cabi/cabi_error.h>
+
+void usage(void) {
+	printf ("Usage: cabi_bind [object_id] [pid]\n");
+	printf ("--------------------------------------------------\n");
+	printf ("  [object_id]      : cabi object id\n");
+	printf ("  [pid]            : bind process id\n");
+}
+
+int main (int argc, char *argv[])
+{
+	int ret;
+       	pid_t pid;
+	
+	unsigned long cabi_id; 	
+
+	if (argc != 3) {
+		usage();
+		return 0;
+	}
+	
+	/* set accounting object id */
+	cabi_id = atol (argv[1]);
+	pid = (pid_t) atoi (argv[2]);
+
+	switch (cabi_id) {
+	    case 0:
+		printf ("object id is 0.\n");
+		return 1;
+	    case 1:
+		printf ("[object_id]=1 is only for overload.");
+		return 1;
+	    default:
+		printf ("cabi bind pid\n");
+		break;
+	}
+
+	// Attach this process to the resource set 
+	if ((ret = cabi_account_bind_pid(cabi_id, pid)) != CABI_SUCCESS) {
+		printf ("cabi_account_bind_pid() faild.(%d)\n", ret);
+	} else {
+		printf ("cabi_account_bind_pid: object_id(%d) pid[%d]\n",
+			(int)cabi_id, pid);
+	}
+
+	return 0;
+}
diff -Nupr linux-2.6.13.2.orig/drivers/cabi/examples/cb_create.c linux-2.6.13.2/drivers/cabi/examples/cb_create.c
--- linux-2.6.13.2.orig/drivers/cabi/examples/cb_create.c	1970-01-01 09:00:00.000000000 +0900
+++ linux-2.6.13.2/drivers/cabi/examples/cb_create.c	2005-09-28 03:15:21.756492291 +0900
@@ -0,0 +1,118 @@
+/*
+ * This is sample program for CABI system.
+ * create accounting object.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <cabi/cabi.h>
+#include <cabi/cabi_error.h>
+
+#define ONE_SEC 1000000
+
+void usage(void) {
+	printf ("cabi_create:\n");
+	printf ("  cabi terminate action [block]:\n");
+	printf ("  Usage: cabi_create [cpu_time(us)] [cpu_period(us)]\n");
+	printf ("  cabi terminate action [signal]:\n");
+	printf ("  Usage: cabi_create [cpu_time(us)] [cpu_period(us)] [pid] [sig] [flag]\n");
+	printf ("--------------------------------------------------\n");
+	printf ("    [cpu_time(us)]   : cpu performance time (usec)\n");
+	printf ("    [cpu_period(us)] : cpu cycle time (usec)\n");
+	printf ("    [pid]            : signal receive pid\n");
+	printf ("    [sig]            : send signal number\n");
+	printf ("    [flag]           : default(current) or else\n");
+}
+
+int main (int argc, char *argv[])
+{
+	int ret;
+	struct cabi_uaccount *ucabi;
+	long long cpu_time, cpu_period;
+	int term_act, sig, flag;
+	pid_t pid;
+	
+	/* set accounting object id */
+	switch (argc) {
+	    case 3:
+		term_act	= CABI_TERM_BLOCK;
+		cpu_time	= atoll (argv[1]);
+		cpu_period	= atoll (argv[2]);
+		pid		= 0;
+		sig		= 0;
+		flag		= 0;
+		break;
+	    case 6:
+		term_act	= CABI_TERM_SIGNAL;
+		cpu_time	= atoll (argv[1]);
+		cpu_period	= atoll (argv[2]);
+		pid		= atoi (argv[3]);
+		sig		= atoi (argv[4]);
+		flag		= atoi (argv[5]);
+		break;
+	    default:
+		usage();
+		return 1;
+	}
+	printf ("Create CABI object...\n");
+	if (cpu_time <= 0) {
+		printf ("Invalid parameter. cpu_time = %lld nsec\n", cpu_time);
+		return 1;
+	}
+	if (cpu_period <= 0) {
+		printf ("Invalid parameter. cpu_period = %lld nsec\n", cpu_period);
+		return 1;
+	}
+	if (cpu_time > cpu_period) {
+		printf ("Invalid parameter. cpu_time > cpu_period\n");
+		return 1;
+	}
+
+ 	/* create a user cabi  */
+	if(!(ucabi = (cabi_account_t) malloc (sizeof(struct cabi_uaccount)))) {
+		printf ("cabi_create: Memory allocation error.\n");
+		return 1;
+	}
+
+	ucabi->cabi_param.term_act = term_act;
+	ucabi->cabi_param.bind_proc_type = BIND_NORMAL_PROC;
+
+	ucabi->cpu_time.tv_sec = 0;
+	ucabi->cpu_time.tv_nsec = 0;
+	
+	ucabi->cpu_period.tv_sec = 0;
+	ucabi->cpu_period.tv_nsec = 0;
+
+	ucabi->cpu_time.tv_sec = (cpu_time / ONE_SEC);
+	ucabi->cpu_time.tv_nsec = (cpu_time % ONE_SEC) * 1000;
+
+	ucabi->cpu_period.tv_sec = (cpu_period / ONE_SEC);
+	ucabi->cpu_period.tv_nsec = (cpu_period % ONE_SEC) * 1000;
+
+	ucabi->cabi_param.cabi_signal.pid  = pid;
+	ucabi->cabi_param.cabi_signal.sig  = sig;
+	ucabi->cabi_param.cabi_signal.flag = flag;
+
+	if ((ret = cabi_account_create (ucabi)) == CABI_SUCCESS) {
+		printf ("account set create.(%d) object_id [%d]\n",
+		       (int)ucabi->cabi_param.term_act,
+		       (int)ucabi->cabi_id);
+	} else { 
+		printf ("cabi_account_create failed.(%d)\n", ret);
+	}	
+
+	if (ucabi->cabi_id == 0) {
+		printf ("cabi_account_create faild on cpu %x\n", (int)ucabi);
+		free(ucabi);
+		return 1;
+	}
+
+	free(ucabi);
+
+	return 0;	
+}
diff -Nupr linux-2.6.13.2.orig/drivers/cabi/examples/cb_create_bind.c linux-2.6.13.2/drivers/cabi/examples/cb_create_bind.c
--- linux-2.6.13.2.orig/drivers/cabi/examples/cb_create_bind.c	1970-01-01 09:00:00.000000000 +0900
+++ linux-2.6.13.2/drivers/cabi/examples/cb_create_bind.c	2005-09-28 03:15:21.756492291 +0900
@@ -0,0 +1,50 @@
+/*
+ * This is sample program for CABI system.
+ * create accounting object.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <cabi/cabi.h> 
+
+
+int main (int argc, char *argv[])
+{
+	int ret;
+	pid_t pid;
+	
+	struct cabi_uaccount *ucabi;
+	
+	pid = getpid();
+ 	ucabi = (cabi_account_t) malloc (sizeof(struct cabi_uaccount));
+
+	memset (ucabi, 0x00, sizeof(struct cabi_uaccount));
+	/* set scheduling and enforce mode */
+	ucabi->cabi_param.term_act = CABI_TERM_BLOCK;
+	ucabi->cpu_time.tv_sec = 0;
+	ucabi->cpu_time.tv_nsec = 1000 * 1000 * 20;
+	
+	ucabi->cpu_period.tv_sec = 0;
+	ucabi->cpu_period.tv_nsec = 1000 * 1000 * 100;
+
+	if (!(ret = cabi_create_bind (ucabi, pid))) {
+		printf("account set create. object_id [%d]\n",
+			(int)ucabi->cabi_id);
+	} else { 
+		printf("cabi_account_create failed.\n");
+	}	
+	
+	if (ucabi->cabi_id == 0) {
+		printf("cabi_account_create faild on cpu %x\n", (int)ucabi);
+		return 1;
+	}
+
+	free(ucabi);
+	
+	return 0;
+}
diff -Nupr linux-2.6.13.2.orig/drivers/cabi/examples/cb_destroy.c linux-2.6.13.2/drivers/cabi/examples/cb_destroy.c
--- linux-2.6.13.2.orig/drivers/cabi/examples/cb_destroy.c	1970-01-01 09:00:00.000000000 +0900
+++ linux-2.6.13.2/drivers/cabi/examples/cb_destroy.c	2005-09-28 03:15:21.757492060 +0900
@@ -0,0 +1,41 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <cabi/cabi.h>
+#include <cabi/cabi_error.h>
+
+void usage(void) {
+	printf ("Usage: cabi_destroy [object_id]\n");
+	printf ("--------------------------------------------------\n");
+	printf ("  [object_id]      : cabi object id\n");
+}
+
+int main (int argc, char *argv[])
+{
+	int ret;
+	unsigned long cabi_id; 	
+
+	if (argc != 2) {
+		usage();
+		return 0;
+	}
+	
+	/* set the object id */
+	cabi_id = atol (argv[1]);	
+
+	if ((ret = cabi_account_destroy(cabi_id)) != CABI_SUCCESS) {
+		printf ("destroy faild.(%d)\n", ret);
+	} else {
+		printf ("destroy succeed.\n");
+	}
+
+        return 1;
+								
+			
+}
+
+
diff -Nupr linux-2.6.13.2.orig/drivers/cabi/examples/cb_exec_bind.c linux-2.6.13.2/drivers/cabi/examples/cb_exec_bind.c
--- linux-2.6.13.2.orig/drivers/cabi/examples/cb_exec_bind.c	1970-01-01 09:00:00.000000000 +0900
+++ linux-2.6.13.2/drivers/cabi/examples/cb_exec_bind.c	2005-09-28 03:15:21.757492060 +0900
@@ -0,0 +1,58 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <signal.h>
+#include <unistd.h>
+#include <sched.h>
+#include <errno.h>
+#include <cabi/cabi.h> 
+#include <cabi/cabi_error.h> 
+
+extern int errno;
+
+void usage(void) {
+	printf ("Usage: cabi_exec_bind [object_id] [program...]\n");
+	printf ("--------------------------------------------------\n");
+	printf ("  [object_id]      : cabi object id\n");
+	printf ("  [program...]     : execute program\n");
+}
+
+int main (int argc, char *argv[])
+{
+	unsigned long cabi_id; 	
+	pid_t	pid;
+	int	status;
+	int	ret;
+
+	if (argc < 3) {
+		usage();
+		return 0;
+	}
+
+	cabi_id = atoi (argv[1]);
+
+	if ((pid = fork()) == -1) {
+		perror("fork()");
+		return 1;
+	} else if (pid > 0) {
+		if ((ret = cabi_account_bind_pid(cabi_id, pid)) != CABI_SUCCESS) {
+			printf("exec_bind : cabi_account_bind_pid: faild. (%d)\n", ret);
+			return 1;
+		} else {
+			printf("exec_bind : cabi_account_bind_pid: Account ID(%d)[%d]\n",
+					(int)cabi_id, pid);
+		}
+		waitpid(-1, &status, WNOHANG);
+	} else {
+		if (execvp(argv[2], &argv[2]) == -1) {
+			perror("execv");
+			return 1;
+		}
+	}
+
+	return 0;
+}
diff -Nupr linux-2.6.13.2.orig/drivers/cabi/examples/cb_get.c linux-2.6.13.2/drivers/cabi/examples/cb_get.c
--- linux-2.6.13.2.orig/drivers/cabi/examples/cb_get.c	1970-01-01 09:00:00.000000000 +0900
+++ linux-2.6.13.2/drivers/cabi/examples/cb_get.c	2005-09-28 03:15:21.757492060 +0900
@@ -0,0 +1,79 @@
+/*
+ * This is sample program for CABI system.
+ * create accounting object.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <cabi/cabi.h>
+#include <cabi/cabi_error.h>
+
+void usage(void) {
+	printf ("Usage: cabi_get [object_id]\n");
+	printf ("--------------------------------------------------\n");
+	printf ("  [object_id]      : cabi object id\n");
+}
+
+int main (int argc, char *argv[])
+{
+	struct cabi_uaccount *ucabi;
+	unsigned long cabi_id; 	
+	unsigned long long cpu_time, cpu_period;
+	float cpu_ratio;
+	int ret;
+
+	if (argc != 2) {
+		usage();
+		return 0;
+	}
+
+	/* set accounting object id */
+	cabi_id = atoi (argv[1]);
+	
+	if (cabi_id == 0) {
+		printf("object id is 0\n");
+		return 1;
+	}
+
+	/* create a user cabi */
+ 	ucabi = (struct cabi_uaccount *) malloc (sizeof(struct cabi_uaccount));
+
+	if ((ret = cabi_account_get (cabi_id, ucabi)) == CABI_SUCCESS) {
+		printf("object_id (%d)\n",
+			(int)ucabi->cabi_id);
+	} else {
+		if (ret == CABI_ENOEXIST) {
+			printf("object id(%ld) not found.\n", cabi_id);
+		} else {
+			printf("cabi_account_get failed.(%d)\n", ret);
+		}
+		return 1;
+	}	
+	if (!ucabi) {
+		printf("cabi_account_get faild on cpu %p\n", ucabi);
+		return 1;
+	}
+	
+	cpu_time = ucabi->cpu_time.tv_sec * 1000 + ucabi->cpu_time.tv_nsec / 1000000; 
+	cpu_period = ucabi->cpu_period.tv_sec * 1000 + ucabi->cpu_period.tv_nsec / 1000000;
+	cpu_ratio = (float)cpu_time / (float)cpu_period * 100.0;
+
+	printf ("TERM_ACT (%x)\n", ucabi->cabi_param.term_act);
+	printf ("CPU_TIME (%lu sec %02lu nsec) /CPU_PERIOD (%lu sec %02lu nsec)\n",
+	ucabi->cpu_time.tv_sec,
+	ucabi->cpu_time.tv_nsec,
+	ucabi->cpu_period.tv_sec,
+	ucabi->cpu_period.tv_nsec);
+	printf ("CPU_RATIO (%5.2f %%)\n", cpu_ratio);
+
+	free(ucabi);
+
+	return 0;	
+}
+
+
diff -Nupr linux-2.6.13.2.orig/drivers/cabi/examples/cb_overload_create.c linux-2.6.13.2/drivers/cabi/examples/cb_overload_create.c
--- linux-2.6.13.2.orig/drivers/cabi/examples/cb_overload_create.c	1970-01-01 09:00:00.000000000 +0900
+++ linux-2.6.13.2/drivers/cabi/examples/cb_overload_create.c	2005-09-28 03:15:21.757492060 +0900
@@ -0,0 +1,134 @@
+/*
+ * This is sample program for CABI system.
+ * create accounting object.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <signal.h>
+#include <unistd.h>
+#include <cabi/cabi.h>
+#include <cabi/cabi_error.h>
+
+#define ONE_SEC 1000000
+
+int count = 0;
+
+void usage(void) {
+	printf ("Usage: cabi_overload_create [overload_time(us)] [ovlerload_period(us)]\n");
+	printf ("--------------------------------------------------\n");
+	printf ("  [overload_time(us)]   : overload cpu performance time (usec)\n");
+	printf ("  [overload_period(us)] : overload cycle time (usec)\n");
+	printf ("  [overload_time] / [overload_period] * 100 : overload limit persents.\n");
+}
+
+void sig(int sig)
+{
+	printf ("signal %d received. count(%d)\n", sig, count); 
+	count++;
+}
+
+
+void loop(void)
+{
+	int i;
+	signal(SIGCONT, sig);
+	for (;; i++) {
+		/* printf("%02d: prog running...\n", i); */
+		sleep (2);
+	}
+}
+
+int main (int argc, char *argv[])
+{
+	int ret;
+	pid_t admin;
+	long long cpu_time, cpu_period;
+	
+	struct cabi_uaccount *ucabi;
+	cabi_account_t cabi = NULL_ACCOUNT;
+	int status;
+	
+	if (argc != 3) {
+		usage();
+		return 0;
+	}
+	cpu_time   = atoll (argv[1]);
+	cpu_period = atoll (argv[2]);
+
+	if (cpu_time <= 0) {
+		printf ("Invalid parameter. cpu_time = %lld nsec\n", cpu_time);
+		return 1;
+	}
+	if (cpu_period <= 0) {
+		printf ("Invalid parameter. cpu_period = %lld nsec\n", cpu_period);
+		return 1;
+	}
+	if (cpu_time > cpu_period) {
+		printf ("Invalid parameter. cpu_time > cpu_period\n");
+		return 1;
+	}
+
+	/* create a resource set */
+ 	ucabi = malloc (sizeof(struct cabi_uaccount));
+
+	/* make admin process */
+	if ((admin = fork()) == -1) {
+		perror("fork()");
+		return 1;
+	}
+	else if (admin > IDLE_PROCESS) {
+		/* this is parent */
+		printf ("AO PID = %d\n", getpid());
+		printf ("Admin PID = %d\n", admin);
+		waitpid(-1, &status, WNOHANG);
+	} else {
+		printf ("Admin start..pid %d\n", getpid());
+		loop();
+	}
+	
+	printf ("Overload Create!\n");
+
+	/* set scheduling and enforce mode */
+	ucabi->cabi_param.term_act = CABI_TERM_SIGNAL;
+	ucabi->cabi_param.cabi_signal.pid = admin;
+	ucabi->cabi_param.cabi_signal.sig = SIGCONT;
+
+	printf ("cabi_param.bind_proc_type (%x)\n", 
+		ucabi->cabi_param.bind_proc_type);
+
+	ucabi->cpu_time.tv_sec = 0;
+	ucabi->cpu_time.tv_nsec = 0;
+	
+	ucabi->cpu_period.tv_sec = 0;
+	ucabi->cpu_period.tv_nsec = 0;
+
+	ucabi->cpu_time.tv_sec = (cpu_time / ONE_SEC);
+	ucabi->cpu_time.tv_nsec = (cpu_time % ONE_SEC) * 1000;
+
+	ucabi->cpu_period.tv_sec = (cpu_period / ONE_SEC);
+	ucabi->cpu_period.tv_nsec = (cpu_period % ONE_SEC) * 1000;
+
+	if ((ret = cabi_overload_create (ucabi)) == CABI_SUCCESS) {
+		printf ("account set create[SIGNAL]. object_id (%d)"
+			"cabi object address (0x%x) , user cabi address(0x%x)\n", 
+			(int)ucabi->cabi_id, (int)cabi, (int)ucabi);
+	} else {
+		kill(admin, SIGKILL);
+		printf ("Kill admin process (pid = %d)\n", admin);
+		printf ("cabi_account_create failed.(%d)\n", ret);
+		return 1;
+	}	
+	
+	if (ucabi->cabi_id != OVERLOAD_CABI_ID) {
+		printf ("cabi_account_create faild on cpu %p\n", cabi);
+		return 1;
+	}
+
+	return 0;	
+}
diff -Nupr linux-2.6.13.2.orig/drivers/cabi/examples/cb_overload_destroy.c linux-2.6.13.2/drivers/cabi/examples/cb_overload_destroy.c
--- linux-2.6.13.2.orig/drivers/cabi/examples/cb_overload_destroy.c	1970-01-01 09:00:00.000000000 +0900
+++ linux-2.6.13.2/drivers/cabi/examples/cb_overload_destroy.c	2005-09-28 03:15:21.758491829 +0900
@@ -0,0 +1,18 @@
+#include <stdio.h>
+#include <sys/types.h>
+#include <cabi/cabi.h> 
+#include <cabi/cabi_error.h>
+
+extern int cabi_overload_destroy(void);
+
+int main (void)
+{
+	int ret;
+
+	if ((ret = cabi_overload_destroy()) == CABI_SUCCESS) {
+		printf("overload destroy success.\n");
+	} else {
+		printf("overload destroy faild. (%d)\n", ret);
+	}
+	return ret;
+}
diff -Nupr linux-2.6.13.2.orig/drivers/cabi/examples/cb_set.c linux-2.6.13.2/drivers/cabi/examples/cb_set.c
--- linux-2.6.13.2.orig/drivers/cabi/examples/cb_set.c	1970-01-01 09:00:00.000000000 +0900
+++ linux-2.6.13.2/drivers/cabi/examples/cb_set.c	2005-09-28 03:15:21.758491829 +0900
@@ -0,0 +1,146 @@
+/*
+ * This is sample program for CABI system.
+ * create accounting object.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <cabi/cabi.h>
+#include <cabi/cabi_error.h>
+
+#define ONE_SEC 1000000
+
+void usage(void) {
+	printf ("cabi_set:\n");
+	printf ("  only cpu ratio change:\n");
+	printf ("  Usage: cabi_set [object_id] [cpu_time(us)] [cpu_period(us)]\n");
+	printf ("  cabi terminate action [signel] -> [block]:\n");
+	printf ("  Usage: cabi_set [object_id] [cpu_time(us)] [cpu_period(us)] [term_act]\n");
+	printf ("  cabi terminate action [block] -> [signal]:\n");
+	printf ("  Usage: cabi_set [object_id] [cpu_time(us)] [cpu_period(us)] [term_act] [pid] [sig] [flag]\n");
+	printf ("--------------------------------------------------\n");
+	printf ("    [object_id]      : cabi object id\n");
+	printf ("    [cpu_time(us)]   : cpu performance time (usec)\n");
+	printf ("    [cpu_period(us)] : cpu cycle time (usec)\n");
+	printf ("    [term_act]       : terminate action (block=1, signal=2)\n");
+	printf ("    [pid]            : signal receive process id\n");
+	printf ("    [sig]            : send signal number\n");
+	printf ("    [flag]           : default(current) or else\n");
+}
+
+int main (int argc, char *argv[])
+{
+  	int ret;
+  	struct cabi_uaccount *ucabi;
+	unsigned long cabi_id;
+	long long cpu_time, cpu_period;
+	int term_act;
+	int sig, flag;
+	pid_t pid;
+
+	sig = flag = 0;
+	pid = 0;
+	/* set accounting object id */
+	switch (argc) {
+	    case 4:
+		term_act = CABI_TERM_BLOCK;
+		break;
+	    case 5:
+		term_act = atoi(argv[4]);
+ 		if(term_act != CABI_TERM_BLOCK) {
+			usage();
+			return 1;
+		}
+		break;
+	    case 8:
+		term_act = atoi(argv[4]);
+		break;
+	    default:
+		usage();
+		return 1;
+	}
+	cabi_id = atoi (argv[1]);
+	cpu_time = atoll (argv[2]);
+	cpu_period = atoll (argv[3]);
+
+	switch (term_act) {
+	    case CABI_TERM_BLOCK:
+		break;
+	    case CABI_TERM_SIGNAL:
+		pid  = atoi (argv[5]);
+		sig  = atoi (argv[6]);
+		flag = atoi (argv[7]);
+		break;
+	    default:
+		printf ("Invalid parameter. term_act = %d\n", term_act);
+		return 1;
+	}
+	printf ("Setting...\n");
+	if (cabi_id == 0) {
+		return 1;
+	}
+	if (cpu_time <= 0) {
+		printf ("Invalid parameter. cpu_time = %lld nsec\n", cpu_time);
+		return 1;
+	}
+	if (cpu_period <= 0) {
+		printf ("Invalid parameter. cpu_period = %lld nsec\n", cpu_period);
+		return 1;
+	}
+	if (cpu_time > cpu_period) {
+		printf ("Invalid parameter. cpu_time > cpu_period\n");
+		return 1;
+	}
+
+	/* create a user cabi  */
+ 	ucabi = (cabi_account_t) malloc (sizeof(struct cabi_uaccount));
+
+	if ((ret = cabi_account_get (cabi_id, ucabi)) != CABI_SUCCESS) {
+		printf ("cabi_account_set : cabi_id(%ld) no exist. (%d)\n", cabi_id, ret);
+		return 1;
+	}	
+
+	/* set time to the timespec */
+	ucabi->cpu_time.tv_sec = 0;
+	ucabi->cpu_time.tv_nsec = 0;
+	ucabi->cpu_period.tv_sec = 0;
+	ucabi->cpu_period.tv_nsec = 0;
+
+	ucabi->cpu_time.tv_sec = (cpu_time / ONE_SEC);
+	ucabi->cpu_time.tv_nsec = (cpu_time % ONE_SEC) * 1000;
+
+	ucabi->cpu_period.tv_sec = (cpu_period / ONE_SEC);
+	ucabi->cpu_period.tv_nsec = (cpu_period % ONE_SEC) * 1000;
+
+	if (argc != 4) {
+		ucabi->cabi_param.term_act = term_act;
+	}
+	if (term_act == CABI_TERM_SIGNAL) {
+		ucabi->cabi_param.cabi_signal.pid  = pid;
+		ucabi->cabi_param.cabi_signal.sig  = sig;
+		ucabi->cabi_param.cabi_signal.flag = flag;
+	}
+
+	if ((ret = cabi_account_set (cabi_id, ucabi)) == CABI_SUCCESS) {
+		printf ("account set. object_id (%d)", (int)cabi_id);
+	} else { 
+		printf ("cabi_id = %ld : cabi_account_set failed. (%d)\n", cabi_id, ret);
+		return 1;
+	}	
+	
+	printf ("TERM_ACT (%d)\n", ucabi->cabi_param.term_act);
+	printf ("CPU_TIME (%lu sec %02lu nsec) /CPU_PERIOD (%lu sec %02lu nsec)\n",
+		ucabi->cpu_time.tv_sec,
+		ucabi->cpu_time.tv_nsec,
+		ucabi->cpu_period.tv_sec,
+		ucabi->cpu_period.tv_nsec);
+
+	free(ucabi);
+
+        return 0;
+}
diff -Nupr linux-2.6.13.2.orig/drivers/cabi/examples/cb_unbind.c linux-2.6.13.2/drivers/cabi/examples/cb_unbind.c
--- linux-2.6.13.2.orig/drivers/cabi/examples/cb_unbind.c	1970-01-01 09:00:00.000000000 +0900
+++ linux-2.6.13.2/drivers/cabi/examples/cb_unbind.c	2005-09-28 03:15:21.758491829 +0900
@@ -0,0 +1,38 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <cabi/cabi.h>
+#include <cabi/cabi_error.h>
+
+void usage(void) {
+	printf ("Usage: cabi_unbind [pid]\n");
+	printf ("--------------------------------------------------\n");
+	printf ("  [pid]            : unbind process id\n");
+}
+
+int main (int argc, char *argv[])
+{
+	int ret;
+	pid_t pid;
+
+	if (argc != 2) {
+		usage();
+		return 0;
+	}
+
+	pid = (pid_t) atoi (argv[1]);
+	printf ("cabi unbind pid: %d\n", pid);
+
+	// Dettach this process from accounting obiect
+	if ((ret = cabi_account_unbind(pid)) != CABI_SUCCESS) {
+	          printf ("unbind faild.(%d)\n", ret);
+	} else {
+	          printf ("unbaind succeed.\n");
+	}
+
+        return 0;
+}
diff -Nupr linux-2.6.13.2.orig/drivers/cabi/lib/Makefile linux-2.6.13.2/drivers/cabi/lib/Makefile
--- linux-2.6.13.2.orig/drivers/cabi/lib/Makefile	1970-01-01 09:00:00.000000000 +0900
+++ linux-2.6.13.2/drivers/cabi/lib/Makefile	2005-09-28 03:15:21.758491829 +0900
@@ -0,0 +1,28 @@
+INSTALL       = /usr/bin/install -c -m 644
+DESTDIR       =
+KERNELDIR     = ../../..
+INCLUDEDIR    = /usr
+CC            = $(CROSS_COMPILE)gcc -g
+AR            = $(CROSS_COMPILE)ar
+RANLIB        = $(CROSS_COMPILE)ranlib
+SOURCES       = $(wildcard *.c)
+OBJS          = $(SOURCES:.c=.o)
+CFLAGS        = -DCONFIG_CABI -O2 -Wall -I$(KERNELDIR)/include -I$(INCLUDEDIR)/include 
+
+all: libcabi.so libcabi.a
+
+libcabi.a: $(OBJS)
+	$(AR) -r libcabi.a $(OBJS)
+	$(RANLIB) libcabi.a
+
+libcabi.so: $(OBJS)
+	$(CC) -fPIC $(OBJS) -shared -o libcabi.so
+
+clean:
+	rm -rf $(OBJS) libcabi.a
+
+install: libcabi.a
+	$(INSTALL) libcabi.a  $(DESTDIR)/lib/libcabi.a
+	$(INSTALL) libcabi.so $(DESTDIR)/lib/libcabi.so
+	$(INSTALL) $(KERNELDIR)/include/cabi/cabi.h $(DESTDIR)/usr/include/cabi/cabi.h
+	$(INSTALL) $(KERNELDIR)/include/cabi/cabi_error.h $(DESTDIR)/usr/include/cabi/cabi_error.h
diff -Nupr linux-2.6.13.2.orig/drivers/cabi/lib/README.cabi linux-2.6.13.2/drivers/cabi/lib/README.cabi
--- linux-2.6.13.2.orig/drivers/cabi/lib/README.cabi	1970-01-01 09:00:00.000000000 +0900
+++ linux-2.6.13.2/drivers/cabi/lib/README.cabi	2005-09-28 03:15:21.759491597 +0900
@@ -0,0 +1,11 @@
+README file for the cabi library.
+===================================
+This file describes the brief instruction abount the cabi library
+install. 
+
+Before make, please add the link for kernel for header
+directories as follows.
+
+#ln -sf /usr/src/linux/include/linux /usr/include/linux
+#ln -sf /usr/src/linux/asm-i386 /usr/include/asm
+
diff -Nupr linux-2.6.13.2.orig/drivers/cabi/lib/cabi_account_bind_pgid.c linux-2.6.13.2/drivers/cabi/lib/cabi_account_bind_pgid.c
--- linux-2.6.13.2.orig/drivers/cabi/lib/cabi_account_bind_pgid.c	1970-01-01 09:00:00.000000000 +0900
+++ linux-2.6.13.2/drivers/cabi/lib/cabi_account_bind_pgid.c	2005-09-28 03:15:21.759491597 +0900
@@ -0,0 +1,14 @@
+/* 
+ * Copyright (C) OS Research Group, Waseda University Nakajima Laboratory.
+ *               MontaVista Software, Inc. 
+ * All Rights Reserved.
+ * any improvements or extensions that they make and grant Waseda University
+ * the rights to redistribute these changes.
+ *
+ */
+#define __LIBRARY__
+#include <cabi/cabi.h>
+/*
+ * int sys_cabi_account_bind_pgid(unsigned long cabi_id, pid_t pgid)
+ */
+_syscall2(int, cabi_account_bind_pgid, unsigned long, cabi_id, pid_t, pgid)
diff -Nupr linux-2.6.13.2.orig/drivers/cabi/lib/cabi_account_bind_pid.c linux-2.6.13.2/drivers/cabi/lib/cabi_account_bind_pid.c
--- linux-2.6.13.2.orig/drivers/cabi/lib/cabi_account_bind_pid.c	1970-01-01 09:00:00.000000000 +0900
+++ linux-2.6.13.2/drivers/cabi/lib/cabi_account_bind_pid.c	2005-09-28 03:15:21.759491597 +0900
@@ -0,0 +1,17 @@
+/* 
+ * Copyright (C) OS Research Group, Waseda University Nakajima Laboratory.
+ *               MontaVista Software, Inc. 
+ * All Rights Reserved.
+ * any improvements or extensions that they make and grant Waseda University
+ * the rights to redistribute these changes.
+ *
+ */
+
+#define __LIBRARY__
+#include <cabi/cabi.h>
+
+/*
+ * int sys_cabi_account_bind_pid(unsigned long cabi_id, pid_t pid)
+ *  
+ */
+_syscall2(int, cabi_account_bind_pid, unsigned long, cabi_id, pid_t, pid)
diff -Nupr linux-2.6.13.2.orig/drivers/cabi/lib/cabi_account_create.c linux-2.6.13.2/drivers/cabi/lib/cabi_account_create.c
--- linux-2.6.13.2.orig/drivers/cabi/lib/cabi_account_create.c	1970-01-01 09:00:00.000000000 +0900
+++ linux-2.6.13.2/drivers/cabi/lib/cabi_account_create.c	2005-09-28 03:15:21.759491597 +0900
@@ -0,0 +1,18 @@
+/* 
+ * Copyright (C) OS Research Group, Waseda University Nakajima Laboratory.
+ *               MontaVista Software, Inc. 
+ * All Rights Reserved.
+ * any improvements or extensions that they make and grant Waseda University
+ * the rights to redistribute these changes.
+ *
+ */
+
+#define __LIBRARY__
+#include <cabi/cabi.h>
+
+/*
+ * int sys_cabi_account_create(cabi_object_t objectid, cabi_account_t cpu)
+ */
+_syscall1(int, cabi_account_create, struct cabi_uaccount *, ucabi)
+
+
diff -Nupr linux-2.6.13.2.orig/drivers/cabi/lib/cabi_account_destroy.c linux-2.6.13.2/drivers/cabi/lib/cabi_account_destroy.c
--- linux-2.6.13.2.orig/drivers/cabi/lib/cabi_account_destroy.c	1970-01-01 09:00:00.000000000 +0900
+++ linux-2.6.13.2/drivers/cabi/lib/cabi_account_destroy.c	2005-09-28 03:15:21.760491366 +0900
@@ -0,0 +1,16 @@
+/* 
+ * Copyright (C) OS Research Group, Waseda University Nakajima Laboratory.
+ *               MontaVista Software, Inc. 
+ * All Rights Reserved.
+ * any improvements or extensions that they make and grant Waseda University
+ * the rights to redistribute these changes.
+ *
+ */
+
+#define __LIBRARY__
+#include <cabi/cabi.h>
+
+/*
+ * int sys_cabi_account_destroy (unsigned long cabi_id)
+ */
+_syscall1(int, cabi_account_destroy, unsigned long, cabi_id)
diff -Nupr linux-2.6.13.2.orig/drivers/cabi/lib/cabi_account_get.c linux-2.6.13.2/drivers/cabi/lib/cabi_account_get.c
--- linux-2.6.13.2.orig/drivers/cabi/lib/cabi_account_get.c	1970-01-01 09:00:00.000000000 +0900
+++ linux-2.6.13.2/drivers/cabi/lib/cabi_account_get.c	2005-09-28 03:15:21.760491366 +0900
@@ -0,0 +1,16 @@
+/* 
+ * Copyright (C) OS Research Group, Waseda University Nakajima Laboratory.
+ *               MontaVista Software, Inc. 
+ * All Rights Reserved.
+ * any improvements or extensions that they make and grant Waseda University
+ * the rights to redistribute these changes.
+ *
+ */
+
+#define __LIBRARY__
+#include <cabi/cabi.h>
+
+/*
+ * cabi_uaccount_t sys_cabi_account_get (unsigned long cabi_id, cabi_uaccount_t, ucabi) 
+ */
+_syscall2(int, cabi_account_get, unsigned long, cabi_id, cabi_uaccount_t, ucabi)
diff -Nupr linux-2.6.13.2.orig/drivers/cabi/lib/cabi_account_set.c linux-2.6.13.2/drivers/cabi/lib/cabi_account_set.c
--- linux-2.6.13.2.orig/drivers/cabi/lib/cabi_account_set.c	1970-01-01 09:00:00.000000000 +0900
+++ linux-2.6.13.2/drivers/cabi/lib/cabi_account_set.c	2005-09-28 03:15:21.761491135 +0900
@@ -0,0 +1,16 @@
+/* 
+ * Copyright (C) OS Research Group, Waseda University Nakajima Laboratory.
+ *               MontaVista Software, Inc. 
+ * All Rights Reserved.
+ * any improvements or extensions that they make and grant Waseda University
+ * the rights to redistribute these changes.
+ *
+ */
+
+#define __LIBRARY__
+#include <cabi/cabi.h>
+
+/*
+ * int sys_cabi_account_set (unsigned long cabi_id, struct cabi_uaccount_t *cpu) 
+ */
+_syscall2(int, cabi_account_set, unsigned long, cabi_id, struct cabi_uaccount *, ucabi)
diff -Nupr linux-2.6.13.2.orig/drivers/cabi/lib/cabi_account_unbind.c linux-2.6.13.2/drivers/cabi/lib/cabi_account_unbind.c
--- linux-2.6.13.2.orig/drivers/cabi/lib/cabi_account_unbind.c	1970-01-01 09:00:00.000000000 +0900
+++ linux-2.6.13.2/drivers/cabi/lib/cabi_account_unbind.c	2005-09-28 03:15:21.761491135 +0900
@@ -0,0 +1,17 @@
+/* 
+ * Copyright (C) OS Research Group, Waseda University Nakajima Laboratory.
+ *               MontaVista Software, Inc. 
+ * All Rights Reserved.
+ * any improvements or extensions that they make and grant Waseda University
+ * the rights to redistribute these changes.
+ *
+ */
+
+#define __LIBRARY__
+#include <cabi/cabi_error.h>
+#include <cabi/cabi.h>
+
+/*
+ * int sys_cabi_account_unbind (pid_t pid)
+ */
+_syscall1(int, cabi_account_unbind, pid_t, pid)
diff -Nupr linux-2.6.13.2.orig/drivers/cabi/lib/cabi_create_bind.c linux-2.6.13.2/drivers/cabi/lib/cabi_create_bind.c
--- linux-2.6.13.2.orig/drivers/cabi/lib/cabi_create_bind.c	1970-01-01 09:00:00.000000000 +0900
+++ linux-2.6.13.2/drivers/cabi/lib/cabi_create_bind.c	2005-09-28 03:15:21.761491135 +0900
@@ -0,0 +1,76 @@
+/* 
+ * Copyright (C) OS Research Group, Waseda University Nakajima Laboratory.
+ *               MontaVista Software, Inc. 
+ * All Rights Reserved.
+ * any improvements or extensions that they make and grant Waseda University
+ * the rights to redistribute these changes.
+ *
+ */
+
+#define __LIBRARY__
+#include <stdio.h>
+#include <cabi/cabi_error.h>
+#include <cabi/cabi.h>
+/*
+ * int cabi_overload_create(cabi_uaccount_t ucabi)
+ */
+
+extern int cabi_account_create (cabi_uaccount_t ucabi);
+extern int cabi_account_bind_pid(unsigned long cabi_id, pid_t pid);
+extern int cabi_account_destroy(unsigned long cabi_id);
+
+
+int 
+cabi_create_bind (cabi_uaccount_t ucabi, pid_t pid)
+{
+	int retval = -EPERM;
+
+
+	/* If ucabi has not valid address. */
+	if (!ucabi) {
+		return CABI_EINVAL;
+	}
+
+	/* call cabi_account_create() */
+        if (!(retval = cabi_account_create (ucabi))) {
+#ifdef DEBUG_CABILIB
+                fprintf(stderr, "create_bind: account set create. object_id (%d)"
+                        "user cabi address (0x%x)\n",
+                        (int) ucabi->cabi_id, (int)ucabi);
+#endif
+        } else {
+#ifdef DEBUG_CABILIB
+                fprintf(stderr, "create_bind failed. (%d)\n", retval);
+#endif
+                goto error;
+        }
+	
+
+        if (pid < 0) {
+#ifdef DEBUG_CABILIB
+                fprintf(stderr, "create_bind: invalid pid(%d)\n",
+                                                        (int)pid);
+#endif
+                retval = CABI_EINVAL;     /* Invalid argument */
+		goto error;
+        }
+	
+	/* call cabi_account_bind_pid */
+        if (!(retval = cabi_account_bind_pid(ucabi->cabi_id, pid))) {
+#ifdef DEBUG_CABILIB
+               fprintf(stderr, "cabi_account_bind_pid: Account ID(%d)[%d]\n",
+                                (int) ucabi->cabi_id, pid);
+#endif
+                return CABI_SUCCESS;
+        } else {
+#ifdef DEBUG_CABILIB
+                fprintf(stderr, "cabi_account_bind_pid() failed.\n");
+#endif
+		cabi_account_destroy(ucabi->cabi_id);
+        }
+
+error:
+        return retval;
+}
+	
+
diff -Nupr linux-2.6.13.2.orig/drivers/cabi/lib/cabi_overload_create.c linux-2.6.13.2/drivers/cabi/lib/cabi_overload_create.c
--- linux-2.6.13.2.orig/drivers/cabi/lib/cabi_overload_create.c	1970-01-01 09:00:00.000000000 +0900
+++ linux-2.6.13.2/drivers/cabi/lib/cabi_overload_create.c	2005-09-28 03:15:21.761491135 +0900
@@ -0,0 +1,71 @@
+/* 
+ * Copyright (C) OS Research Group, Waseda University Nakajima Laboratory.
+ *               MontaVista Software, Inc. 
+ * All Rights Reserved.
+ * any improvements or extensions that they make and grant Waseda University
+ * the rights to redistribute these changes.
+ *
+ */
+
+#define __LIBRARY__
+#include <stdio.h>
+#include <cabi/cabi_error.h>
+#include <cabi/cabi.h>
+
+/*
+ * int ca