📄 schedule.cpp
字号:
/************************************************************************
* schedule.cpp *
* Main task scheduler for Borg. This class is central to the workings *
* of the secondary thread, and to the calls which are passed back and *
* forth to the secondary thread. When Borg decides it is going to do *
* something it is added to a list of things to do, along with a *
* priority for doing it. Like updating the main window is more *
* important than naming a location. The scheduler then manages the *
* queue of items to be processed, and calls each in turn. The queue can *
* be temporarily stopped for low priority items (lower than userrequest *
* priority), this is to enable many of the primary thread dialog boxes *
* to work whilst maintaining window updates and changes *
* Accessing the task list should be covered by critical sections, since *
* either thread can access the list. The other place that critical *
* sections are heavily used is in the display of the main window, and *
* the buffer generation for the main window. *
************************************************************************/
#include <windows.h>
#include "schedule.h"
#include "xref.h"
#include "gname.h"
#include "disasm.h"
#include "data.h"
#include "dasm.h"
#include "mainwind.h"
#include "range.h"
#include "debug.h"
// our internal implementation of the taskitem.
// we have type and priority
// and for each we can also keep an addr, a text string and a number
struct taskitem
{ tasktype ttype;
priority p;
lptr addr;
char *comment;
dword tnum;
};
/************************************************************************
* constructor *
* - simply sets up the thread pause/stop request status *
************************************************************************/
schedule::schedule()
{ threadpause=false;
threadstopped=true;
}
/************************************************************************
* destructor *
* - currently null function *
************************************************************************/
schedule::~schedule()
{
}
/************************************************************************
* addtask *
* - this adds a task to the queue. This function has to be very careful *
* as it can potentially be called by either thread at any time, and *
* so could be called from both threads at almost the same time. *
* So there is a critical section for manipulating the queue of tasks. *
* - added tasktype tt and moved tnumt whilst commenting this function *
* Borg v2.21 for safety! *
************************************************************************/
void schedule::addtask(tasktype ttype,priority p,lptr loc,char *comment)
{ taskitem *titem;
static dword tnumt=0;
tasktype tt;
// limit window updates added to queue - could be called many times by disasm.
if(ttype==windowupdate)
{ EnterCriticalSection(&cs);
titem=peekfirst();
if(titem!=NULL)
tt=titem->ttype;
else
tt=tasktype_null; // zero
LeaveCriticalSection(&cs);
if(tt==windowupdate)
return;
}
titem=new taskitem;
titem->ttype=ttype;
titem->p=p;
titem->addr=loc;
titem->comment=comment;
EnterCriticalSection(&cs);
titem->tnum=tnumt;
tnumt++;
addto(titem);
LeaveCriticalSection(&cs);
}
/************************************************************************
* compare function *
* - the task list is stored in priority order, and then using a uid *
* generated during the add function *
************************************************************************/
int schedule::compare(taskitem *i,taskitem *j)
{ if(i->p==j->p)
{ if(i->tnum==j->tnum)
return 0;
if(i->tnum>j->tnum)
return 1;
return -1;
}
if(i->p>j->p)
return 1;
return -1;
}
/************************************************************************
* delete function *
* - overrides the standard listitem deletion function *
************************************************************************/
void schedule::delfunc(taskitem *i)
{ if(i->comment!=NULL)
delete i->comment;
delete i;
}
/************************************************************************
* process *
* - here we take the item at the front of the task queue and process it *
* - if the queue has been requested to hold then we only process high *
* priority items *
* - more thread safety code added v 2.21 during commenting and closer *
* examination *
************************************************************************/
bool schedule::process(void)
{ taskitem *task;
bool done;
bool procdany;
priority q;
done=false;
procdany=false;
threadstopped=false;
do
{ // our checks for pausing the threads must be thread safe
// accessing the task list must be in a critical section
EnterCriticalSection(&cs);
task=peekfirst();
if(task!=NULL)
q=task->p;
else
q=priority_null; // zero
LeaveCriticalSection(&cs);
if(q>priority_userrequest)
{ while(threadpause)
{ threadstopped=true;
EnterCriticalSection(&cs);
task=peekfirst();
if(task!=NULL)
q=task->p;
else
q=priority_null; // zero
LeaveCriticalSection(&cs);
if(q<priority_userrequest)
break;
Sleep(0);
}
}
threadstopped=false;
EnterCriticalSection(&cs);
// note: processqueue detaches the task from the list and gives it to us
task=processqueue();
LeaveCriticalSection(&cs);
if(task==NULL)
done=true;
else
{ StatusMessageNItems(numlistitems());
procdany=true;
// note - if the routine to be called does not delete any task->comment string then
// it is up to the code here to do it.
switch(task->ttype)
{ case dis_code:
#ifdef DEBUG
DebugMessage("Scheduler:Disassembling Code at : %04lx:%04lx",task->addr.segm,task->addr.offs);
#endif
dsm.disblock(task->addr);
break;
case dis_exportcode:
#ifdef DEBUG
DebugMessage("Scheduler:Disassembling Export Code at : %04lx:%04lx",task->addr.segm,task->addr.offs);
#endif
dsm.disexportblock(task->addr);
break;
case user_makecode:
#ifdef DEBUG
DebugMessage("Scheduler:User Make Code");
#endif
dio.makecode();
break;
case user_undefineline:
#ifdef DEBUG
DebugMessage("Scheduler:User Undefine Line");
#endif
dsm.undefineline();
break;
case user_undefinelines:
#ifdef DEBUG
DebugMessage("Scheduler:User Undefine Lines");
#endif
dsm.undefinelines();
break;
case user_undefinelines_long:
#ifdef DEBUG
DebugMessage("Scheduler:User Undefine Lines Long");
#endif
dsm.undefinelines_long();
break;
case user_jumpback:
#ifdef DEBUG
DebugMessage("Scheduler:User Jump Back");
#endif
dio.jumpback();
break;
case user_jumpto:
#ifdef DEBUG
DebugMessage("Scheduler:User Jump To");
#endif
dio.jumpto(true);
break;
case user_jumptoarg2:
#ifdef DEBUG
DebugMessage("Scheduler:User Jump To (arg2)");
#endif
dio.jumpto(false);
break;
case user_jumptoaddr:
#ifdef DEBUG
DebugMessage("Scheduler:User Jump To Addr");
#endif
dio.savecuraddr();
dio.setcuraddr(task->addr);
break;
case windowupdate:
dio.updatewindow();
break;
case scrolling:
dio.scroller(task->addr.offs);
break;
case vthumbposition:
dio.vertsetpos(task->addr.offs);
break;
case hthumbposition:
horizscrollto(task->addr.offs);
break;
case hscroll: // amount
horizscroll(task->addr.offs);
break;
case user_makedword:
#ifdef DEBUG
DebugMessage("Scheduler:User Make dword");
#endif
dio.makedword();
break;
case user_makesingle:
#ifdef DEBUG
DebugMessage("Scheduler:User Make single real");
#endif
dio.makesingle();
break;
case user_makedouble:
#ifdef DEBUG
DebugMessage("Scheduler:User Make double real");
#endif
dio.makedouble();
break;
case user_makelongdouble:
#ifdef DEBUG
DebugMessage("Scheduler:User Make long double real");
#endif
dio.makelongdouble();
break;
case user_makeword:
#ifdef DEBUG
DebugMessage("Scheduler:User Make Word");
#endif
dio.makeword();
break;
case user_makestring:
#ifdef DEBUG
DebugMessage("Scheduler:User Make String");
#endif
dio.makestring();
break;
case user_pascalstring:
#ifdef DEBUG
DebugMessage("Scheduler:User Pascal String");
#endif
dio.pascalstring();
break;
case user_ucstring:
#ifdef DEBUG
DebugMessage("Scheduler:User Unicode C String");
#endif
dio.ucstring();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -