- thread_yield should suspend the calling thread and run the thread with
- * identifier tid. The calling thread is put in the ready queue. tid can be
- * identifier of any avable thread or the following constants:ila
- *
- * THREAD_ANY: run any thread in the ready queue.
- *
- * Upon success, return the identifier of the thread that ran. The calling
- * thread does not see this result until it runs later. */
- Tid
- thread_yield(Tid want_tid)
- {
- int interrupt_enabled = interrupts_set(0);
- //THREAD_INVALID: identifier tid does not correspond to a valid thread.
- if (want_tid < -2 || want_tid >= THREAD_MAX_THREADS){
- interrupts_set(interrupt_enabled);
- return THREAD_INVALID;
- }
- //THREAD_NONE: no more threads, other than the caller, are available to
- //run. this can happen is response to a call with tid set to THREAD_ANY. */
- //if (want_tid == THREAD_ANY){
- // }
- //THREAD_SELF: continue executing calling thread, for debugging purposes.
- if (want_tid == THREAD_SELF || want_tid == current_thread->id){
- interrupts_set(interrupt_enabled);
- return current_thread->id;
- }
- //THREAD_ANY: run any thread in the ready queue.
- if (want_tid == THREAD_ANY){
- //check if its in my ready queue
- if (ready_queue == NULL){
- interrupts_set(interrupt_enabled);
- return THREAD_NONE;
- }
- struct queue *new_node = (struct queue*)malloc(sizeof(struct queue));
- //check if there is at least one thing in the queue && add to the end
- struct queue *prev = ready_queue; //points to the head of my ready queue
- if (ready_queue == NULL){
- ready_queue = new_node; //added new node to the end of my linked list aka ready queue
- new_node->next = NULL;
- new_node->id = current_thread->id;
- } else {
- //if its more than one element, iterate till u get to the end of the linked list
- struct queue *currentnode = ready_queue-> next;
- while(currentnode != NULL){
- prev = currentnode;
- currentnode = currentnode -> next;
- }
- //prev->next = in_queue; //new is my new node i created
- /*
- while (prev->next != NULL){
- //if (ready_queue->id == want_tid){
- //return THREAD_INVALID;
- //}
- // go to the next one till u get to the end
- prev = prev->next;
- }
- */
- //something is in for sure, added new node
- prev->next = new_node;
- new_node->id = current_thread->id;
- new_node->next =NULL;
- }
- struct queue *it = ready_queue;
- if (it == NULL){ //empty
- interrupts_set(interrupt_enabled);
- return THREAD_NOMORE;
- }
- ready_queue=ready_queue->next;
- volatile int saved = it->id;
- free(it);
- volatile int setcontextcall = 0;
- //saving current
- contexts[new_node->id].status = READY;
- getcontext(&contexts[new_node->id].threadcontext);
- if (setcontextcall == 1){
- while(exit_queue != NULL){
- Tid threadid = exit_queue->id;
- free(contexts[threadid].threadcontext.uc_stack.ss_sp);
- array[threadid] =0;
- struct queue* deleter = exit_queue;
- exit_queue =exit_queue->next;
- free(deleter);
- }
- if (contexts[current_thread->id].status == KILLED){
- thread_exit();
- }
- contexts[current_thread->id].status = RUNNING;
- interrupts_set(interrupt_enabled);
- return (saved);
- }
- setcontextcall = 1;
- current_thread->id = saved;
- setcontext(&contexts[saved].threadcontext);
- } else {
- /*thread_yield should suspend the calling thread and run the thread with
- * identifier tid. The calling thread is put in the ready queue. tid can be
- * identifier of any avable thread*/
- struct queue *temp = ready_queue;
- if (ready_queue == NULL){
- interrupts_set(interrupt_enabled);
- return THREAD_INVALID;
- }
- Tid next;
- //taking it out of my linked list aka suspending the calling thread if it matches with id
- if (temp->id == want_tid){
- ready_queue = temp ->next;
- temp->next = NULL;
- next = temp->id; //stored context
- free(temp);
- } else {
- //if they dont match keep looking for it muahahahahahha:)
- struct queue *prev = ready_queue;
- struct queue *curr= ready_queue->next;
- while (curr != NULL && curr->id != want_tid) {
- prev = curr;
- curr = curr->next;
- }
- if (curr!=NULL){
- //remove it
- temp = curr;
- next = curr->id;
- //curr will be removed later
- prev->next = curr ->next;
- free(temp);
- }
- else {
- interrupts_set(interrupt_enabled);
- return THREAD_INVALID;
- }
- }
- struct queue *node = (struct queue*)malloc(sizeof(struct queue));
- struct queue *prev = ready_queue; //points to the head of my ready queue
- if (ready_queue == NULL){
- ready_queue = node; //added new node to the end of my linked list aka ready queue
- node->next = NULL;
- node->id = current_thread->id;
- } else {
- //if its more than one element, iterate till u get to the end of the linked list
- struct queue *currentnode = ready_queue-> next;
- while(currentnode != NULL){
- prev = currentnode;
- currentnode = currentnode -> next;
- }
- // prev->next = in_queue; //new is my new node i created
- /*
- while (prev->next != NULL){
- //if (ready_queue->id == want_tid){
- //return THREAD_INVALID;
- //}
- // go to the next one till u get to the end
- prev = prev->next;
- }
- */
- //something is in for sure, added new node
- prev->next = node;
- node->id = current_thread->id;
- node->next =NULL;
- }
- contexts[node->id].status = READY;
- volatile int setcontext_call = 0;
- getcontext(&contexts[node->id].threadcontext);
- if (setcontext_call == 1){
- if (contexts[next].status == KILLED){
- thread_exit();
- }
- while(exit_queue != NULL){
- Tid threadid = exit_queue->id;
- free(contexts[threadid].threadcontext.uc_stack.ss_sp);
- array[threadid] =0;
- struct queue* deleter = exit_queue;
- exit_queue = exit_queue->next;
- free(deleter);
- }
- contexts[current_thread->id].status = RUNNING;
- volatile int returnvalue = next;
- interrupts_set(interrupt_enabled);
- return (returnvalue);
- }
- setcontext_call = 1;
- current_thread->id = next;
- setcontext(&contexts[want_tid].threadcontext);
- }
- interrupts_set(interrupt_enabled);
- return THREAD_FAILED;
- }
[text] kjglkg
Viewer
*** This page was generated with the meta tag "noindex, nofollow". This happened because you selected this option before saving or the system detected it as spam. This means that this page will never get into the search engines and the search bot will not crawl it. There is nothing to worry about, you can still share it with anyone.
Editor
You can edit this paste and save as new: