Team Ai
Datasetpublic

hschumann2/TempleOS-Source-Code

sourceHugging Faceupdated 1y agoView on Hugging Face
0likes847downloads
KTask.txt547 linesDownload Raw Back to Kernel
1 2U0 Exit()3{//Terminate own task.4  if (Fs==sys_focus_task && IsDbgMode) {5    LBts(&Fs->task_flags,TASKf_KILL_AFTER_DBG);6    G;7  } else {8    if (sys_staff_mode_flag)9      AdamLog("%p:%p:%p:%p:%p:%p\n",Caller(0),Caller(1),Caller(2),Caller(3),10            Caller(4),Caller(5),Caller(6),Caller(7));11    if (!Gs->num && !IsDbgMode)12      SingleUser(OFF);13    Fs->rflags=GetRFlags;14    Fs->rsp=GetRSP;15    Fs->rbp=GetRBP;16    Fs->rip=$;17    CLI18    LBts(&Fs->task_flags,TASKf_KILL_TASK);19    TaskEndNow;20  }21}22 23Bool TaskValidate(CTask *task)24{//return TRUE if task looks valid.25  if (!(0<task<=I32_MAX) || task->addr!=task ||26        task->task_signature!=TASK_SIGNATURE_VAL)27    return FALSE;28  else29    return TRUE;30}31 32I64 BirthWait(CTask **_task,I64 task_num=-1)33{//Wait for task valid and not task_num.34  while (!TaskValidate(*_task)||(*_task)->task_num==task_num)35    Yield;36  return (*_task)->task_num;37}38 39U0 DeathWait(CTask **_task,Bool send_exit=FALSE)40{//Wait for task death.41  if (send_exit && TaskValidate(*_task)) {42    TaskWait(*_task,TRUE);43    XTalk(*_task,"Exit;\n");44  }45  while (TaskValidate(*_task))46    Yield;47}48 49Bool Kill(CTask *task,Bool wait=TRUE,Bool just_break=FALSE)50{//Terminate other task.51  I64 i;52  if (TaskValidate(task)) {53    if (just_break) {54      if (task!=Fs)55        Break;56      else {//TODO wait57        sys_focus_task=task;58        LBts(sys_ctrl_alt_flags,CTRL_ALT_C);59        return TRUE;60      }61    } else {62      if (task!=sys_winmgr_task) {63        for (i=0;i<mp_cnt;i++)64          if (task==cpu_structs[i].seth_task)65            return FALSE;66        LBts(&task->task_flags,TASKf_KILL_TASK);67        if (wait) {68          do Yield;69          while (TaskValidate(task) && Bt(&task->task_flags,TASKf_KILL_TASK));70        }71        return TRUE;72      }73    }74  }75  return FALSE;76}77 78Bool Suspend(CTask *task=NULL,Bool state=TRUE)79{//Tell scheduler to skip task.80  Bool res;81  if (!task) task=Fs;82  PUSHFD83  CLI84  if (TaskValidate(task))85    res=LBEqu(&task->task_flags,TASKf_SUSPENDED,state);86  else87    res=FALSE;88  POPFD89  return res;90}91 92Bool IsSuspended(CTask *task=NULL)93{//You might use this in a DrawIt() or Animatetask().94  if (!task) task=Fs;95  if (TaskValidate(task))96    return Bt(&task->task_flags,TASKf_SUSPENDED);97  else98    return FALSE;99}100 101CTaskStk *TaskStkNew(I64 stk_size,CTask *task)102{103  CTaskStk *tmps=MAlloc(stk_size+offset(CTaskStk.stk_base),task);104  tmps->next_stk=NULL;105  tmps->stk_ptr=NULL;106  tmps->stk_size=MSize(tmps)-offset(CTaskStk.stk_base);107  return tmps;108}109 110#exe {Option(OPTf_NO_REG_VAR,ON);};111argpop I64 CallStkGrow(I64 stk_size_threshold,I64 stk_size,112                        /*argpop*/I64 (*fp_addr)(...),...)113{//Grow stk in call with any fixed num of args.114//See ::/Demo/StkGrow.HC.115  CTaskStk *tmps,*tmps2,**_stk;116  I64 res,*rsp,*rsp2,*old_stk;117 118  if (UnusedStk>=stk_size_threshold) {119 120    asm {121      LEAVE122      POP       RAX     //return addr123      ADD       RSP,16  //pop threshold,stk_size124      POP       RBX     // *f125      ADD       RSP,8   //pop ARGC126      PUSH      RAX127      JMP       RBX     //CALL fp_addr()128    };129 130  } else {131 132    tmps2=TaskStkNew(stk_size,Fs);133    tmps2->next_stk=tmps=Fs->stk;134    rsp2=(&tmps2->stk_base)(U8 *)+tmps2->stk_size;135    old_stk=rsp=&argv[argc];136    while (argc-->0)137      *--rsp2=*--rsp;138    _stk=&Fs->stk;139    tmps->stk_ptr=rsp=GetRSP;140    asm {141      IMPORT    _FREE;  //We are in a function, not at glbl scope.142//The compiler treats these in isolation.143 144      PUSHFD145      POP       RDX     //flags146      CLI147      MOV       RBX,U64 &tmps2[RBP]148      MOV       RAX,&_stk[RBP]149      MOV       U64 [RAX],RBX   //Fs->stk=tmps2150      MOV       RSP,U64 &rsp2[RBP]151      PUSH      RDX152      POPFD153 154      CALL      U64 &fp_addr[RBP]155      MOV       U64 &res[RBP],RAX156 157      PUSHFD158      POP       RDX     //flags159      CLI160      MOV       RBX,U64 &tmps[RBP]161      MOV       RAX,&_stk[RBP]162      MOV       U64 [RAX],RBX   //Fs->stk=tmps163      MOV       RSP,U64 &rsp[RBP]164      PUSH      RDX165      POPFD166 167      PUSH      U64 &tmps2[RBP]168      CALL      _FREE169 170      MOV       RDX,U64 &old_stk[RBP]171      MOV       RBX,U64 8[RBP]172      MOV       RAX,U64 &res[RBP]173      MOV       RBP,U64 [RBP]174      MOV       RSP,RDX175      JMP       RBX     //return176    };177  }178  return 0; //dummy to get rid of warning179}180;181#exe {Option(OPTf_NO_REG_VAR,OFF);};182 183I64 TaskInit(CTask *task,I64 stk_size)184{//Returns Fs of task185  CTaskStk *tmps;186 187  QueInit(&task->code_heap->next_mem_blk);188  task->code_heap->last_mergable=NULL;189  if (task->code_heap!=task->data_heap) {190    QueInit(&task->data_heap->next_mem_blk);191    task->data_heap->last_mergable=NULL;192  }193 194  task->addr=task->next_task=task->last_task=195        task->next_input_filter_task=task->last_input_filter_task=196        task;197 198  task->task_num=sys_num_spawned_tasks++;199 200  task->rflags=RFLAGG_NORMAL;201  task->win_inhibit=WIG_TASK_DFT;202 203  task->next_child_task=task->last_child_task=204        (&task->next_child_task)(U8 *)-offset(CTask.next_sibling_task);205 206  JobCtrlInit(&task->srv_ctrl);207  QueInit(&task->next_cc);208  QueInit(&task->next_except);209  QueInit(&task->next_ctrl);210  QueInit(&task->next_ode);211 212  task->fpu_mmx=MAllocAligned(sizeof(CFPU),0x10,task);213  MemCpy(task->fpu_mmx,214        SYS_FIXED_AREA+offset(CSysFixedArea.init_fpu_mmx),sizeof(CFPU));215 216  task->hash_table=HashTableNew(TASK_HASH_TABLE_SIZE,task);217 218  if (!stk_size)219    stk_size=MEM_DFT_STK;220  task->stk=tmps=TaskStkNew(stk_size,task);221  task->rsp=(&tmps->stk_base)(U8 *)+tmps->stk_size;222 223  task->text_attr       =WHITE<<4+BLUE;224  task->border_src      =BDS_CONST;225  task->border_attr     =DrvTextAttrGet(':');226  task->title_src       =TTS_CONST;227  task->win_left        =1;228  task->win_right       =text.cols-2;229  task->win_top         =13;230  task->win_bottom      =text.rows-2;231 232  if (blkdev.home_dir) {//Beware Adam TaskInit. I guess ok until DskChg().233    task->cur_dv=blkdev.let_to_drv[*blkdev.home_dir-'A'];234    task->cur_dir=StrNew(blkdev.home_dir+2,task);235  } else236    task->cur_dir=StrNew("/Home",task);237 238  Seed(,task);239 240  return task;241}242 243CTask *Spawn(U0 (*fp_start_addr)(U8 *data),U8 *data=NULL,U8 *task_name=NULL,244        I64 target_cpu=-1,      //-1 for current CPU. See multi-core.245        CTask *parent=NULL,     //NULL means adam246        I64 stk_size=0,         //0=default247        I64 flags=1<<JOBf_ADD_TO_QUE)248{//Create task on core running at address.249//Alloc CTask structure from code heap so addr will be short.250  //Could be alloced off of data heap.251  CTask *task;252  if (target_cpu>=0)253    return SpawnQue(fp_start_addr,data,task_name,target_cpu,254          parent,stk_size,flags);255  task=CAlloc(sizeof(CTask),adam_task->code_heap);256  task->task_signature=TASK_SIGNATURE_VAL;257  if (!task_name) task_name="Unnamed Task";258  if (!parent) parent=Gs->seth_task;259  task->parent_task=parent;260  task->gs=parent->gs;261  if (sys_code_bp)262    task->code_heap=HeapCtrlInit(,task,sys_code_bp);263  if (sys_data_bp)264    task->data_heap=HeapCtrlInit(,task,sys_data_bp);265  else266    task->data_heap=task->code_heap;267  TaskInit(task,stk_size);268  task->rip=fp_start_addr;269  task->rsp(U8 *)-=8;270  *task->rsp=data;271  task->rsp(U8 *)-=8;272  *task->rsp=&Exit;273  task->hash_table->next=parent->hash_table;274  MemCpy(task->task_name,task_name,TASK_NAME_LEN);275  StrCpy(task->task_title,task->task_name);276  task->title_src=TTS_TASK_NAME;277  PUSHFD278  CLI279  if (Bt(&flags,JOBf_ADD_TO_QUE)) {280    TaskQueInsChild(task);281    TaskQueIns(task);282  }283  POPFD284  return task;285}286 287U0 TaskDerivedValsUpdate(CTask *task=NULL,Bool update_z_buf=TRUE)288{//Those things calculated from other variables.289  if (!task) task=Fs;290  PUSHFD291  CLI292  while (LBts(&task->task_flags,TASKf_TASK_LOCK))293    PAUSE294  WinDerivedValsUpdate(task);295  if (fp_update_ctrls)296    (*fp_update_ctrls)(task);297  if (update_z_buf && Bt(&task->display_flags,DISPLAYf_SHOW))298    LBts(&sys_semas[SEMA_UPDATE_WIN_Z_BUF],0);299  LBtr(&task->task_flags,TASKf_TASK_LOCK);300  POPFD301}302 303I64 ExeCmdLine(CCmpCtrl *cc)304{//Terminal JIT-compile-and-execute loop for CCmpCtrl.305  I64 res=0,type,old_title_src=Fs->title_src;306  U8 *ptr,*ptr2,*ptr3,*machine_code,*old_task_title=StrNew(Fs->task_title);307  F64 t0;308  CDocEntry *doc_e;309  CDoc *doc;310  if (Fs->title_src!=TTS_LOCKED_CONST)311    Fs->title_src=TTS_CUR_LEX;312  while (cc->token &&313        (cc->token!='}' || !(cc->flags & CCF_EXE_BLK)) ) {314    if (Fs->title_src==TTS_CUR_LEX) {315      ptr2=&Fs->task_title;316      ptr3=ptr2+STR_LEN-1;317      if (cc->lex_include_stk->flags & LFSF_DOC) {318        doc_e=cc->lex_include_stk->cur_entry;319        doc=cc->lex_include_stk->doc;320        while (doc_e!=doc && ptr2<ptr3) {321          switch (doc_e->type_u8) {322            case DOCT_TEXT:323              ptr=doc_e->tag;324              while (*ptr && ptr2<ptr3)325                *ptr2++=*ptr++;326              break;327            case DOCT_TAB:328            case DOCT_NEW_LINE:329              *ptr2++='.';330              break;331          }332          doc_e=doc_e->next;333        }334        if (ptr2<ptr3) *ptr2=0;335      } else336        if ((ptr=cc->lex_include_stk->line_start) && *ptr)337          MemCpy(ptr2,ptr,STR_LEN-1);338    }339    cc->flags&=~CCF_HAS_MISC_DATA;340    machine_code=LexStmt2Bin(cc,&type);341    if (machine_code!=INVALID_PTR) {342      if (!(cc->flags&CCF_JUST_LOAD)) {343        t0=tS;344        res=Call(machine_code);345        Fs->answer=res;346        Fs->answer_type=type;347        Fs->answer_time=tS-t0;348        Fs->new_answer=TRUE;349        cc->pmt_line=0;350      }351      if (!(cc->flags&CCF_HAS_MISC_DATA))352        Free(machine_code);353    }354  }355  if (Fs->title_src!=TTS_LOCKED_CONST) {356    Fs->title_src=old_title_src;357    StrCpy(Fs->task_title,old_task_title);358  }359  Free(old_task_title);360  if (cc->flags&CCF_JUST_LOAD) {361    if (cc->error_cnt)362      return FALSE;363    else364      return TRUE;365  } else366    return res;367}368 369U0 SrvTaskCont()370{//Act as server task in a loop handling commands.371  I64 old_flags=GetRFlags;372  FlushMsgs;373  while (TRUE) {374    CLI375    if (JobsHndlr(old_flags) && Fs->title_src==TTS_TASK_NAME)376      MemCpy(Fs->task_title,Fs->task_name,TASK_NAME_LEN);377    FlushMsgs;378    LBts(&Fs->task_flags,TASKf_IDLE);379    LBts(&Fs->task_flags,TASKf_AWAITING_MSG);380    Yield;381    SetRFlags(old_flags);382  }383}384 385U0 UserTaskCont()386{//Terminal key-input-execute loop.387  CCmpCtrl *cc;388  CDoc *doc;389  Bool cont=TRUE;390  do {391    cc=CmpCtrlNew(,CCF_CMD_LINE|CCF_PMT|CCF_QUESTION_HELP);392    QueIns(cc,Fs->last_cc);393    try {394      Lex(cc);395      ExeCmdLine(cc);396      cont=Bt(&cc->flags,CCf_PMT);397      QueRem(cc);398      CmpCtrlDel(cc);399    } catch {400      if ((doc=Fs->put_doc) && doc->doc_signature==DOC_SIGNATURE_VAL)401        DocUnlock(doc);402      PutExcept;403    }404  } while (cont);405}406 407U0 SrvCmdLine(I64 dummy=0)408{409  no_warn dummy;410  Fs->win_inhibit=WIG_USER_TASK_DFT;411  CallExtStr("SrvStartUp");412  SrvTaskCont;413}414 415U0 UserCmdLine(I64 dummy=0)416{//A user task ends-up calling this.417  no_warn dummy;418  Fs->win_inhibit=WIG_USER_TASK_DFT;419  CallExtStr("UserStartUp");420  if (!LBts(&Fs->display_flags,DISPLAYf_SHOW))421    Dbg;422  UserTaskCont;423}424 425CTask *User(U8 *fmt=NULL,...)426{//Create user term task.427  U8 *st;428  CTask *task=Spawn(&UserCmdLine);429  TaskWait(task);430  if (fmt) {431    st=StrPrintJoin(NULL,fmt,argc,argv);432    XTalk(task,st);433    Free(st);434  }435  return task;436}437 438U0 TaskDel(CTask *task)439{//We delay freeing in case lingering ptr to reincarnated.440  HeapCtrlDel(task->code_heap);441  if (task->data_heap!=task->code_heap)442    HeapCtrlDel(task->data_heap);443  Free(task);444}445 446I64 TaskEnd()447{//Called with irq's off.448  CTask *task=Fs,*tmpt,*tmpt1;449  if (task==sys_task_being_scrn_updated) {450    LBts(&task->task_flags,TASKf_KILL_TASK);451    return task->next_task;452  }453  if (task->task_end_cb) {454    task->wake_jiffy=0;455    LBtr(&task->task_flags,TASKf_KILL_TASK);456    TaskRstAwaitingMsg(task);457    Suspend(task,FALSE);458    task->rip=task->task_end_cb;459    task->task_end_cb=NULL;460    return task;461  }462  if (task->parent_task && task->parent_task->popup_task==task) {463    task->parent_task->popup_task=NULL;464    Kill(task->parent_task,FALSE);465    return task->parent_task;466  }467 468  DrvsRelease;469  BlkDevsRelease;470  tmpt1=(&task->next_child_task)(U8 *)-offset(CTask.next_sibling_task);471  tmpt=tmpt1->next_sibling_task;472  if (tmpt!=tmpt1) {473    do {474      LBts(&tmpt->task_flags,TASKf_KILL_TASK);475      tmpt=tmpt->next_sibling_task;476    } while (tmpt!=tmpt1);477    return task->next_task;478  }479  if (LBtr(&task->display_flags,DISPLAYf_SHOW))480    LBts(&sys_semas[SEMA_UPDATE_WIN_Z_BUF],0);481 482  while (LBts(&task->task_flags,TASKf_TASK_LOCK))483    PAUSE484  while (LBts(&task->srv_ctrl.flags,JOBCf_LOCKED))485    PAUSE486 487  JobQueDel(&task->srv_ctrl.next_waiting);488  JobQueDel(&task->srv_ctrl.next_done);489 490  if (IsRaw)491    VGAFlush;492 493  if (sys_focus_task==task) {494    if (!Gs->num)495      SingleUser(OFF);496    sys_focus_task=NULL;497    if (fp_set_std_palette)498      (*fp_set_std_palette)();499  }500 501  //QueRem502  task->task_signature(I64)=0;503 504  tmpt =task->next_input_filter_task;505  tmpt1=task->last_input_filter_task;506  tmpt1->next_input_filter_task=tmpt;507  tmpt ->last_input_filter_task=tmpt1;508 509  tmpt =task->next_sibling_task;510  tmpt1=task->last_sibling_task;511  tmpt1->next_sibling_task=tmpt;512  tmpt ->last_sibling_task=tmpt1;513 514  tmpt =task->next_task; //save to return515  TaskQueRem(task);516 517  LBtr(&task->srv_ctrl.flags,JOBCf_LOCKED);518  LBtr(&task->task_flags,TASKf_TASK_LOCK);519 520  task->wake_jiffy=cnts.jiffies+DYING_JIFFIES;521  while (LBts(&Gs->cpu_flags,CPUf_DYING_TASK_QUE))522    PAUSE523  QueIns(task,Gs->last_dying);524  LBtr(&Gs->cpu_flags,CPUf_DYING_TASK_QUE);525 526  return tmpt;527}528 529U0 TaskKillDying()530{//Delay freeing to prevent asking for trouble with quick reincarnations.531//What if the user is doing this: DoTreeCheckers.532  CTaskDying *task,*task1;533  if (Gs->kill_jiffy<cnts.jiffies) {//Avoid doing as many lock operations.534    while (LBts(&Gs->cpu_flags,CPUf_DYING_TASK_QUE))535      PAUSE536    task=Gs->next_dying;537    while (task!=&Gs->next_dying && task->wake_jiffy<cnts.jiffies) {538      task1=task->next;539      QueRem(task);540      TaskDel(task);541      task=task1;542    }543    LBtr(&Gs->cpu_flags,CPUf_DYING_TASK_QUE);544    Gs->kill_jiffy=cnts.jiffies+DYING_JIFFIES;545  }546}547