Thread: [Linux-hls-cvs] hls/linux-2.6 Makefile,NONE,1.1 bottom.c,NONE,1.1 bottom.h,NONE,1.1 div.c,NONE,1.1 e
Status: Pre-Alpha
Brought to you by:
lucabe
Update of /cvsroot/linux-hls/hls/linux-2.6 In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv10942 Added Files: Makefile bottom.c bottom.h div.c export.c hls_ctl.c hls_timers.c init.c misc.c procfs.c procfs.h sched.c Log Message: Beginning of a 2.6 backend... Does not work yet! --- NEW FILE: init.c --- /* * Copyright (c) 2002 Luca Abeni * * Module Name: init.c * Abstract: Module initialization and cleanup. * Author: Luca Abeni 2-Feb-2002 * * This is free software; see GPL.txt */ #include <linux/config.h> #if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS) #define MODVERSIONS #endif #ifdef MODVERSIONS //#include <linux/modversions.h> #endif #include <linux/module.h> #include <linux/kernel.h> #include <linux/sched.h> #include <data.h> #include "hls_hooks.h" #include "bottom.h" #include "procfs.h" #ifndef CONFIG_GENERIC_SCHEDULER #error Generic Scheduler is not enabled!!! #endif extern void (*block_hook)(struct task_struct *tsk); extern void (*unblock_hook)(struct task_struct *tsk); extern void (*fork_hook)(struct task_struct *tsk); extern void (*cleanup_hook)(struct task_struct *tsk); extern int (*setsched_hook)(pid_t pid, int policy, struct sched_param *param); extern int (*getsched_hook)(pid_t pid, struct sched_param *param); #ifdef __LOG_DEVICE__ #include "logger.h" #define hls_printk log_printf #else #define hls_printk printk #endif MODULE_LICENSE("GPL"); /* FIXME: These prototypes should be removed... */ int hls_setsched(pid_t pid, int policy, struct sched_param *param); extern void HLSInit(void); extern void HLSDeinit (void); extern spinlock_t hls_lock; void hls_convert_tasks(void) { struct task_struct *dummy, *t; /* If all the tasks must be managed by the HLS, we must * ``transform'' all the existing tasks in HLS tasks... */ t = current; if (t->private_data == NULL) { t->policy = SCHED_FIFO; t->rt_priority = HLS_IDLE_PRIORITY; if ((t->state == TASK_INTERRUPTIBLE) || (t->state == TASK_UNINTERRUPTIBLE)) { HLSCreateThreadHook(t, t->state); } else if (t->state == TASK_RUNNING) { HLSCreateThreadHook(t, TASK_UNINTERRUPTIBLE); t->state = TASK_RUNNING; HLSUnblockThreadHook(t); } else { #ifdef VERBOSE hls_printk("state: %ld\n", t->state); #endif } } else { printk("Error: It already is an HLS task!!!\n"); hls_printk("Error: It already is an HLS task!!!\n"); } read_lock(&tasklist_lock); do_each_thread(dummy, t) { #ifdef __FP_DEAMONS__ if (t->tty == NULL) { #ifdef VERBOSE hls_printk("Giving T%d the highest priority\n", t->pid); #endif t->policy = SCHED_FIFO; t->rt_priority = HLS_SCHEDULING_PRIORITY + 1; t->private_data = NULL; } else { #endif #ifdef VERBOSE hls_printk("Transforming T%d in HLS task\t", t->pid); #endif if (t->private_data == NULL) { t->policy = SCHED_FIFO; t->rt_priority = HLS_IDLE_PRIORITY; if ((t->state == TASK_INTERRUPTIBLE) || (t->state == TASK_UNINTERRUPTIBLE)) { HLSCreateThreadHook(t, t->state); } else if (t->state == TASK_RUNNING) { HLSCreateThreadHook(t, TASK_UNINTERRUPTIBLE); t->state = TASK_RUNNING; HLSUnblockThreadHook(t); } else { #ifdef VERBOSE hls_printk("state: %ld\t", t->state); #endif } #ifdef VERBOSE hls_printk("ok!\n"); #endif } else { printk("already PRIVATE_DATA != NULL???\n"); hls_printk("already PRIVATE_DATA != NULL???\n"); } #ifdef __FP_DEAMONS__ } #endif } while_each_thread(dummy, t); read_unlock(&tasklist_lock); } void hls_release_tasks(void) { struct task_struct *dummy, *t; t = current; read_lock(&tasklist_lock); do_each_thread(dummy, t) { if (t->private_data != NULL) { #ifdef VERBOSE printk("Removing task %d from HLS\n", t->pid); #endif if (t->state == TASK_RUNNING) { hls_block_other_thread(t); } HLSExitThreadHook(t); t->private_data = 0; t->policy = SCHED_NORMAL; } } while_each_thread(dummy, t); read_unlock(&tasklist_lock); } int init_module(void) { int res; unsigned long flags; res= hls_proc_init(); if (res < 0) { return res; } if (block_hook != NULL) { printk("Error installing HLS: block_hook != NULL!!!\n"); return -1; } if (unblock_hook != NULL) { printk("Error installing HLS: block_hook != NULL!!!\n"); return -1; } if (fork_hook != NULL) { printk("Error installing HLS: fork_hook != NULL!!!\n"); return -1; } if (cleanup_hook != NULL) { printk("Error installing HLS: cleanup_hook != NULL!!!\n"); return -1; } #ifdef __DO_CLI__ spin_lock_irqsave(&hls_lock, flags); #endif block_hook = hls_bottom_vp_release; unblock_hook = hls_bottom_vp_request; fork_hook = hls_bottom_vp_register; cleanup_hook = hls_bottom_vp_unregister; setsched_hook = hls_setsched; HLSInit(); /* * ??? = hls_bottom_vp_msg; */ #ifdef __CREATE_HIERARCHY__ hls_convert_tasks(); #endif #ifdef __DO_CLI__ spin_unlock_irqrestore(&hls_lock, flags); #endif return 0; } void cleanup_module(void) { unsigned long flags; #ifdef __DO_CLI__ spin_lock_irqsave(&hls_lock, flags); #endif hls_release_tasks(); HLSDeinit(); block_hook = NULL; unblock_hook = NULL; fork_hook = NULL; cleanup_hook = NULL; setsched_hook = NULL; hls_proc_cleanup(); #ifdef __DO_CLI__ spin_unlock_irqrestore(&hls_lock, flags); #endif } --- NEW FILE: sched.c --- /* * Copyright (c) 2002 Luca Abeni * * Module Name: sched.c * Abstract: Moves tasks between schedulers. * Author: Luca Abeni 2-Feb-2002 * * This is free software; see GPL.txt */ static inline struct task_struct *find_process_by_pid(pid_t pid) { struct task_struct *tsk = current; if (pid) { tsk = find_task_by_pid(pid); } return tsk; } /* Return value: * < 0 ---> Failure * = 0 ---> Success * > 0 ---> do the regular Linux thing... */ int hls_setsched(pid_t pid, int policy, struct sched_param *param) { struct task_struct *p; struct hls_param hls_p; struct sched_param sched_p; unsigned long flags; int res; spin_lock_irqsave(&hls_lock, flags); p = find_process_by_pid(pid); if (p == NULL) { spin_unlock_irqrestore(&hls_lock, flags); return -ESRCH; } if (policy != HLS_CBS) { if (p->private_data != NULL) { HLSExitThreadHook(t); p->policy = SCHED_NORMAL; p->private_data = NULL; } spin_unlock_irqrestore(&hls_lock, flags); return 1; } if (copy_from_user(&sched_p, param, sizeof(struct sched_param)) < 0) { spin_unlock_irqrestore(&hls_lock, flags); return -EFAULT; } if (sizeof(struct hls_param) != sched_p.size) { spin_unlock_irqrestore(&hls_lock, flags); return -EFAULT; } if (copy_from_user(&hls_p, sched_p.p, sizeof(struct hls_param)) < 0) { spin_unlock_irqrestore(&hls_lock, flags); return -EFAULT; } /* Extra consinstency check... */ if (hls_p.signature != HLS_SIGNATURE) { spin_unlock_irqrestore(&hls_lock, flags); return -EFAULT; } if (p->private_data == NULL) { printk("HLS Error: %d has private_data = NULL???\n", p->pid); spin_unlock_irqrestore(&hls_lock, flags); return -EINVAL; } res = HLSCtl(p, &hls_p); spin_unlock_irqrestore(&hls_lock, flags); return res; } --- NEW FILE: procfs.c --- /* * Copyright (c) 2002 Luca Abeni * * Module Name: procfs.c * Abstract: ProcFS interface for HLS: allows to create scheduler * instances and to build the schedulers hierarchy. * Author: Luca Abeni 2-Feb-2002 * * This is free software; see GPL.txt */ #include <linux/config.h> #if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS) #define MODVERSIONS #endif #ifdef MODVERSIONS //#include <linux/modversions.h> #endif #include <linux/module.h> #include <linux/kernel.h> #include <linux/proc_fs.h> #include <linux/slab.h> #include <data.h> #include <interface-data.h> #include <hls_internal.h> #include "procfs.h" static struct proc_dir_entry *hls_dir, *schedulers_file, *instances_file, *tasks_file, *default_file, *rt_file; #if 0 extern char *hls_scheduler_name(int i); extern char *hls_instance_name(int i); extern char *hls_instance_scheduler(int i); extern char *hls_instance_father(int i); extern struct HLS_SCHED_INSTANCE *HLSFindInstByName (char *Name); extern struct HLS_SCHED_INSTANCE *HLSNewSchedInstance(char *SchedName, char *InstName, struct HLS_SCHED_INSTANCE *Parent); extern void SetDefPriForSched(char Pri, struct HLS_SCHED_INSTANCE *Inst); extern int hls_setparam_ascii(struct HLS_SCHED_INSTANCE *inst, char *param); #endif static int hls_proc_read_rt(char *p, char **s, off_t o, int c, int *eof, void *dummy) { char *name; int len; name = hls_rt_name(); #if (HLS_DEBUG > 0) printk("Read %s (%d)\n", name, strlen(name)); #endif len = strlen(name) + 1; strcpy(p, name); return len; } static int hls_proc_write_rt(struct file *f, const char *b, unsigned long c, void *dummy) { void *sched; char schedname[16]; memcpy(schedname, b, c); schedname[c - 1] = 0; sched = HLSFindInstByName(schedname); if (sched == NULL) { printk("Cannot find %s\n", schedname); return c; } hls_setrt(sched); return c; } static int hls_proc_read_default(char *p, char **s, off_t o, int c, int *eof, void *dummy) { char *name; int len; name = hls_default_name(); #if (HLS_DEBUG > 0) printk("Read %s (%d)\n", name, strlen(name)); #endif len = strlen(name) + 1; strcpy(p, name); return len; } static int hls_proc_write_default(struct file *f, const char *b, unsigned long c, void *dummy) { void *sched; char schedname[16]; memcpy(schedname, b, c); schedname[c - 1] = 0; if (memcmp(schedname, "null", 4)) { printk("Searching for %s\n", schedname); sched = HLSFindInstByName(schedname); if (sched == NULL) { printk("Cannot find %s\n", schedname); return c; } } else { printk("Schedname = NULL\n"); sched = NULL; } hls_setdefault(sched); return c; } static int hls_proc_read_schedulers(char *p, char **s, off_t o, int c, int *eof, void *dummy) { int l, len, i; char *name; len = 0; i = 0; MOD_INC_USE_COUNT; while((name = hls_scheduler_name(i)) != (char *)-1) { if (name != NULL) { l = sprintf(p, "%d %s\n", i, name); p += l; len += l; } i++; } MOD_DEC_USE_COUNT; return len; } static int hls_proc_write_instances(struct file *f, const char *b, unsigned long c, void *dummy) { void *father_sched, *new_instance; char mybuff[64]; char instname[16], schedname[16], fathername[16]; int len, res; memcpy(mybuff, b, c); mybuff[c - 1] = 0; #if (HLS_DEBUG > 0) printk("ProcFSed %s\n", mybuff); #endif sscanf(mybuff, "%s %s %s %n", instname, schedname, fathername, &len); #if (HLS_DEBUG > 0) printk("Creating %s of type %s and father %s\n", instname, schedname, fathername); #endif father_sched = HLSFindInstByName(fathername); if (father_sched == NULL) { printk("Cannot find the parent scheduler\n"); return c; } new_instance = HLSNewSchedInstance(schedname, instname, father_sched); if (new_instance == NULL) { printk("Creation failed!\n"); return c; } SetDefPriForSched(1, new_instance); if ((len > 0) && (len < c)) { #if (HLS_DEBUG > 0) printk("Read %d: remains %s\n", len, mybuff + len); #endif res = hls_setparam_ascii(new_instance, mybuff + len); if (res < 0) { printk("Failed to set the scheduling parameters\n"); /* FIXME: Maybe we should remove this instance... */ } } else { res = hls_setparam_ascii(new_instance, NULL); if (res < 0) { printk("Failed to set the scheduling parameters\n"); /* FIXME: Maybe we should remove this instance... */ } } return c; } static int hls_proc_read_instances(char *p, char **s, off_t o, int c, int *eof, void *type) { int l, len, i; char *name, *schedname, *father; len = 0; i = 0; MOD_INC_USE_COUNT; while((name = hls_instance_name(i)) != (char *)-1) { if (name != NULL) { schedname = hls_instance_scheduler(i); father = hls_instance_father(i); #if 1 if (((type == (void *)2) && (!strcmp(schedname, "thread"))) || ((type == (void *)1) && (strcmp(schedname, "thread")))) { l = sprintf(p, "%d %s %s %s\n", i, name, schedname, father); p += l; len += l; } #else l = sprintf(p, "%d %s %s\n", i, name, schedname); p += l; len += l; #endif } i++; } MOD_DEC_USE_COUNT; return len; } int hls_proc_init(void) { hls_dir = proc_mkdir("HLS", NULL); if(hls_dir == NULL) { return -ENOMEM; } hls_dir->owner = THIS_MODULE; schedulers_file = create_proc_read_entry("schedulers", 0444, hls_dir, hls_proc_read_schedulers, NULL); if(schedulers_file == NULL) { remove_proc_entry("HLS", NULL); return -ENOMEM; } schedulers_file->owner = THIS_MODULE; instances_file = create_proc_entry("instances", 0644, hls_dir); if(instances_file == NULL) { remove_proc_entry("schedulers", hls_dir); remove_proc_entry("HLS", NULL); return -ENOMEM; } instances_file->data = (void *)1; instances_file->read_proc = hls_proc_read_instances; instances_file->write_proc = hls_proc_write_instances; instances_file->owner = THIS_MODULE; tasks_file = create_proc_read_entry("tasks", 0444, hls_dir, hls_proc_read_instances, (void *)2); if(tasks_file == NULL) { remove_proc_entry("instances", hls_dir); remove_proc_entry("schedulers", hls_dir); remove_proc_entry("HLS", NULL); return -ENOMEM; } tasks_file->owner = THIS_MODULE; default_file = create_proc_entry("default", 0644, hls_dir); if(default_file == NULL) { remove_proc_entry("tasks", hls_dir); remove_proc_entry("instances", hls_dir); remove_proc_entry("schedulers", hls_dir); remove_proc_entry("HLS", NULL); return -ENOMEM; } default_file->data = NULL; default_file->read_proc = hls_proc_read_default; default_file->write_proc = hls_proc_write_default; default_file->owner = THIS_MODULE; rt_file = create_proc_entry("rt", 0644, hls_dir); if(rt_file == NULL) { remove_proc_entry("default", hls_dir); remove_proc_entry("tasks", hls_dir); remove_proc_entry("instances", hls_dir); remove_proc_entry("schedulers", hls_dir); remove_proc_entry("HLS", NULL); return -ENOMEM; } rt_file->data = NULL; rt_file->read_proc = hls_proc_read_rt; rt_file->write_proc = hls_proc_write_rt; rt_file->owner = THIS_MODULE; return 0; } void hls_proc_cleanup(void) { remove_proc_entry("rt", hls_dir); remove_proc_entry("default", hls_dir); remove_proc_entry("tasks", hls_dir); remove_proc_entry("instances", hls_dir); remove_proc_entry("schedulers", hls_dir); remove_proc_entry("HLS", NULL); } --- NEW FILE: misc.c --- unsigned char KiFindLeftNibbleBitTable[] = {0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3}; --- NEW FILE: hls_timers.c --- /* * Copyright (c) 2002 Luca Abeni & John Regehr * * Module Name: hls_timers.c * Abstract: Kernel-dependent part of the timers mechanism. * Author: Luca Abeni 2002, John Regehr 2000 * * This is free software; see GPL.txt */ #include <hls_common.h> /* For struct HLS_SCHED_INSTANCE */ extern spinlock_t hls_lock; /* * expiring scheduler timers call this function */ void hls_timeout(unsigned long arg) { struct HLS_SCHED_INSTANCE *Sched; #ifdef __DO_CLI1__ spin_lock_irqsave(&hls_lock, flags); #endif Sched = (struct HLS_SCHED_INSTANCE *) arg; if (current->state != TASK_RUNNING) { /* hls_printk("Interrupting a blocking call??? [%d]\n", current->pid); */ } Sched->CB->I_TimerCallback(Sched); #ifdef __DO_CLI1__ spin_unlock_irqrestore(&hls_lock, flags); #endif } void hls_stop_timer(struct HLS_SCHED_INSTANCE *Sched) { del_timer_sync(&(Sched->HLSTimer)); } void HLSSetTimer (_int64 T1, struct HLS_SCHED_INSTANCE *Sched) { _int64 T; /* Timer debugging stuff... */ if (timer_pending(&Sched->HLSTimer)) { /* ERROR!!! Timer Posted twice! */ extern int whereami; hls_hard_printk("HLS ERROR: Scheduler %s posted a timer twice!!! WAI = %d\n", Sched->Name, whereami); return; } T = -T1; if (T < 0) { panic("Strange timer..."); } #ifdef __MULDIV__ Sched->HLSTimer.expires = jiffies + llimd(T, HZ, 10000000); #else Sched->HLSTimer.expires = jiffies + (T * HZ) / 10000000; #endif if (Sched->HLSTimer.expires == jiffies) { Sched->HLSTimer.expires++; } Sched->HLSTimer.data = (unsigned long)Sched; Sched->HLSTimer.function = hls_timeout; add_timer(&(Sched->HLSTimer)); } WNT_TIME HLSGetCurrentTime (void) { /* FIXME: For the moment, we are using gettimeofday... * but we can do something smarter! */ #if 0 WNT_TIME t = HLSReadTimeStamp (); HLS_ASSERT (NTtoTicks != 0); return t / NTtoTicks; #else struct timeval tv; WNT_TIME res; do_gettimeofday(&tv); res = ((WNT_TIME)tv.tv_usec * 10) + (WNT_TIME)(tv.tv_sec * 10000000); return res; #endif } --- NEW FILE: bottom.h --- #ifndef __BOTTOM_H__ #define __BOTTOM_H__ extern void hls_bottom_vp_request(struct task_struct *t); extern void hls_bottom_vp_release(struct task_struct *t); extern void hls_bottom_vp_register(struct task_struct *t); extern void hls_bottom_vp_unregister(struct task_struct *t); #endif /* __BOTTOM_H__ */ --- NEW FILE: bottom.c --- /* * Copyright (c) 2002 Luca Abeni * * Module Name: bottom.c * Abstract: This is the low level interface with the Linux kernel, * containing the hooks called by the gensched patch and the * functions used to schedule a task in Linux. * Author: Luca Abeni 2-Feb-2002 * * This is free software; see GPL.txt */ #include <interface-funcs.h> #include <linux/smp_lock.h> #include <linux/kernel.h> #include <linux/sched.h> #include "data.h" #include "interface-data.h" #include "hls_hooks.h" #include "bottom.h" #include "hls_internal.h" #ifndef CONFIG_GENERIC_SCHEDULER #error Generic Scheduler is not enabled!!! #endif /* #define VERBOSE1 */ struct HLS_PROC { void *CurrentThread; int Standby; }; static struct task_struct *my_current[MAXIMUM_PROCESSORS]; extern struct HLS_PROC HLSProc[MAXIMUM_PROCESSORS]; spinlock_t hls_lock __cacheline_aligned = SPIN_LOCK_UNLOCKED; /* inner */ static int wup, lastt; extern int whereami; void show_tasks(void); /* CHECKME: Must acquire rq lock, somewhere... */ void HLSScheduleThread(struct task_struct *t, unsigned long proc) { int sched_non_running; sched_non_running = 0; if (my_current[proc] != NULL) { struct task_struct *c; c = my_current[proc]; #ifdef VERBOSE hls_printk("setting %d to %d... ", current->pid, HLS_IDLE_PRIORITY); #endif if (c->rt_priority != HLS_SCHEDULING_PRIORITY) { printk("HLS ERROR!!! Deschedulign %d with rt_priority = %ld != %d\n", c->pid, c->rt_priority, HLS_SCHEDULING_PRIORITY); } /* Must be implemented in some way... */ #error TODO: Do something smart, here!!! c->rt_priority = HLS_IDLE_PRIORITY; c->prio = MAX_PRIO; array = c->array; array->nr_active--; list_del(&c->run_list); if (list_empty(array->queue + c->prio)) __clear_bit(c->prio, array->bitmap); } else { #ifdef VERBOSE hls_printk("HLS From idle...\n"); #endif } #ifdef VERBOSE hls_printk("current->rt_priority = %ld\n", current->rt_priority); #endif my_current[proc] = t; /* Do we have a new task to schedule? */ if (t != NULL) { sched_non_running = (t->state != TASK_RUNNING); if(t->policy != SCHED_FIFO) { printk("HLS ERROR: Scheduling an HLS task with policy != SCHED_FIFO...\n"); hls_printk("HLS ERROR: Scheduling an HLS task with policy != SCHED_FIFO...\n"); } /* Yes... Schedule it. * The linux dispatcher will do the dirty work for us... */ t->rt_priority = HLS_SCHEDULING_PRIORITY; HLSProc[proc].CurrentThread = t->private_data; c->prio = 0; /* FIXME! */ repeat_lock_task: local_irq_save(rq_flags); rq = task_rq(c); spin_lock(&rq->lock); if (unlikely(rq != task_rq(p))) { spin_unlock_irqrestore(&rq->lock, rq_flags); goto repeat_lock_task; } array = rq->active; list_add_tail(&c->run_list, array->queue + c->prio); __set_bit(c->prio, array->bitmap); array->nr_active++; c->array = array; wup = t->pid; } else { HLSProc[proc].CurrentThread = NULL; wup = -1; } set_tsk_need_resched(current); show_tasks(); lastt = wup; if (sched_non_running) { printk("HLS ERROR: Trying to schedule %d with state = %ld\n", t->pid, t->state); } } void hls_bottom_vp_request(struct task_struct *t) { unsigned long flags; #ifdef __DO_CLI__ spin_lock_irqsave(&hls_lock, flags); #endif #ifdef VERBOSE hls_printk("\nTask %d unblocks (requests the VP)", t->pid); #endif HLSUnblockThreadHook(t); #ifdef VERBOSE hls_printk(" --- DONE the unblock of %d\n\n", t->pid); #endif #ifdef __DO_CLI__ spin_unlock_irqrestore(&hls_lock, flags); #endif } void hls_bottom_vp_release(struct task_struct *t) { unsigned long flags; long int initial_state; #ifdef __DO_CLI__ spin_lock_irqsave(&hls_lock, flags); #endif initial_state = t->state; if (t->state == TASK_RUNNING) { printk("HLS HYPER-ERROR!!! Blocking %d with state == %ld\n", t->pid, t->state); hls_printk("HLS HYPER-ERROR!!! Blocking %d with state == %ld\n", t->pid, t->state); } #ifdef VERBOSE hls_printk("\nTask %d blocks [state %ld] (releases the VP)", t->pid, t->state); hls_printk("State again (before calling): %ld\n", t->state); #endif HLSBlockThreadHook(t); #ifdef VERBOSE hls_printk(" --- DONE the block of %d [state %ld]\n\n", t->pid, t->state); #endif if (initial_state != t->state) { hls_printk("HLS ERROR!!! Task state changed during the hook??? %ld != %ld!!! Correcting...\n", t->state, initial_state); t->state = initial_state; } #ifdef __DO_CLI__ spin_unlock_irqrestore(&hls_lock, flags); #endif } void hls_bottom_vp_register(struct task_struct *t) { unsigned long flags; if (!strcmp(hls_default_name(), "")) { t->private_data = NULL; return; } #ifdef __DO_CLI__ spin_lock_irqsave(&hls_lock, flags); #endif #ifdef VERBOSE hls_printk("\nCreated task %d ", t->pid); hls_printk("HLS parameter is: 0x%lx\n", (unsigned long int)t->hls); #endif if (t->state != TASK_UNINTERRUPTIBLE) { printk("HLS ERROR: Creating task with unexpected state: %ld\n", t->state); hls_printk("HLS ERROR: Creating task with unexpected state: %ld\n", t->state); return; } t->policy = SCHED_FIFO; t->rt_priority = HLS_IDLE_PRIORITY; HLSCreateThreadHook(t, t->state); #ifdef VERBOSE hls_printk(" --- DONE the creation of %d\n\n", t->pid); #endif #ifdef __DO_CLI__ spin_unlock_irqrestore(&hls_lock, flags); #endif } void hls_bottom_vp_unregister(struct task_struct *t) { unsigned long flags; #ifdef __DO_CLI__ spin_lock_irqsave(&hls_lock, flags); #endif #ifdef VERBOSE hls_printk("\n%d exits (Unregisters the VP) \n", t->pid); #endif if (t->private_data != NULL) { HLSExitThreadHook(t); t->policy = SCHED_NORMAL; } #ifdef VERBOSE hls_printk(" --- DONE the end of %d\n\n", t->pid); #endif #ifdef __DO_CLI__ spin_unlock_irqrestore(&hls_lock, flags); #endif } void show_tasks(void) { struct task_struct *dummy, *t; int active; active = 0; read_lock(&tasklist_lock); do_each_thread(dummy, t) { #ifdef VERBOSE1 hls_printk("T%d:\t", t->pid); #endif if (t->private_data) { #ifdef VERBOSE1 hls_printk("HLS "); #endif if (t->rt_priority == HLS_SCHEDULING_PRIORITY) { if (t->state != TASK_RUNNING) { printk("HLS ERROR: Task %d has rt_priority = %ld and state = %ld --- WAI = %d WUP = %d Last = %d\n", t->pid, t->rt_priority, t->state, whereami, wup, lastt); hls_printk("HLS ERROR: Task %d has rt_priority = %ld and state = %ld\n", t->pid, t->rt_priority, t->state); } active++; } } else { #ifdef VERBOSE1 hls_printk("non hls "); #endif } #ifdef VERBOSE1 hls_printk("priority: %ld policy: %ld state: %ld\n", t->rt_priority, t->policy, t->state); #endif } while_each_thread(dummy, t); read_unlock(&tasklist_lock); #if 0 if (active > 1) { printk("Too many active tasks!!! Shutting HLS down...\n"); for_each_task(t) { #ifdef VERBOSE printk("T%d\t", t->pid); #endif if (t->private_data != NULL) { #ifdef VERBOSE printk("HLS!\t"); #endif HLSExitThreadHook(t); t->private_data = 0; t->policy = SCHED_NORMAL; } #ifdef VERBOSE printk("\n"); #endif } HLSDeinit(); block_hook = NULL; unblock_hook = NULL; fork_hook = NULL; cleanup_hook = NULL; } #else if (active > 1) { printk("HLS ERROR: Too many active tasks!!! But doing nothing...\n"); hls_printk("HLS ERROR: Too many active tasks!!! But doing nothing...\n"); } #endif #ifdef VERBOSE if (active == 0) { hls_printk("No active tasks?\n"); } #endif } --- NEW FILE: procfs.h --- #ifndef __PROCFS_H__ #define __PROCFS_H__ int hls_proc_init(void); void hls_proc_cleanup(void); #endif /* __PROCFS_H__ */ --- NEW FILE: hls_ctl.c --- /* * Copyright (c) 2002 Luca Abeni & John Regehr * * Module Name: hls_ctl.c * Abstract: This file implements the user interface for HLS, * allowing to move tasks between scheduler instances. * Author: Luca Abeni 2002, John Regehr 2000 * * This is free software; see GPL.txt */ #include <hls_common.h> #include <hls_internal.h> #include <thr.h> #include <hls.h> #include <hls_hooks.h> #define NOLINUX_TASKS #define HLS_NAME_SIZE 256 #define HLS_PARMS_SIZE 256 struct hls_sched_param { struct sched_param sp; int size; void *p; }; extern spinlock_t hls_lock; static int hls_setparam(struct HLS_VPROC *vp, void *sched_params, int prio) { struct hls_message NewMsg; #ifdef HLS_DEBUG NewMsg.ObjType = RRMsgValue; #endif NewMsg.body = sched_params; if (sched_params == NULL) { NewMsg.type = MSG_SETPRI; } else { NewMsg.type = MSG_SETPARAMS; } NewMsg.Pri = prio; return vp->TopSched->CB->B_Msg(NULL, vp, (MsgHandle)&NewMsg); } static int hls_null_msg(PRKTHREAD t) { int status; struct hls_message NewMsg; struct TH_INSTANCE_DATA *th; HLS_STATUS res; th = HLSFindThread (t); HLS_ASSERT (th); #ifdef HLS_DEBUG NewMsg.ObjType = RRMsgValue; #endif NewMsg.type = MSG_NULL; NewMsg.body = NULL; res = th->vp->TopSched->CB->B_Msg (NULL, th->vp, (MsgHandle)&NewMsg); if (res == HLS_SUCCESS) { status = 0; } else { status = -EINVAL; } HLSDbgPrint (9, ("(infr) HLSNullMsg: done\n")); return status; } static int hls_thread_move(PRKTHREAD t, struct HLS_SCHED_INSTANCE *new_sched) { struct HLS_SCHED_INSTANCE *th_inst; struct TH_INSTANCE_DATA *th, *th1; HLS_STATUS status; VPROC_STATE st; HLSDbgPrint (9, ("(infr) entering MoveThread\n")); th = HLSFindThread(t); if (!th) { HLSDbgPrint (1, ("MoveThread: HLSFindThread returned NULL\n")); return -EINVAL; } HLS_ASSERT (th->vp); HLS_ASSERT (th->vp->BottomSched); th_inst = th->vp->BottomSched; th1 = (struct TH_INSTANCE_DATA *)th_inst->SchedData; /* FIXME: This was put in to check if th1 is always == th... * it seems that it is. So, we can remove the need for th1! if (th == th1) { printk("They are the same!!!\n"); } */ HLS_ASSERT (th1->ObjType == ThInstValue); HLSDbgPrint (3, ("(infr) moving thread %s from %s to %s\n", th_inst->Name, th1->vp->TopSched->Name, new_sched->Name)); st = th1->vp->State; RemoveThread (th1, th1->Thread, HLS_TRUE); HLSDbgPrint (3, ("(infr) removed\n")); HLS_ASSERT (th1->vp->State == VP_Waiting); th1->vp->TopSched = new_sched; status = th1->vp->TopSched->CB->B_RegisterVP(new_sched, th_inst, th1->vp); HLS_ASSERT(status == HLS_SUCCESS); HLSDbgPrint(3, ("(infr) registered\n")); th_inst->Parent = new_sched; /* This cannot be done until the sched param are set... status = HLSSetPri(th1->Thread, HLS_DEFAULT_PRIORITY); HLS_ASSERT(status == HLS_SUCCESS); HLSDbgPrint (3, ("(infr) priority set to 1\n")); */ return st; } void set_state(struct TH_INSTANCE_DATA *th, int st) { switch(st) { case VP_Ready: case VP_Running: HLSDbgPrint (3, ("(infr) ChangeDefault: requesting CPU for thread\n")); // th1->vp->State = VP_Ready; th->vp->TopSched->CB->B_VP_Request(th->vp); break; case VP_Waiting: HLSDbgPrint (3, ("(infr) ChangeDefault: thread is currently blocked\n")); th->vp->State = VP_Waiting; break; default: printk("HLS Error: Unexpected state!!!\n"); HLS_ASSERT (0); } HLSDbgPrint (3, ("(infr) returning\n")); } /* TODO: * - in hls_ctl, Change hls_param *p ---> void *sp, HLS_SCHED_INSTANCE *target_sched * - add an hls_do_something_to_user_parms to get those vales... */ int hls_ctl(PRKTHREAD t, struct HLS_SCHED_INSTANCE *target_sched, void *s_p, int hls_priority) { int status; /* void *s_p; struct HLS_SCHED_INSTANCE *target_sched; */ struct TH_INSTANCE_DATA *th; int state; #if 0 if (p->command == HLS_CMD_NULL_MSG) { return hls_null_msg(t); } #endif #if 0 target_sched = HLSFindInstByName(sched_name); if (!target_sched) { HLSDbgPrint (2, ("(infr) Cannot find scheduler %s\n", sched_name)); return -EINVAL; } #endif /* Find the task instance */ th = HLSFindThread(t); if (!th) { HLSDbgPrint (2, ("(infr) oops - bad news; thread %d not found\n", t->pid)); return -EINVAL; } /* Is it already the task's scheduler? */ if (th->vp->TopSched == target_sched) { /* Yes: We simply do a setparm */ HLSDbgPrint (9, ("(infr) hls_ctl: %s is already scheduled by %s; trying to update params\n", ThreadStr(t), target_sched->Name)); status = hls_setparam(th->vp, s_p, hls_priority); if (status == HLS_SUCCESS) { return 0; } else { return -EINVAL; } } /* We have to move to the new scheduler... */ #ifdef HLS_DEBUG hls_printk("hls_ctl: Moving to %s\n", target_sched->Name); #endif state = hls_thread_move(t, target_sched)... [truncated message content] |