The fork system call

The pseudo code:

     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;
     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){

        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;");