CoolFace
Datasetpublic

hschumann2/TempleOS-Source-Code

sourceHugging Faceupdated 1y agoView on Hugging Face
0likes838downloads
Job.txt504 linesDownload Raw Back to Kernel
1 2U0 JobDel(CJob *tmpc)3{//Free one cmd node.4  Free(tmpc->aux_str);5  Free(tmpc);6}7 8U0 JobQueDel(CJob *head)9{10  CJob *tmpc=head->next,*tmpc1;11  while (tmpc!=head) {12    tmpc1=tmpc->next;13    QueRem(tmpc);14    JobDel(tmpc);15    tmpc=tmpc1;16  }17}18 19U0 JobCtrlInit(CJobCtrl *ctrl)20{21  QueInit(&ctrl->next_waiting);22  QueInit(&ctrl->next_done);23  ctrl->flags=0;24}25 26U0 TaskRstAwaitingMsg(CTask *task=NULL)27{//Pop-ups get parent messages so wake-up our pop-ups if we got a msg.28  if (!task) task=Fs;29  PUSHFD30  CLI31  do {32    if (TaskValidate(task))33      LBtr(&task->task_flags,TASKf_AWAITING_MSG);34    else35      break;36  } while (task=task->popup_task);37  POPFD38}39 40CJob *TaskExe(CTask *srv,CTask *master,U8 *data,I64 flags)41{//Queues a request to compile and execute src code text.42  CJob *res;43  if (!data || !TaskValidate(srv) || master && !TaskValidate(master) ||44        srv->popup_task && !Bt(&srv->task_flags,TASKf_FILTER_INPUT))45    return NULL;46  res=ACAlloc(sizeof(CJob));47  res->master_task=master;48  res->job_code=JOBT_EXE_STR;49  res->flags=flags;50  res->aux_str=AStrNew(data);51  res->ctrl=&srv->srv_ctrl;52 53  PUSHFD54  CLI55  while (LBts(&srv->srv_ctrl.flags,JOBCf_LOCKED))56    PAUSE57  if (!TaskValidate(srv)) {58    LBtr(&srv->srv_ctrl.flags,JOBCf_LOCKED);59    POPFD60    JobDel(res);61    return NULL;62  } else {63    LBtr(&srv->task_flags,TASKf_IDLE);64    TaskRstAwaitingMsg(srv);65    QueIns(res,srv->srv_ctrl.last_waiting);66    LBtr(&srv->srv_ctrl.flags,JOBCf_LOCKED);67    if (Bt(&flags,JOBf_WAKE_MASTER)) {68      Suspend(master);69      Yield;70    }71  }72  POPFD73  return res;74}75 76CJob *TaskText(CTask *srv,CTask *master,U8 *data,I64 flags)77{//Post StdIn text to servant task. Tell who the master task is.78  CJob *res;79  CTask *task;80  if (!data || !TaskValidate(srv) || master && !TaskValidate(master) ||81        srv->popup_task && !Bt(&srv->task_flags,TASKf_FILTER_INPUT))82    return NULL;83  res=ACAlloc(sizeof(CJob));84  res->master_task=master; //in case somebody cares85  res->job_code=JOBT_TEXT_INPUT;86  res->flags=flags;87  res->aux_str=AStrNew(data);88 89  PUSHFD90  task=srv->last_input_filter_task;91  if (Bt(&flags,JOBf_HIGHEST_PRIORITY) || task==srv) {92    if (task!=srv)93      TaskWait(srv);94    task=Spawn(&InputFilterTask,NULL,"Input Filter",,srv);95    CLI96    task->next_input_filter_task=srv->next_input_filter_task;97    task->last_input_filter_task=srv;98    srv->next_input_filter_task=task;99    task->next_input_filter_task->last_input_filter_task=task;100  } else {101    CLI102    task=srv->next_input_filter_task;103  }104  res->ctrl=&task->srv_ctrl;105  while (LBts(&task->srv_ctrl.flags,JOBCf_LOCKED))106    PAUSE107  if (!TaskValidate(task)) {108    JobDel(res);109    res=NULL;110  } else {111    LBtr(&task->task_flags,TASKf_IDLE);112    TaskRstAwaitingMsg(task);113    QueIns(res,task->srv_ctrl.last_waiting);114    LBtr(&task->srv_ctrl.flags,JOBCf_LOCKED);115  }116  POPFD117  return res;118}119 120CJob *TaskMsg(CTask *_srv,CTask *master,121        I64 msg_code,I64 arg1,I64 arg2,I64 flags)122{//Post message to servant task.  Tell who the master task is.123//See flags and msg_code.124  CJob *tmpc1,*tmpc;125  CTask *srv=_srv;126  if (!TaskValidate(srv) || master && !TaskValidate(master)||127        srv->popup_task && !Bt(&srv->task_flags,TASKf_FILTER_INPUT))128    return NULL;129  tmpc=ACAlloc(sizeof(CJob));130  tmpc->master_task=master;131  tmpc->job_code=JOBT_MSG;132  tmpc->msg_code=AbsI64(msg_code); //negative means do a down and up133  tmpc->aux1=arg1;134  tmpc->aux2=arg2;135  tmpc->flags=flags;136  PUSHFD137  if (Bt(&sys_semas[SEMA_RECORD_MACRO],0) &&138        srv!=sys_macro_task && msg_code==MSG_KEY_DOWN) {139    tmpc1=AMAllocIdent(tmpc);140    CLI141    QueIns(tmpc1,sys_macro_head.last);142  }143  CLI144  while (Bt(&srv->task_flags,TASKf_FILTER_INPUT) &&145        !Bt(&flags,JOBf_DONT_FILTER))146    srv=srv->next_input_filter_task;147  tmpc->ctrl=&srv->srv_ctrl;148  while (LBts(&srv->srv_ctrl.flags,JOBCf_LOCKED))149    PAUSE150  if (!TaskValidate(srv)) {151    JobDel(tmpc);152    tmpc=NULL;153  } else {154    LBtr(&srv->task_flags,TASKf_IDLE);155    TaskRstAwaitingMsg(srv);156    QueIns(tmpc,srv->srv_ctrl.last_waiting);157    LBtr(&srv->srv_ctrl.flags,JOBCf_LOCKED);158  }159  POPFD160  if (msg_code<0) //Down-Up161    TaskMsg(_srv,master,-msg_code+1,arg1,arg2,flags);162  return tmpc;163}164 165Bool JobResScan(CJob *rqst=NULL,I64 *_res=NULL)166{//Check rqst complete, return with or without.167  CJobCtrl *ctrl;168  CJob *tmpc,*tmpc1;169  if (!rqst || Bt(&rqst->flags,JOBf_DONE)) {170    if (!rqst || rqst->master_task)171      ctrl=&Fs->srv_ctrl;172    else173      ctrl=rqst->ctrl;174    PUSHFD175    CLI176    while (LBts(&ctrl->flags,JOBCf_LOCKED))177      PAUSE178    tmpc1=&ctrl->next_done;179    tmpc=tmpc1->next;180    while (tmpc!=tmpc1) {181      if (!rqst || rqst==tmpc) {182        QueRem(tmpc);183        LBtr(&ctrl->flags,JOBCf_LOCKED);184        POPFD185        if (_res)186          *_res=tmpc->res;187        JobDel(tmpc);188        return TRUE;189      }190      tmpc=tmpc->next;191    }192    LBtr(&ctrl->flags,JOBCf_LOCKED);193    POPFD194  }195  if (_res)196    *_res=0;197  return FALSE;198}199 200I64 JobResGet(CJob *rqst=NULL)201{//See ::/Demo/MultiCore/Lock.HC202  I64 res;203  CJob *tmpc1;204  if (!rqst) {205    tmpc1=&Fs->srv_ctrl.next_done;206    while (tmpc1==tmpc1->next) {207      LBts(&Fs->task_flags,TASKf_IDLE);208      Yield;209    }210  } else {211    while (!Bt(&rqst->flags,JOBf_DONE)) {212      LBts(&Fs->task_flags,TASKf_IDLE);213      Yield;214    }215  }216  LBtr(&Fs->task_flags,TASKf_IDLE);217//Could get taken by someone else.218  JobResScan(rqst,&res);219  return res;220}221 222U0 TaskWait(CTask *task=NULL,Bool cmd_line_pmt=FALSE)223{//Wait for idle.224  CTask *task1;225  CJob *tmpc1;226  if (!task) task=Fs;227  if (TaskValidate(task)) {228    PUSHFD229    CLI230    while (TRUE) {231      task1=task->last_input_filter_task;232      tmpc1=&task1->srv_ctrl.next_waiting;233      if (task1==Fs || !TaskValidate(task1) ||234            tmpc1==tmpc1->next && Bt(&task1->task_flags,TASKf_IDLE) &&235            (!cmd_line_pmt || Bt(&task1->task_flags,TASKf_CMD_LINE_PMT)))236        break;237      Yield;238    }239    POPFD240  }241}242 243U0 PostMsg(CTask *task,I64 msg_code,I64 arg1,I64 arg2,I64 flags=0)244{//Post message to a task and return immediately.  See msg_code.245  if (TaskValidate(task)) {246    if (Bt(&task->task_flags,TASKf_INPUT_FILTER_TASK))247      TaskMsg(task->last_input_filter_task,NULL,msg_code,arg1,arg2,248            flags|1<<JOBf_DONT_FILTER);249    else250      TaskMsg(task,NULL,msg_code,arg1,arg2,flags);251  }252}253 254U0 PostMsgWait(CTask *task,I64 msg_code,I64 arg1,I64 arg2,I64 flags=0)255{//Post message to a task and wait until task is idle.See msg_code.256  PostMsg(task,msg_code,arg1,arg2,flags);257  TaskWait(task);258}259 260U0 Msg(I64 msg_code,I64 arg1,I64 arg2,I64 flags=0)261{//Post message to current task and return immediately.262//See msg_code.263  PostMsg(Fs,msg_code,arg1,arg2,flags);264}265 266#define JOB_DONE        0267#define JOB_CONT        1268#define JOB_EXIT        2269 270I64 JobRunOne(I64 run_flags,CJobCtrl *ctrl)271{//Called with ctrl->flags,JOBCf_LOCKED.272  CJob *tmpc=ctrl->next_waiting;273  CTask   *master;274  I64 res,flags=tmpc->flags,old_flags=GetRFlags;275  if (Bt(&flags,JOBf_EXIT_ON_COMPLETE))276    res=JOB_EXIT;277  else278    res=JOB_CONT;279  switch (tmpc->job_code) {280    case JOBT_SPAWN_TASK:281      QueRem(tmpc);282      LBts(&tmpc->flags,JOBf_DISPATCHED);283      LBtr(&ctrl->flags,JOBCf_LOCKED);284      if (tmpc->aux_str)285        tmpc->spawned_task=Spawn(tmpc->addr,tmpc->fun_arg,286              tmpc->aux_str,,tmpc->aux1,tmpc->aux2,tmpc->flags);287      else288        tmpc->spawned_task=Spawn(tmpc->addr,tmpc->fun_arg,289              "Unnamed",,tmpc->aux1,tmpc->aux2,tmpc->flags);290      break;291    case JOBT_CALL:292      QueRem(tmpc);293      LBts(&tmpc->flags,JOBf_DISPATCHED);294      LBtr(&ctrl->flags,JOBCf_LOCKED);295      SetRFlags(run_flags);296      LBtr(&Fs->task_flags,TASKf_IDLE);297      try298              tmpc->res=(*tmpc->addr)(tmpc->fun_arg);299      catch300        Fs->catch_except=TRUE;301      SetRFlags(old_flags);302      break;303    case JOBT_EXE_STR:304      QueRem(tmpc);305      LBts(&tmpc->flags,JOBf_DISPATCHED);306      LBtr(&ctrl->flags,JOBCf_LOCKED);307      SetRFlags(run_flags);308      LBtr(&Fs->task_flags,TASKf_IDLE);309      try310              tmpc->res=ExePrint("%s",tmpc->aux_str);311      catch312        Fs->catch_except=TRUE;313      SetRFlags(old_flags);314      break;315    default:316      res=JOB_DONE;317  }318  if (res) {319    if (master=tmpc->master_task) {320      if (!Bt(&flags,JOBf_FREE_ON_COMPLETE)) {321        CLI322        while (LBts(&master->srv_ctrl.flags,JOBCf_LOCKED))323          PAUSE324        QueIns(tmpc,master->srv_ctrl.last_done);325        LBts(&tmpc->flags,JOBf_DONE);326        LBtr(&master->srv_ctrl.flags,JOBCf_LOCKED);327        SetRFlags(old_flags);328      }329      if (Bt(&flags,JOBf_FOCUS_MASTER) &&330            !Bt(&master->win_inhibit,WIf_SELF_FOCUS))331        sys_focus_task=master;332      if (Bt(&flags,JOBf_WAKE_MASTER))333        Suspend(master,FALSE);334    }335    if (Bt(&flags,JOBf_FREE_ON_COMPLETE))336      JobDel(tmpc);337    else if (!master) {338      CLI339      while (LBts(&ctrl->flags,JOBCf_LOCKED))340        Yield;341      QueIns(tmpc,ctrl->last_done);342      LBts(&tmpc->flags,JOBf_DONE);343      LBtr(&ctrl->flags,JOBCf_LOCKED);344      SetRFlags(old_flags);345    }346  }347  return res;348}349 350I64 JobsHndlr(I64 run_flags,CTask *task=NULL)351{//Handle all waiting cmds and return.352  I64 cnt=0,old_flags=GetRFlags;353  if (!task) task=Fs;354  while (TRUE) {355    CLI356    while (LBts(&task->srv_ctrl.flags,JOBCf_LOCKED))357      PAUSE358    if (task->srv_ctrl.next_waiting!=&task->srv_ctrl)359      switch (JobRunOne(run_flags,&task->srv_ctrl)) {360        case JOB_CONT:361          cnt++;362          break;363        case JOB_EXIT:364          Exit;365        case JOB_DONE:366          goto jh_done;367      }368    else369      goto jh_done;370  }371jh_done:372  LBtr(&task->srv_ctrl.flags,JOBCf_LOCKED);373  SetRFlags(old_flags);374  return cnt;375}376 377I64 PopUp(U8 *buf,CTask *parent=NULL,CTask **_pu_task=NULL)378{//Execute code in PopUp task.379  I64 res;380  CJob *tmpc;381  CTask *task=Spawn(&SrvCmdLine,NULL,"Servant",,parent);382  if (!parent) {383    TaskExe(task,parent,buf,1<<JOBf_EXIT_ON_COMPLETE|1<<JOBf_FREE_ON_COMPLETE);384    if (_pu_task) *_pu_task=task;385    return 0;386  } else {387    Fs->popup_task=task;388    tmpc=TaskExe(task,parent,buf,1<<JOBf_WAKE_MASTER|1<<JOBf_FOCUS_MASTER);389    if (_pu_task) *_pu_task=task;390    JobResScan(tmpc,&res);391    Fs->popup_task=NULL;392    Kill(task);393    if (_pu_task) *_pu_task=NULL;394    return res;395  }396}397 398I64 PopUpPrint(U8 *fmt,...)399{//Execute code in PopUp task.400  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);401  I64 res;402  res=PopUp(buf,Fs);403  Free(buf);404  return res;405}406 407I64 Adam(U8 *fmt,...)408{//Make adam_task execute code.409  I64 res;410  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);411  CJob *tmpc;412  if (Fs==adam_task) {413    tmpc=TaskExe(adam_task,Fs,buf,0);414    JobsHndlr(GetRFlags);415  } else {416    TaskWait(adam_task);417    tmpc=TaskExe(adam_task,Fs,buf,1<<JOBf_WAKE_MASTER);418  }419  JobResScan(tmpc,&res);420  Free(buf);421  return res;422}423 424U0 AdamLog(U8 *fmt,...)425{//Display text in adam_task.426  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);427  if (Fs==adam_task)428    "%s",buf;429  else if (!IsSingleUser)430    Adam("\"%%s\",%d;",buf);431  Free(buf);432}433 434U0 AdamErr(U8 *fmt,...)435{//Display red blinking Err text in adam_task.436  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv),437        *st=MStrPrint(ST_ERR_ST "%s",buf);438  if (Fs==adam_task)439    "%s",st;440  else if (!IsSingleUser)441    Adam("\"%%s\",%d;",st);442  Free(st);443  Free(buf);444}445 446U0 XTalk(CTask *task,U8 *fmt,...)447{//Sends text to other task. See ::/Misc/OSTestSuite.HC.448  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv),*st=AStrNew(buf),449        *st2=MStrPrint("\"%%s\",%d;Free(%d);",st,st);450  TaskText(task,NULL,st2,0);451  Free(st2);452  Free(buf);453}454 455U0 XTalkWait(CTask *task,U8 *fmt,...)456{//Send text to other task and wait for it to idle.457  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv),*st=AStrNew(buf),458        *st2=MStrPrint("\"%%s\",%d;Free(%d);",st,st);459  TaskText(task,NULL,st2,0);460  Free(st2);461  Free(buf);462  TaskWait(task);463}464 465U0 InStr(U8 *fmt,...)466{//Send InFile code to self.467  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);468  if (Bt(&Fs->task_flags,TASKf_INPUT_FILTER_TASK))469    ExePrint("%s",buf);470  else471    TaskText(Fs,NULL,buf,1<<JOBf_HIGHEST_PRIORITY);472  Free(buf);473}474 475U0 InFile(U8 *filename)476{//Send InFile code file to self.477  U8 *name=ExtDft(filename,"IN.Z");478  InStr("Cd(\"%C:%s\");;#include \"%s\"",479        Drv2Let(Fs->cur_dv),Fs->cur_dir,name);480  Free(name);481}482 483U0 In(U8 *fmt,...)484{//Send text to own input buffer. See ::/Demo/AcctExample/TOS/TOSDistro.HC.485  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv),*st=AStrNew(buf);486  InStr("\"%%s\",%d;Free(%d);",st,st);487  Free(buf);488}489 490U0 XTalkStr(CTask *task,U8 *fmt,...)491{//Send InFile code to other task.492  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);493  TaskText(task,NULL,buf,0);494  Free(buf);495}496 497U0 XTalkStrWait(CTask *task,U8 *fmt,...)498{//Send InFile code to other task and wait for it to idle.499  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);500  TaskText(task,NULL,buf,0);501  Free(buf);502  TaskWait(task);503}504