// check sleep queue to wake up all timed-out threads // sync == TRUE -> synchronize last_check_time static void sleepq_check(int sync) { unsigned long long now; long long interval; linked_list_entry_t *e; if (!sync && max_sleep_time == 0) { // shortcut to return first_wake_usecs = 0; // FIXME: don't write to it every time return; } sleepq_sanity_check(); now = current_usecs(); if( now > last_check_time ) interval = now-last_check_time; else interval = 0; last_check_time = now; // adjust max_sleep_time if (max_sleep_time < (unsigned long long)interval) max_sleep_time = 0; else max_sleep_time -= interval; while (interval > 0 && (e = ll_view_head(sleepq))) { thread_t *t = (thread_t *)pl_get_pointer(e); if (t->sleep > interval) { t->sleep -= interval; first_wake_usecs = now + t->sleep; break; } interval -= t->sleep; t->sleep = -1; t->timeout = 1; //output(" %10llu: thread %d timeout\n", current_usecs(), t->tid); _thread_resume(t); // this doesn't deal with sleep queue ll_free_entry(sleepq, ll_remove_head(sleepq)); } if (ll_size(sleepq) == 0) { // the sleepq is empty again first_wake_usecs = 0; } sleepq_sanity_check(); }
/** * remove the head of the list, and return the associated data. If * the list is empty, return -1, to distinguish between NULL data. **/ void* pl_remove_head(pointer_list_t *pl) { pointer_list_entry_t *e; const void *data; e = (pointer_list_entry_t*) ll_remove_head(pl); if(e == NULL) return (void *) -1; data = e->data; ll_free_entry(pl,(linked_list_entry_t*)e); return (void*)data; }
void ll_clean( struct linked_list **list ) { struct linked_list *iter = *list; struct linked_list_element *tmp; if( !ll_is_valid( iter )) return; while(( tmp = ll_get_head( iter )) != NULL ) { ll_remove_head( iter ); ll_free_element( ll_get_addr( tmp )); } free( iter ); }