void sem_pend(sem_struct *sem) { cpu_sr_t cpu_sr; list_node_t *pnode; thread_struct *pthread; cpu_sr = save_cpu_sr(); if (sem->value == 0) { if (!is_empty_list(&sem->wait_list)) { for (pnode = begin_list(&sem->wait_list); pnode != end_list(&sem->wait_list); pnode = next_list(pnode)) { pthread = entry_list(pnode, thread_struct, node); if (current_thread->prio < pthread->prio) { current_thread->state = EVENT_WAIT; insert_before_list( pnode, ¤t_thread->node); break; } } } if (current_thread->state != EVENT_WAIT) { current_thread->state = EVENT_WAIT; insert_back_list(&sem->wait_list, ¤t_thread->node); } schedule(SCHED_THREAD_REQUEST); return; } sem->value--; restore_cpu_sr(cpu_sr); }
/** Inserts @a d into list @a l. @a d is inserted before the first value in the * list where d < list->data. @a c is used to compare d to the data in the list. * O(n) operation. * @param l The list * @param d The new data member * @param c A comparison function. * @return The new list */ struct slist *slist_insert_sorted(struct slist *l, void *d, compare_func c) { struct slist *ins = next_list(); struct slist *head = l; struct slist *prev; ins->next = NULL; ins->data = d; if(head == NULL) return ins; if(c(d, head->data) < 0) { ins->next = head; return ins; } prev = head; l = l->next; while(l != NULL) { if(c(d, l->data) < 0) { ins->next = prev->next; prev->next = ins; return head; } prev = l; l = l->next; } prev->next = ins; return head; }
/** Prepends @a d to list @a l. O(1) operation. * @param l The list * @param d The new data member * @return The new list */ struct slist *slist_insert(struct slist *l, void *d) { struct slist *head; head = next_list(); head->next = l; head->data = d; return head; }
/** Appends @a d to the end of list @a l. O(n) operation * @param l The list * @param d The new data member * @return The new list */ struct slist *slist_append(struct slist *l, void *d) { struct slist *last; struct slist *head = l; last = next_list(); last->next = NULL; last->data = d; if(head == NULL) return last; while(l->next != NULL) { l = l->next; } l->next = last; return head; }
/** * @brief time tick advanced * Maintain time_quantum */ void advance_time_tick() { cpu_sr_t cpu_sr; list_node_t *pnode; thread_struct *pthread; thread_struct *readyed_thread = NULL; cpu_sr = save_cpu_sr(); os_time_tick++; /* If there are delays in the list of threads... */ if (!is_empty_list(&delayed_list)) { for (pnode = begin_list(&delayed_list); pnode != end_list(&delayed_list); pnode = next_list(pnode) ) { pthread = entry_list(pnode, thread_struct, node); pthread->delayed_time--; /* ready to change the status */ if (readyed_thread != NULL) { delete_list(&readyed_thread->node); readyed_thread->state = READY; readyed_thread->time_quantum = TIME_QUANTUM; insert_back_list( &ready_list[readyed_thread->prio], &readyed_thread->node); prio_exist_flag[readyed_thread->prio] = true; readyed_thread = NULL; } if (pthread->delayed_time <= 0) { readyed_thread = pthread; } } if (readyed_thread != NULL) { delete_list(&readyed_thread->node); readyed_thread->state = READY; readyed_thread->time_quantum = TIME_QUANTUM; insert_back_list( &ready_list[readyed_thread->prio], &readyed_thread->node); prio_exist_flag[readyed_thread->prio] = true; } } current_thread->time_quantum--; restore_cpu_sr(cpu_sr); }