The fork system call

The pseudo code:

 do_fork()
    {
     Increment number of the tasks, we gOT one more;
     The new task is ready to run.
     Copy the whole TCB.
     Copy the whole tcb (task control block), wich contains all hw- related things as registers
     to the new task;
     CHANGE RETURN PARAMETER TO THE CHILD PROCESS ( reg r8)
     SET tlb tr info for the new task's backing strore area.
     Backing store must always have translation virtual-> physical. Can't use fault as the rest of the system (demand paging).

     loop(parent's all page table entries)
      {
       if (parent alreday accessed the page)
          {
           Icrement gobal physicl block pointer.
           Copy the PYSICAL page for children.
           Update child's page table (The new pages needed come from "the disc"- simulated as needed)
          }
      }
          
   
    Return to the middle of the context switch- branch by flag, BAD PROGRAMMING STYLE, SEE EXERCISES
 }

A parent and child differ from each other by athe return value. I use for the parent 1944 (my birth year) and for the child 1972, my son's bith year.

register char * f_ptr                      __asm__("r4"); //         These are "caller saved" registers, gcc do not use then RSE when it needs more registers!
register char * old_ptr                  __asm__("r5");
register char * f_ptr_T                  __asm__("r6");
register char * old_ptr_T              __asm__("r7");

//_____________________
void do_fork(void){

        fork_flag=0;
        old_ptr       = (char *)tcb_ptr[found];
        f_ptr          = (char *)tcb_ptr[MAXTASK];
        old_ptr_T   = (char *)TCB_ptr[found];
        f_ptr_T       = (char *)TCB_ptr[MAXTASK];//+1!!!!!!!!!!!!!!              
        F_ptr          = (struct tcb_type *)f_ptr;
        O_ptr          = (struct tcb_type *)old_ptr;        

         for (count=0;count <  STCB;count++) // Copy TCB to new task (Task Control Block)
                      *f_ptr_T++ =  *old_ptr_T++;   
         ++MAXTASK;                                        //Now we have one more task
        _ready_             = _ready_ | (1 << MAXTASK-1); //And the new task is ready to run
         message=0x1944;//Return value for the original task
         for (count=0;count <  Stcb;count++) //Copy whole tcb (HW state, registers)
               *f_ptr++ =  *old_ptr++;
          F_ptr->GRs_r01_r15[7]=0x1972; //Return value  for the new task.  THE COPIED CONTENTS IS NOT GOOD AS TO RETURN VALUE      
          F_ptr->flag         = 0xa;
          F_ptr->rse_idrt    = (F_ptr->rse_idrt & 0xffffffffff000fff ) | ((long)(next_block+0x200)) ; //NEW TLB transalation info to  for backing store   
         for(iDsize=0;iDsize< MAXPAGES;iDsize++) //Make new physical copy for the child task/ every accessed data page of the parent
          {
          d_ptr = (long *)(PHYS_data[found][iDsize]) ;
         if((long)(d_ptr) !=0)
                 {
                       next_block  += 0x200;
                       new_d_ptr   =next_block;
                       or(r=0;r< 0x200;r++ )//Copy the data segment including backing storage
                                     *new_d_ptr++= *d_ptr++;
             PHYS_data[MAXTASK-1][iDsize]=(long)next_block ;  //Update child's page table                  
                }
         }
        __asm__("br.sptk.few b7;");
       
}