/*
 * Copyright (C) 2002 Luca Abeni
 * This is Free Software; see GPL.txt for details
 */

#include <linux/config.h>
#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
#define MODVERSIONS
#endif
#ifdef MODVERSIONS
#include <linux/modversions.h>
#endif
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/list.h>

#include <scheduler.h>
#include <dispatch.h>

#ifdef __EXTRA_CHECK__

#define __EXTRA_LOG__ 

static void show_tasks(void)
{
  struct task_struct *t;
  int active;

  active = 0;

  for_each_task(t) {
#ifdef __EXTRA_LOG__ 
    sched_print("T%d:\t", t->pid);
#endif

    if (t->private_data) {
#ifdef __EXTRA_LOG__ 
      sched_print("Generic Scheduler");
#endif
    } else {
#ifdef __EXTRA_LOG__
      sched_print("non Generic Scheduler");
#endif
    }
    if (t->rt_priority == SCHEDULING_PRIORITY) {
      if (t->state != TASK_RUNNING) {
        sched_error("Scheduling ERROR: Task %d has rt_priority = %ld and state = %ld\n",
			t->pid, t->rt_priority, t->state);
      }
	active++;
    }

#ifdef __EXTRA_LOG__
    sched_print("priority: %ld  policy: %ld  state: %ld\n",
		    t->rt_priority, t->policy, t->state);
#endif
  }
  if (active > 1) {
    sched_error("Scheduling ERROR: Too many active tasks!!! But doing nothing...\n");
  }
  
  if (active == 0) {
    sched_print("No active tasks?\n");
  }
}
#endif

void stop(struct task_struct *c)
{
  if (c == NULL) {
    sched_error("CBS ERROR: Scheduling from idle!!!\n");

    return;
  }

  /* Various debugging & sanity checks... */
#ifdef __CBS_DEBUG__
  sched_print("setting %d to %d... ", c->pid, IDLE_PRIORITY);
#endif
  if (c->rt_priority != SCHEDULING_PRIORITY) {
    sched_error("Scheduling ERROR!!! Descheduling %d with rt_priority = %ld != %d\n",
		    c->pid, c->rt_priority, SCHEDULING_PRIORITY);
  }
  
  c->rt_priority = IDLE_PRIORITY;
  if((c->policy != SCHED_FIFO) && (c->policy != SCHED_RR)) {
    sched_error("Scheduling ERROR: Descheduling task %d with policy %ld != SCHED_FIFO or SCHED_RR...\n", c->pid, c->policy);
  }
}

void dispatch(struct task_struct *t, int cpu)
{
  /* Do we have a new task to schedule? */
  if (t != NULL) {

    if((t->policy != SCHED_FIFO) && (t->policy != SCHED_RR)){
      sched_error("Scheduling ERROR: Scheduling task %d with policy %ld != SCHED_FIFO | SCHED_RR...\n", t->pid, t->policy);
    }
    /* Yes... Schedule it.
     * The linux dispatcher will do the dirty work for us...
     */
    t->rt_priority = SCHEDULING_PRIORITY;
  } else {
#ifdef __CBS_DEBUG__
//    sched_print("Scheduling noone - are u sure?\n");
#endif
  } 
  current->need_resched = 1;

#ifdef __EXTRA_CHECK__
  show_tasks();
#endif
}

void idle_cpu(int cpu)
{
  dispatch(NULL, cpu);
}
