数据结构:
内存用双向链表模拟,便于内存块的拆分和合并;
进程表用小根堆表示,以进程的结束时间为排序依据;
等待队列就是用先进先出的队列结构了。
算法描述:
设任一时刻当前需要被处理的进程为p1,进程表堆顶进程为p2,等待队列队头进程为p3,进入过等待队列的进程总数为count,所有进程运行完毕的时间为duration。
1、如果所有进程都已经被处理并且进程表也为空,则算法结束,否则执行第2步。
2、如果还有进程未被处理则执行第3步;否则,执行第6步。
3、如果进程表为空则执行第5步,否则执行第4步。
4、检测p1的起始时间是否小于进程表中所有进程的结束时间(由于进程表具有小根堆的性质,只需要和p2的结束时间比较即可),如果小于则执行第5步;否则执行第6步。
5、尝试给p1分配内存, 如果成功则更新p1的结束时间(p1的结束时间 = p1的开始时间 + p1的运行时间),并且将其加入进程表中,同时调整进程表的结构以保持小根堆性质;如果失败,将其加入等待队列,更新count(count = count + 1),转到第1步。
6、更新duration(duration = p2的结束时间),销毁进程表中所有结束时间等于duration的进程,也需要调整进程表的结构以保持小根堆性质,释放它们所占用的内存,执行第7步。
7、尝试给p3分配内存,如果成功则更新p3的结束时间(p3的结束时间 = duration + p3的运行时间),并且将其加入到进程表中,同时从等待队列中删除,此时同样需要调整进程表的结构以保持小根堆性质,继续执行第7步;否则转到第1步。
PS:描述不清楚或者错误还请指正,代码有点多~~~
#include <stdio.h>
#define MAX_COUNT 10010
#define LEFT_CHILD(x) (2 * x + 1)
#define RIGHT_CHILD(x) (2 * x + 2)
#define PARENT(x) ((x - 1) / 2)
//MemoryNode
typedef struct _MemoryNode
{
int size;
int status;
struct _MemoryNode *prev;
struct _MemoryNode *next;
} MemoryNode;
//Memory
typedef struct _Memory
{
MemoryNode head;
MemoryNode unused;
MemoryNode buffer[MAX_COUNT];
} Memory;
//method of Memory
void MemoryInit(Memory *m, int size)
{
int i;
MemoryNode *prev = NULL;
MemoryNode *next = NULL;
m->head.size = size;
m->head.status = 0;
m->head.prev = NULL;
m->head.next = NULL;
m->unused.size = 0;
m->unused.status = 0;
m->unused.prev = NULL;
m->unused.next = m->buffer;
prev = &m->unused;
next = m->buffer;
for (i = 0; i < MAX_COUNT - 1; i++)
{
next->size = 0