[text] kjglkg

Viewer

  1. thread_yield should suspend the calling thread and run the thread with
  2.  * identifier tid. The calling thread is put in the ready queue. tid can be
  3.  * identifier of any avable thread or the following constants:ila
  4.  *
  5.  * THREAD_ANY:           run any thread in the ready queue.
  6.  
  7.  *
  8.  * Upon success, return the identifier of the thread that ran. The calling
  9.  * thread does not see this result until it runs later.  */
  10.  
  11. Tid
  12. thread_yield(Tid want_tid)
  13. {
  14.      int interrupt_enabled = interrupts_set(0);
  15.     //THREAD_INVALID: identifier tid does not correspond to a valid thread.
  16.     if (want_tid < -2 || want_tid >= THREAD_MAX_THREADS){
  17.         interrupts_set(interrupt_enabled);
  18.         return THREAD_INVALID;
  19.     }
  20.     
  21.     //THREAD_NONE: no more threads, other than the caller, are available to
  22.     //run. this can happen is response to a call with tid set to THREAD_ANY. */
  23.     //if (want_tid == THREAD_ANY){
  24.         
  25.    // }
  26.     
  27.     //THREAD_SELF: continue executing calling thread, for debugging purposes.
  28.     if (want_tid == THREAD_SELF || want_tid == current_thread->id){
  29.         interrupts_set(interrupt_enabled);
  30.         return current_thread->id;
  31.     }
  32.  
  33.     //THREAD_ANY: run any thread in the ready queue.
  34.     if (want_tid == THREAD_ANY){
  35.         //check if its in my ready queue
  36.         if (ready_queue == NULL){ 
  37.             interrupts_set(interrupt_enabled);
  38.             return THREAD_NONE;
  39.         }
  40.     struct queue *new_node = (struct queue*)malloc(sizeof(struct queue));
  41.     //check if there is at least one thing in the queue && add to the end
  42.  
  43.     struct queue *prev = ready_queue; //points to the head of my ready queue
  44.         if (ready_queue == NULL){
  45.   
  46.         
  47.         ready_queue = new_node; //added new node to the end of my linked list aka ready queue
  48.         new_node->next = NULL;
  49.         new_node->id = current_thread->id;
  50.         } else {
  51.          //if its more than one element, iterate till u get to the end of the linked list
  52.          struct queue *currentnode = ready_queue-> next;
  53.         
  54.         while(currentnode != NULL){
  55.             prev = currentnode;
  56.             currentnode = currentnode -> next;
  57.             
  58.             }
  59.          //prev->next = in_queue; //new is my new node i created 
  60. /*
  61.         while (prev->next != NULL){
  62.             //if (ready_queue->id == want_tid){
  63.                 //return THREAD_INVALID;
  64.             //}
  65.             // go to the next one till u get to the end
  66.             prev = prev->next;
  67.             
  68.         } 
  69. */
  70.         //something is in for sure, added new node
  71.         prev->next = new_node;
  72.         new_node->id = current_thread->id;
  73.         new_node->next =NULL;
  74.         }
  75.          struct queue *it = ready_queue;
  76.          if (it == NULL){ //empty
  77.             interrupts_set(interrupt_enabled);
  78.              return THREAD_NOMORE;
  79.       
  80.          }
  81.  
  82.          ready_queue=ready_queue->next;
  83.          volatile int saved = it->id;
  84.          free(it);
  85.         
  86.         
  87.         volatile int setcontextcall = 0;
  88.         //saving current
  89.         contexts[new_node->id].status = READY;
  90.         getcontext(&contexts[new_node->id].threadcontext);
  91.         
  92.         if (setcontextcall == 1){
  93.             while(exit_queue != NULL){
  94.             Tid threadid = exit_queue->id;
  95.             free(contexts[threadid].threadcontext.uc_stack.ss_sp);
  96.             array[threadid] =0;
  97.             struct queue* deleter = exit_queue;
  98.             exit_queue =exit_queue->next;
  99.           free(deleter);
  100.         }
  101.             if (contexts[current_thread->id].status == KILLED){
  102.                 thread_exit();
  103.             }
  104.             contexts[current_thread->id].status = RUNNING;
  105.                interrupts_set(interrupt_enabled);
  106.             return (saved);
  107.         } 
  108.         setcontextcall = 1;
  109.         current_thread->id = saved;
  110.         setcontext(&contexts[saved].threadcontext);
  111.             
  112.         
  113.         
  114.     } else {
  115.  
  116. /*thread_yield should suspend the calling thread and run the thread with
  117.  * identifier tid. The calling thread is put in the ready queue. tid can be
  118.  * identifier of any avable thread*/
  119.  
  120.         struct queue *temp = ready_queue;
  121.      
  122.          if (ready_queue == NULL){
  123.                 interrupts_set(interrupt_enabled);
  124.              return THREAD_INVALID;
  125.          }
  126.         
  127.         Tid next;
  128.         
  129.         //taking it out of my linked list aka suspending the calling thread if it matches with id
  130.         if (temp->id == want_tid){
  131.             ready_queue = temp ->next;
  132.             temp->next = NULL;
  133.             next = temp->id; //stored context
  134.             free(temp);
  135.  
  136.         } else {
  137.             //if they dont match keep looking for it muahahahahahha:)
  138.             struct queue *prev = ready_queue;
  139.             struct queue *curr= ready_queue->next;
  140.             while (curr != NULL && curr->id != want_tid) {
  141.                 prev = curr;
  142.                 curr = curr->next;
  143.             }
  144.  
  145.             if (curr!=NULL){
  146.                 //remove it 
  147.                 temp = curr;
  148.                 next = curr->id;
  149.                 //curr will be removed later
  150.                 prev->next = curr ->next;
  151.                 free(temp);
  152.             }
  153.             else {
  154.                 interrupts_set(interrupt_enabled);
  155.                 return THREAD_INVALID;
  156.             }
  157.         }
  158.         
  159.         struct queue *node = (struct queue*)malloc(sizeof(struct queue));
  160.         struct queue *prev = ready_queue; //points to the head of my ready queue
  161.         if (ready_queue == NULL){
  162.   
  163.         
  164.         ready_queue = node; //added new node to the end of my linked list aka ready queue
  165.         node->next = NULL;
  166.         node->id = current_thread->id;
  167.         } else {
  168.          //if its more than one element, iterate till u get to the end of the linked list
  169.             struct queue *currentnode = ready_queue-> next;
  170.         
  171.         while(currentnode != NULL){
  172.             prev = currentnode;
  173.             currentnode = currentnode -> next;
  174.             
  175.             }
  176.         // prev->next = in_queue; //new is my new node i created 
  177. /*      
  178.          
  179.         while (prev->next != NULL){
  180.             //if (ready_queue->id == want_tid){
  181.                 //return THREAD_INVALID;
  182.             //}
  183.             // go to the next one till u get to the end
  184.             prev = prev->next;
  185.             
  186.         } 
  187. */
  188.         //something is in for sure, added new node
  189.         prev->next = node;
  190.         node->id = current_thread->id;
  191.         node->next =NULL;
  192.         }
  193.         
  194.  
  195.         contexts[node->id].status = READY;
  196.         volatile int setcontext_call = 0;
  197.         getcontext(&contexts[node->id].threadcontext);
  198.  
  199.  
  200.         if (setcontext_call == 1){
  201.             if (contexts[next].status == KILLED){
  202.              thread_exit();
  203.             }
  204.             while(exit_queue != NULL){
  205.             Tid threadid = exit_queue->id;
  206.             free(contexts[threadid].threadcontext.uc_stack.ss_sp);
  207.             array[threadid] =0;
  208.             struct queue* deleter = exit_queue;
  209.             exit_queue = exit_queue->next;
  210.           free(deleter);
  211.         }
  212.         contexts[current_thread->id].status = RUNNING;
  213.         volatile int returnvalue = next;
  214.             interrupts_set(interrupt_enabled);
  215.             return (returnvalue);
  216.         }
  217.         setcontext_call = 1;
  218.         current_thread->id = next;
  219.         setcontext(&contexts[want_tid].threadcontext);
  220.        
  221.     }
  222.     interrupts_set(interrupt_enabled);
  223.     return THREAD_FAILED;
  224. }

Editor

You can edit this paste and save as new:


File Description
  • kjglkg
  • Paste Code
  • 20 Oct-2019
  • 7.45 Kb
You can Share it: