/*
OS Scheduler Simulator
** 連絡先: 琉球大学情報工学科 河野 真治
** (E-Mail Address: kono@ie.u-ryukyu.ac.jp)
**
** このソースのいかなる複写,改変,修正も許諾します。ただし、
** その際には、誰が貢献したを示すこの部分を残すこと。
** 再配布や雑誌の付録などの問い合わせも必要ありません。
** 営利利用も上記に反しない範囲で許可します。
** バイナリの配布の際にはversion messageを保存することを条件とします。
** このプログラムについては特に何の保証もしない、悪しからず。
**
** Everyone is permitted to do anything on this program
** including copying, modifying, improving,
** as long as you don't try to pretend that you wrote it.
** i.e., the above copyright notice has to appear in all copies.
** Binary distribution requires original version messages.
** You don't have to ask before copying, redistribution or publishing.
** THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE.
Task Queue Manager
*/
#include <stdio.h>
#include <stdlib.h>
#include "queue.h"
int queue_errno;
static QueuePtr freeQueue; /* Free Pool of Queue */
static QueuePtr queuePool; /* List of malloced free Queue */
static int extend_queue_pool(int num);
const int QUEUE_MALLOC_ERROR = 10;
const int POOL_SIZE_OVER_ERROR = 11;
const int MAX_POOL_SIZE = 65536*100;
int errno_queue;
static int pool_size;
//
// Initialize Queue Pool
// return NULL on error
//
int
init_queue(int num)
{
if (! queuePool) {
return extend_queue_pool(num);
}
return 1;
}
static int
extend_queue_pool(int num)
{
QueuePtr q;
// Keep malloc history in QueuePool
pool_size = num;
q = (QueuePtr) malloc(sizeof(Queue) * (num+1));
if (!q) {
queue_errno = QUEUE_MALLOC_ERROR;
return NULL;
}
q->next = queuePool;
queuePool = q;
// Connect all free queue in the pool
q = queuePool + 1;
for(q = queuePool+1; num-->0; q++) q->next = q+1;
q->next = freeQueue;
freeQueue = queuePool+1;
return 1;
}
void
destory_queue()
{
QueuePtr q;
for(q = queuePool ;q; q = q->next) {
free(q);
}
freeQueue = queuePool = NULL;
}
QueuePtr
new_queue(char *name, int length, int priority)
{
QueuePtr q;
if (!freeQueue) {
pool_size *= 2;
if (pool_size > MAX_POOL_SIZE) {
queue_errno = POOL_SIZE_OVER_ERROR;
return NULL;
}
if (!extend_queue_pool(pool_size)) {
return NULL;
}
}
q = freeQueue;
freeQueue = freeQueue->next;
q->next = NULL;
q->priority = priority;
q->name = name;
q->length = length;
q->invoke = 0;
q->waiting = q->start = q->end = q->prev_end = 0;
return q;
}
void
free_queue(QueuePtr q)
{
q->next = freeQueue;
freeQueue = q;
}
QueuePtr
insert_queue(QueuePtr list,QueuePtr q)
{
q->next = list;
return q;
}
QueuePtr
append_queue(QueuePtr list,QueuePtr q)
{
QueuePtr p = list;
if (!p) {
return q;
} else {
while(p->next) p = p->next;
p->next = q;
return list;
}
}
QueuePtr
dequeue(QueuePtr list,QueuePtr *q)
{
QueuePtr p = list;
if (p) {
*q = list;
return list->next;
}
return p;
}
QueuePtr
remove_queue(QueuePtr list,QueuePtr q)
{
QueuePtr p = list;
QueuePtr p1;
if (!p) return p;
p1 = p->next;
while(p1 && p1 != q) { p1 = p1->next; p = p->next; }
if (p1) {
p->next = p1->next;
}
return list;
}
QueuePtr
sort_queue(QueuePtr q,int (*comp)(QueuePtr,QueuePtr))
{
QueuePtr top,high,low,r,r1;
if (q == NULL) return q;
if (q->next == NULL) return q;
/* split list into high part and low part */
high = low = NULL;
for(r = q->next; r ; ) {
r1 = r->next;
if (comp(q,r)) {
r->next=high; high = r;
} else {
r->next=low; low = r;
}
r = r1;
}
/* sort each parts */
high = sort_queue(high,comp);
low = sort_queue(low,comp);
/* append sorted parts */
q->next = low;
if (high) {
top = high;
while(high->next) high = high->next;
high->next = q;
} else {
return q;
}
return top;
}
/* end */