// set a timer on a thread that will wake the thread up after timeout // microseconds. this is used to implement thread_suspend_self(timeout) static void sleepq_add_thread(thread_t *t, unsigned long long timeout) { linked_list_entry_t *e; long long total_time; sleepq_check(1); // make sure: last_check_time == now assert(t->sleep == -1); sleepq_sanity_check(); if (timeout >= max_sleep_time) { // set first_wake_usecs if this is the first item if( pl_view_head(sleepq) == NULL ) first_wake_usecs = current_usecs() + timeout; // just append the thread to the end of sleep queue pl_add_tail(sleepq, t); t->sleep = timeout - max_sleep_time; assert( t->sleep >= 0 ); max_sleep_time = timeout; sleepq_sanity_check(); return; } // let's find a place in the queue to insert the thread // we go backwards e = ll_view_tail(sleepq); total_time = max_sleep_time; while (e) { thread_t *tt = (thread_t *)pl_get_pointer(e); assert(tt->sleep >= 0); total_time -= tt->sleep; assert (total_time >= 0); // can be == 0 if we are adding the head item if ((unsigned long long)total_time <= timeout) { // insert t into the queue linked_list_entry_t *newp = ll_insert_before(sleepq, e); pl_set_pointer(newp, t); t->sleep = timeout - total_time; assert( t->sleep > 0 ); // set first_wake_usecs if this is the first item if( total_time == 0 ) first_wake_usecs = current_usecs() + timeout; // update the sleep time of the thread right after t tt->sleep -= t->sleep; assert( tt->sleep > 0 ); break; } e = ll_view_prev(sleepq, e); } assert (e != NULL); // we're sure to find such an e sleepq_sanity_check(); return; }
uintptr_t rfl_alloc_specific_range(rfl_t rfl, uintptr_t from, unsigned long size) { struct range *range; uintptr_t retval; rfl_t cur; /* * Find size entries to allocate */ if (rfl->next == rfl) { return 0; } cur = rfl->next; do { range = cur->data; retval = range->from; if(range->from <= from && range->to > from && range->to >= (from + size - 1)) { if(range->from == from && range->from + size - 1 == range->to) { free(range); ll_delete(cur); return retval; } else if (range->from == from) { range->from += size; return retval; } else if (from + size - 1 == range->to) { range->to -= size; return range->to; } else { struct range *new_range = malloc(sizeof(struct range)); if(new_range == 0) { return E_RFL_NOMEM; /* Failure! */ } ll_insert_before(cur, new_range); new_range->from = range->from; new_range->to = from - 1; range->from = from + size; return from; } } else { cur = cur->next; } } while (cur != rfl); /* * Unable to fulfil request */ return 0; }
t_llist_node *ll_prepend(t_llist *l, void *val) { return ll_insert_before(l->sentinel_node->next,val); }
t_llist_node *ll_append(t_llist *l, void *val) { return ll_insert_before(l->sentinel_node,val); }
t_llist_node *ll_insert_after(t_llist_node *node, void *val) { return ll_insert_before(node->next,val); }