📄 timebase.c
字号:
/* timebase.c -- management of calls, time bases and heaps for moxc *//****************************************************************************** Change Log* Date | Change*-----------+-----------------------------------------------------------------* 2-Apr-91 | JDW : further changes* 21-Mar-92 | GWL : abort recovery* 28-Apr-03 | DM : true->TRUE*****************************************************************************/#include "stdio.h"#include "cext.h"#include "userio.h"#include "midifns.h"#include "timebase.h"#include "moxc.h"timebase_type timebase_queue = NULL; /* waiting to run timebase queue */call_type callfree = NULL; /* free list */private void fatal();/***************************************************************************** timebase_create* Inputs:* maxsize is the initial size of the heap* Outputs:* returns an initialized timebase_type****************************************************************************/timebase_type timebase_create(maxsize) int maxsize;{ static char *error_msg = "Out of memory in timebase_create()"; timebase_type base = (timebase_type) memget(sizeof(timebase_node)); if (!base) fatal(error_msg); base->next = NULL; base->next_time = MAXTIME; base->virt_base = 0L; base->real_base = 0L; base->rate = 256L; base->heap_size = 0; base->heap_max = maxsize; base->heap = (call_type *) memget(sizeof(call_type) * maxsize); if (!base->heap) fatal(error_msg); return base;}/***************************************************************************** callinsert* Inputs:* timebase_type base: the time base and heap* call_type call: the call to insert in heap* Outputs: none* Implementation:* linear insertion; to be changed to heap****************************************************************************/void callinsert(base, call) timebase_type base; call_type call;{ int i; register call_type *heap = base->heap; /* handle overflow -- this should never be executed if the user * gives the right initial heap size */ base->heap_size++; if (base->heap_size >= base->heap_max) { call_type *new_heap = (call_type *) memget((base->heap_max << 1) * sizeof(call_type)); int i; call_type *oldptr; call_type *newptr; if (!new_heap) { gprintf(TRANS, "Out of space, can't allocate new heap\n"); EXIT(1); } oldptr = base->heap; newptr = new_heap; for (i = base->heap_max; i > 0; i--) *newptr++ = *oldptr++; memfree((char *) heap, base->heap_max * sizeof(call_type)); base->heap = heap = new_heap; base->heap_max = (base->heap_max << 1); } /* now do the heap insert */ i = base->heap_size; while (i > 1) { int parent = i >> 1; if (heap[parent]->u.e.time < call->u.e.time || (heap[parent]->u.e.time == call->u.e.time && heap[parent]->u.e.priority <= call->u.e.priority)) break; heap[i] = heap[parent]; i = parent; } heap[i] = call; /* if next_time might change, reinsert base into queue */ if (heap[1] == call) { remove_base(base); insert_base(base); }}/***************************************************************************** callshow* Inputs:* calltype call: the call to show* Effect: * prints a description of call* Assumes:* call is not null****************************************************************************/void callshow(call) call_type call;{ int i; gprintf(TRANS,"address: %lx\n", (ulong)call); gprintf(TRANS,"time: %ld\n", call->u.e.time); gprintf(TRANS,"routine: %lx\n", (ulong)call->u.e.routine); gprintf(TRANS,"parameters:"); for (i = 0; i < MAX_CALL_ARGS; i++) { gprintf(TRANS, " %d", call->u.e.p.arg[i]); } gprintf(TRANS, "\n");}/**************************************************************** fatal** Input : msg: a message to be displayed* Effect: print message and exit program***************************************************************/private void fatal(msg) char *msg;{ gprintf(FATAL, msg); EXIT(1);}/**************************************************************** timebase_free** Input : a time base* Effect: deallocate the time base***************************************************************/void timebase_free(timebase) timebase_type timebase;{ remove_base(timebase); if (timebase->heap) { memfree((char *) timebase->heap, (timebase->heap_max * sizeof(call_type))); } memfree((char *) timebase, sizeof(timebase_node));}/**************************************************************** insert_base** Input : a time base not in the list * Effect: insert timebase at the appropriate spot in the list* computes the next_time field from the top of the heap***************************************************************/void insert_base(timebase) timebase_type timebase;{ register timebase_type *ptr = &timebase_queue; register time_type next_time = MAXTIME; /* compute next_time */ if (timebase->heap_size != 0) { register call_type call = timebase->heap[1]; /* virt to real calculation */ next_time = (virt_to_real_256(timebase, call->u.e.time) & 0xFFFFFF00) + call->u.e.priority;/* gprintf(TRANS, "insert next_time is %ld, vt %ld, rb %ld, vb %ld rt %ld\n", next_time, timebase->heap[1]->u.e.time, timebase->real_base, timebase->virt_base, timebase->rate); */ } timebase->next_time = next_time; if (next_time != MAXTIME) { /* insert into the list */ while (TRUE) { if (! *ptr) { *ptr = timebase; timebase->next = NULL; return; } else if ((*ptr)->next_time >= next_time) { timebase->next = *ptr; *ptr = timebase; return; } else ptr = &((*ptr)->next); } }}/**************************************************************** remove_base** Input : timebase* Effect: if timebase is in the queue, remove it***************************************************************/void remove_base(timebase) timebase_type timebase;{ timebase_type *ptr = &timebase_queue; while (*ptr) { if (*ptr == timebase) { *ptr = timebase->next; return; } else ptr = &((*ptr)->next); }}/**************************************************************** remove_call** Input : a timebase -- passed as a global* Assumes: a_timebase->heap_size > 0* Returns: the earliest call in the queue* Effect: removes the earliest call in the queue***************************************************************/call_type remove_call(timebase_type a_timebase){ register call_type *heap = a_timebase->heap; call_type result = heap[1]; register call_type large; int i = 1; int child = i << 1;; large = heap[a_timebase->heap_size--]; while (child <= a_timebase->heap_size) { if (child + 1 <= a_timebase->heap_size) { if (heap[child + 1]->u.e.time < heap[child]->u.e.time || (heap[child + 1]->u.e.time == heap[child]->u.e.time && heap[child + 1]->u.e.priority < heap[child]->u.e.priority)) child++; } /* child is now the index of the least child */ if (large->u.e.time < heap[child]->u.e.time || (large->u.e.time == heap[child]->u.e.time && large->u.e.priority <= heap[child]->u.e.priority)) break; /* swap */ heap[i] = heap[child]; i = child; child = i << 1; } heap[i] = large; return result;}/**************************************************************** set_rate** Input : timebase and new rate* Effect: makes the current rate of timebase be rate***************************************************************/void set_rate(base, rate) timebase_type base; time_type rate;{ if (base == timebase) base->virt_base = virttime; else base->virt_base = real_to_virt(base, eventtime); base->real_base = eventtime; base->rate = rate;/* gprintf(TRANS, "new real_base %ld virt_base %ld\n", base->real_base, base->virt_base); */ remove_base(base); insert_base(base);} /**************************************************************** set_virttime** Input : virtual time* Effect: makes the current virtual time of timebase be vtime***************************************************************/void set_virttime(base, vtime) timebase_type base; time_type vtime;{ base->real_base = eventtime; base->virt_base = vtime; if (base == timebase) virttime = vtime; remove_base(base); insert_base(base);}/**************************************************************** timebase_use** Input : a timebase to use for scheduling* Effect: sets up globals: timebase, virttime***************************************************************/void timebase_use(base) register timebase_type base;{ if (timebase != base) { timebase = base; virttime = real_to_virt(base, eventtime); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -