/* * Given an element, remove it from the btree if it's already * there and re-insert it based on its current key. */ void schedule_add_modify (struct schedule *s, struct schedule_entry *e) { #ifdef ENABLE_DEBUG if (check_debug_level (D_SCHEDULER)) schedule_entry_debug_info ("schedule_add_modify", e); #endif /* already in tree, remove */ if (IN_TREE (e)) schedule_remove_node (s, e); /* set random priority */ schedule_set_pri (e); if (s->root) schedule_insert (s, e); /* trivial insert into tree */ else s->root = e; /* tree was empty, we are the first element */ /* This is the magic of the randomized treap algorithm which keeps the tree balanced. Move the node up the tree until its own priority is greater than that of its parent */ while (e->parent && e->parent->pri > e->pri) schedule_rotate_up (s, e); }
/************************************************************************* schedule_reschedule: Moves an item from one time to another in the schedule. Currently, this is used when the unimolecular rates for a subunit cause a molecule's unimolecular reaction rate to change. In: struct schedule_helper *sh - the scheduler from which to remove void *data - the item to remove double new_t - the new time for the item Out: 0 on success, 1 if the item was not found *************************************************************************/ int schedule_reschedule(struct schedule_helper *sh, void *data, double new_t) { if (!schedule_deschedule(sh, data)) { struct abstract_element *ae = (struct abstract_element *)data; ae->t = new_t; return schedule_insert(sh, data, 1); } else return 1; }
int schedule_advance(struct schedule_helper *sh, struct abstract_element **head, struct abstract_element **tail) { int n; struct abstract_element *p, *nextp; if (head != NULL) *head = sh->circ_buf_head[sh->index]; if (tail != NULL) *tail = sh->circ_buf_tail[sh->index]; sh->circ_buf_head[sh->index] = sh->circ_buf_tail[sh->index] = NULL; sh->count -= n = sh->circ_buf_count[sh->index]; sh->circ_buf_count[sh->index] = 0; sh->index++; sh->now += sh->dt; if (sh->index >= sh->buf_len) { /* Move events from coarser time scale to this time scale */ sh->index = 0; if (sh->next_scale != NULL) { /* Save our depth */ int old_depth = sh->depth; int conservecount = sh->count; /* Hack: Toggle the non-zero-ness of our depth to toggle FIFO/LIFO * behavior */ sh->depth = old_depth ? 0 : -1; if (schedule_advance(sh->next_scale, &p, NULL) == -1) { sh->depth = old_depth; return -1; } while (p != NULL) { nextp = p->next; if (schedule_insert(sh, (void *)p, 0)) { sh->depth = old_depth; return -1; } p = nextp; } /* moved items were already counted when originally scheduled so don't * count again */ sh->count = conservecount; /* restore our depth */ sh->depth = old_depth; } } return n; }
struct thread *thread_thaw(struct thread *thread) { if (thread->frozen) { thread->frozen--; } if (!thread->frozen) { schedule_insert(thread); } return thread; }
struct thread *thread_send(struct thread *image, pid_t target, portid_t port, struct msg *msg) { struct process *p_targ; struct thread *new_image; /* find target process */ p_targ = process_get(target); /* check process */ if (!p_targ || !p_targ->entry) { return image; } /* create new thread */ new_image = thread_alloc(); thread_bind(new_image, p_targ); new_image->ds = 0x23; new_image->cs = 0x1B; new_image->ss = 0x23; new_image->eflags = 0; new_image->useresp = new_image->stack + SEGSZ; new_image->proc = p_targ; new_image->eip = p_targ->entry; /* set up registers in new thread */ new_image->ebx = 0; new_image->ecx = (msg) ? msg->count : 0; new_image->edx = port; new_image->esi = (image) ? image->proc->pid : 0; new_image->edi = 0; new_image->msg = msg; /* set new thread's user id */ new_image->user = (!image || p_targ->user) ? p_targ->user : image->user; /* insert new thread into scheduler */ schedule_insert(new_image); /* return new thread */ return new_image; }
static void set_expire_event(timeval_t t) { disable_interrupts(); expire_event.time = t; schedule_insert(current_time(), &expire_event); enable_interrupts(); }
void inline radio_state() { if (init) { schedule_insert(system_schedule, 0, ms_clock, get_time); schedule_insert(system_schedule, 0, ms_clock, get_rbds); schedule_insert(system_schedule, 0, ms_clock, get_status); schedule_insert(system_schedule, 0, ms_clock, display_radio_screen); schedule_insert(system_schedule, 0, ms_clock, display_radio_channel); schedule_insert(system_schedule, 0, ms_clock, display_rbds_information); schedule_insert(system_schedule, 0, ms_clock, start_ADC_conversion); if (!radio_is_on) { si4705_power_on(); si4705_set_channel(channel); set_volume(ADC_values[0]); } radio_is_on = true; what_the_beep = false; nokia5110_clear(); wd_clock = 0; //second counter #ifndef USING_PRINTF PORTD &= ~_BV(0); // Turn the radio LED on PORTD |= _BV(1); // Turn the stereo status LED off #endif } if(bns[0]) { bns[0] = false; if (radio_activity == 1) { channel -= 2; if (channel%2 == 0) { channel += 1; } if (channel < SI4705_FM_LOW) channel = SI4705_FM_HIGH; si4705_set_channel(channel); clear_radio_strings(); } radio_activity = 1; wd_clock = 0; //reset activity schedule_insert(system_schedule, 200, ms_clock, button_down); } if(bns[1]) { bns[1] = false; eeprom_update_word(&saved_channel, channel); state = menu; } if(bns[2]) { //printf("I was pressed up\n"); bns[2] = false; if (radio_activity == 2) { channel += 2; if (channel%2 == 0) { channel -= 1; } if (channel < SI4705_FM_LOW) channel = SI4705_FM_HIGH; si4705_set_channel(channel); clear_radio_strings(); } radio_activity = 2; wd_clock = 0; //reset activity ////printf("event scheduled\n"); schedule_insert(system_schedule, 200, ms_clock, button_up); } if (event_is_ready) { switch(next_event.id) { case start_ADC_conversion: ADC_start_conversion(); set_brightness(photo_avg/PHOTO_AVG_RESOLUTION); set_volume(ADC_values[0]); schedule_insert(system_schedule, 20, ms_clock, start_ADC_conversion); break; case get_time: ds1307_getdate_s(&time); schedule_insert(system_schedule, 1000, ms_clock, get_time); //printf("%d:%d:%d\n", time.hour, time.minute, time.second); break; case get_rbds: si4705_get_rdbs(station_text, scroll_text); schedule_insert(system_schedule, 200, ms_clock, get_rbds); break; case get_status: si4705_get_tune_status(&radio_tune_status); si4705_get_rsq_status(&radio_rsq_status); channel = radio_tune_status.tuneFrequency; //printf("%u\n", channel); schedule_insert(system_schedule, 100, ms_clock, get_status); break; case display_radio_screen: nokia5110_gotoXY(14,0); snprintf(line, 10, "%02d:%02d %s", time.hour - 12*(time.hour>12), time.minute, time.hour<12?"am":"pm"); nokia5110_writeString(line); schedule_insert(system_schedule, 1000, ms_clock, display_radio_screen); break; case display_radio_channel: nokia5110_gotoXY(8-8*(channel>=1000),1); snprintf(line, 8, " %d.%d ", channel/10, channel%10); nokia5110_writeString_megaFont(line); nokia5110_gotoXY(0, 2); snprintf(line, 2, "%c", 124+(ADC_values[0]>80)+(ADC_values[0]>180)); nokia5110_writeString(line); nokia5110_gotoXY(0, 3); snprintf(line, 2, "%c", 128 + (radio_rsq_status.rssi>22) + (radio_rsq_status.rssi>35)); nokia5110_writeString(line); nokia5110_gotoXY(70, 3); snprintf(line, 3, "%s", radio_rsq_status.pilot?"st":" "); nokia5110_writeString(line); #ifndef USING_PRINTF if (radio_rsq_status.pilot) { PORTD &= ~(_BV(1)); // Turn the stereo status on } else { PORTD |= _BV(1); // Turn the stereo status off } #endif schedule_insert(system_schedule, 100, ms_clock, display_radio_channel); break; case display_rbds_information: rbds_pixel_offset = (rbds_pixel_offset+1) % 7; if (rbds_pixel_offset == 0) { text_index = (text_index + 1) % (strlen(scroll_text)); } if (strlen(scroll_text) > DISPLAY_OFFSET+1) { // we have a radio string nokia5110_gotoXY(0,5); nokia5110_writeString_L(&scroll_text[text_index], rbds_pixel_offset); //nokia5110_writeString_C(&scroll_text[text_index]); } else if (strlen(station_text) > 0) { // we don't have a radio string, but we have program service! snprintf(line, 12, "%s ", station_text); nokia5110_gotoXY(14,5); nokia5110_writeString_C(line); } else { // we got nothing nokia5110_gotoXY(0,5); nokia5110_writeString(" "); } schedule_insert(system_schedule, 100, ms_clock, display_rbds_information); break; case button_down: if (hol[0]) { si4705_seek(DOWN); clear_radio_strings(); } else { channel -= 2; if (channel%2 == 0) { channel += 1; } if (channel < SI4705_FM_LOW) channel = SI4705_FM_HIGH; si4705_set_channel(channel); clear_radio_strings(); } radio_activity = 0; break; case button_up: //printf("handling event - "); if (hol[2]) { //printf("you were holding\n"); si4705_seek(UP); clear_radio_strings(); } else { //printf("you were tapping\n"); channel += 2; if (channel%2 == 0) { channel -= 1; } if (channel > SI4705_FM_HIGH) channel = SI4705_FM_LOW; si4705_set_channel(channel); clear_radio_strings(); } radio_activity = 0; break; default: break; } } if (wd_clock == 3599) { state = last_state; } }
void inline preset_state() { if (init) { schedule_insert(system_schedule, 0, ms_clock, start_ADC_conversion); menu_index = 0; nokia5110_clear(); for (err = 0; err < NUMBER_OF_PRESETS; err++) { nokia5110_gotoXY(0, err); snprintf(line, 12, " %u.%u", presets[err]/10, presets[err]%10); nokia5110_writeString(line); } nokia5110_gotoXY(0,0); nokia5110_writeString(">"); nokia5110_gotoXY(0,5); nokia5110_writeString(" Back"); } if (bns[0]) { bns[0] = false; nokia5110_gotoXY(0, menu_index); nokia5110_writeString(" "); menu_index = (menu_index+1) % 6; nokia5110_gotoXY(0, menu_index); nokia5110_writeString(">"); wd_clock = 0; // reset activity watchdog_feed(); } if (bns[1]) { bns[1] = false; if(menu_index == 5) { state = last_state; } else { // choose preset if (last_state == home) { nokia5110_gotoXY(0,menu_index); nokia5110_writeString(" "); err = set_preset_variable(menu_index); if (err) { state = last_state; } nokia5110_gotoXY(0,menu_index); snprintf(line, 12, ">%u.%u", presets[menu_index]/10, presets[menu_index]%10); nokia5110_writeString(line); } else { if (channel != presets[menu_index]) { channel = presets[menu_index]; si4705_set_channel(channel); clear_radio_strings(); } state = radio; } } } if (bns[2]) { bns[2] = false; nokia5110_gotoXY(0, menu_index); nokia5110_writeString(" "); menu_index = (menu_index+5) % 6; nokia5110_gotoXY(0, menu_index); nokia5110_writeString(">"); wd_clock = 0; //reset activity watchdog_feed(); } if (event_is_ready) { switch(next_event.id) { case start_ADC_conversion: ADC_start_conversion(); set_brightness(photo_avg/PHOTO_AVG_RESOLUTION); schedule_insert(system_schedule, 20, ms_clock, start_ADC_conversion); break; default: break; } } if(wd_clock == 60) { wd_clock = 0; state = last_state; } }
void inline alarm_state() { if (init) { nokia5110_clear(); nokia5110_drawSplash(); schedule_insert(system_schedule, 0, ms_clock, get_time); schedule_insert(system_schedule, 0, ms_clock, start_ADC_conversion); if (state == alarm_A) { if (alarm_A_is_beep) { radio_is_on = false; what_the_beep = true; schedule_insert(system_schedule, 250, ms_clock, beep_off); } else { #ifndef USING_PRINTF PORTD &= ~_BV(0); // Turn the radio LED on #endif what_the_beep = false; radio_is_on = true; si4705_power_on(); si4705_set_channel(channel); schedule_insert(system_schedule, 100, ms_clock, radio_volume_change); } } else { if (alarm_B_is_beep) { radio_is_on = false; what_the_beep = true; schedule_insert(system_schedule, 250, ms_clock, beep_off); } else { #ifndef USING_PRINTF PORTD &= ~_BV(0); // Turn the radio LED on #endif what_the_beep = false; radio_is_on = true; si4705_power_on(); si4705_set_channel(channel); schedule_insert(system_schedule, 100, ms_clock, radio_volume_change); } } err = 25; set_volume(25); wd_clock = 0; } if(bns[0] || bns[2]) { // sleep bns[0] = bns[2] = false; if (state==alarm_A) { time_alarm_A.hour = time.hour; time_alarm_A.minute = time.minute + ALARM_SLEEP_TIME; if (time_alarm_A.minute >= 60) { time_alarm_A.minute -= 60; time_alarm_A.hour += 1; if (time_alarm_A.hour >= 24) { time_alarm_A.hour -= 24; } } } if (state==alarm_B) { time_alarm_B.hour = time.hour; time_alarm_B.minute = time.minute + ALARM_SLEEP_TIME; if (time_alarm_B.minute >= 60) { time_alarm_B.minute -= 60; time_alarm_B.hour += 1; if (time_alarm_B.hour >= 24) { time_alarm_B.hour -= 24; } } } state = last_state; } if(bns[1] || ((state == alarm_A) && !hol[3]) || ((state == alarm_B) && !hol[4])) { // silence....... or did we have that backwards bns[1] = false; if (state==alarm_A) { alarm_A_went_off_today = true; } if (state==alarm_B) { alarm_B_went_off_today = true; } state = last_state; } if (event_is_ready) { switch(next_event.id) { case start_ADC_conversion: ADC_start_conversion(); set_brightness(photo_avg/PHOTO_AVG_RESOLUTION); schedule_insert(system_schedule, 20, ms_clock, start_ADC_conversion); break; case get_time: ds1307_getdate_s(&time); schedule_insert(system_schedule, 1000, ms_clock, get_time); break; case radio_volume_change: if (err < 175 || err < ADC_values[0]) { err ++; set_volume(err); } else { if (ADC_values[0] > 175) { set_volume(ADC_values[0]); } else { set_volume(175); } } schedule_insert(system_schedule, 100, ms_clock, radio_volume_change); break; case beep_off: set_volume(0); schedule_insert(system_schedule, 500, ms_clock, beep_on); break; case beep_on: if (err < 175 || err < ADC_values[0]) { err += 5; set_volume(err); } else { if (ADC_values[0] > 175) { set_volume(ADC_values[0]); } else { set_volume(175); } } schedule_insert(system_schedule, 250, ms_clock, beep_off); break; default: break; } } if (wd_clock == 3599) { if (state==alarm_A) { alarm_A_went_off_today = true; } if (state==alarm_B) { alarm_B_went_off_today = true; } state = last_state; } }
void inline menu_state() { if (init) { schedule_insert(system_schedule, 0, ms_clock, start_ADC_conversion); menu_index = 0; nokia5110_clear(); nokia5110_gotoXY(0,0); if (last_state == home) { nokia5110_writeString(">Radio"); } else { nokia5110_writeString(">Radio Off"); } nokia5110_gotoXY(0,1); nokia5110_writeString(" Time-Set"); nokia5110_gotoXY(0,2); nokia5110_writeString(" Set AlarmA"); nokia5110_gotoXY(0,3); nokia5110_writeString(" Set AlarmB"); nokia5110_gotoXY(0,4); if (last_state == home) { nokia5110_writeString(" Set Presets"); } else { nokia5110_writeString(" FM Presets"); } nokia5110_gotoXY(0,5); nokia5110_writeString(" Back"); } if (bns[0]) { bns[0] = false; nokia5110_gotoXY(0, menu_index); nokia5110_writeString(" "); menu_index = (menu_index+1) % 6; nokia5110_gotoXY(0, menu_index); nokia5110_writeString(">"); wd_clock = 0; //reset activity watchdog_feed(); } if(bns[1]) { bns[1] = false; switch(menu_index) { case 0: if (last_state == home) { state = radio; } else { state = home; } break; case 1: state = set_clock; break; case 2: state = set_alarm_A; break; case 3: state = set_alarm_B; break; case 4: state = preset; break; default: state = last_state; break; } } if (bns[2]) { bns[2] = false; nokia5110_gotoXY(0, menu_index); nokia5110_writeString(" "); menu_index = (menu_index+5) % 6; nokia5110_gotoXY(0, menu_index); nokia5110_writeString(">"); wd_clock = 0; //reset activity watchdog_feed(); } if (event_is_ready) { switch(next_event.id) { case start_ADC_conversion: ADC_start_conversion(); set_brightness(photo_avg/PHOTO_AVG_RESOLUTION); schedule_insert(system_schedule, 20, ms_clock, start_ADC_conversion); break; default: break; } } if(wd_clock == 60) { wd_clock = 0; state = last_state; } }
void inline home_state() { if (init) { schedule_insert(system_schedule, 0, ms_clock, get_time); schedule_insert(system_schedule, 0, ms_clock, display_home_screen); schedule_insert(system_schedule, 0, ms_clock, display_temp_and_alarm_settings); schedule_insert(system_schedule, 0, ms_clock, start_ADC_conversion); nokia5110_clear(); if (radio_is_on) { si4705_power_off(); radio_is_on = false; } what_the_beep = false; set_volume(0); #ifndef USING_PRINTF PORTD |= _BV(0); // Turn the radio LED off PORTD |= _BV(1); // Turn the stereo status LED off #endif } if(bns[0]) { bns[0] = false; } if(bns[1]) { bns[1] = false; state = menu; } if(bns[2]) { bns[2] = false; } if (event_is_ready) { switch(next_event.id) { case start_ADC_conversion: ADC_start_conversion(); set_brightness(photo_avg/PHOTO_AVG_RESOLUTION); schedule_insert(system_schedule, 20, ms_clock, start_ADC_conversion); break; case get_time: ds1307_getdate_s(&time); err = ds1307_getdayofweek(time.year, time.month, time.day); schedule_insert(system_schedule, 1000, ms_clock, get_time); //printf("%d:%d:%d\n", time.hour, time.minute, time.second); break; case display_home_screen: snprintf(line, 12, "%02d:%02d", time.hour - 12*(time.hour>12), time.minute); nokia5110_gotoXY(12,1); nokia5110_writeString_megaFont(line); snprintf(line, 12, " %s ", days_of_week[err]); nokia5110_gotoXY(day_pixel_offsets[err],0); nokia5110_writeString(line); snprintf(line, 12, "%s", time.hour<12?"am":"pm"); nokia5110_gotoXY(68,3); nokia5110_writeString(line); snprintf(line, 9, "%d/%d/%d ", time.month, time.day, time.year); nokia5110_gotoXY(0,4); nokia5110_writeString(line); schedule_insert(system_schedule, 1000, ms_clock, display_home_screen); break; case display_temp_and_alarm_settings: init = false; snprintf(line, 8, "%02d.%01d%cF ", (uint8_t)(temperature_avg/THERM_AVG_RESOLUTION/10), (uint8_t)(temperature_avg/THERM_AVG_RESOLUTION%10), 123); nokia5110_gotoXY(0,5); nokia5110_writeString(line); nokia5110_gotoXY(63,4); if (hol[3]) { snprintf(line, 4, "A:%c", alarm_A_is_beep?124+(ADC_values[0]>80)+(ADC_values[0]>180):127); } else { snprintf(line, 4, "A: "); } nokia5110_writeString(line); nokia5110_gotoXY(63,5); if (hol[4]) { snprintf(line, 4, "B:%c", alarm_B_is_beep?124+(ADC_values[0]>80)+(ADC_values[0]>180):127); } else { snprintf(line, 4, "B: "); } nokia5110_writeString(line); schedule_insert(system_schedule, 100, ms_clock, display_temp_and_alarm_settings); break; default: break; } } watchdog_feed(); }
int schedule_insert(struct schedule_helper *sh, void *data, int put_neg_in_current) { struct abstract_element *ae = (struct abstract_element *)data; if (put_neg_in_current && ae->t < sh->now) { /* insert item into current list */ sh->current_count++; if (sh->current_tail == NULL) { sh->current = sh->current_tail = ae; ae->next = NULL; } else { sh->current_tail->next = ae; sh->current_tail = ae; ae->next = NULL; } return 0; } /* insert item into future lists */ sh->count++; double nsteps = (ae->t - sh->now) * sh->dt_1; if (nsteps < ((double)sh->buf_len)) { /* item fits in array for this scale */ int i; if (nsteps < 0.0) i = sh->index; else i = (int)nsteps + sh->index; if (i >= sh->buf_len) i -= sh->buf_len; if (sh->circ_buf_tail[i] == NULL) { sh->circ_buf_count[i] = 1; sh->circ_buf_head[i] = sh->circ_buf_tail[i] = ae; ae->next = NULL; } else { sh->circ_buf_count[i]++; /* For schedulers other than the first tier, maintain a LIFO ordering */ if (sh->depth) { ae->next = sh->circ_buf_head[i]; sh->circ_buf_head[i] = ae; } /* For first-tier scheduler, maintain FIFO ordering */ else { sh->circ_buf_tail[i]->next = ae; ae->next = NULL; sh->circ_buf_tail[i] = ae; } } } else { /* item fits in array for coarser scale */ if (sh->next_scale == NULL) { sh->next_scale = create_scheduler( sh->dt * sh->buf_len, sh->dt * sh->buf_len * sh->buf_len, sh->buf_len, sh->now + sh->dt * (sh->buf_len - sh->index)); if (sh->next_scale == NULL) return 1; sh->next_scale->depth = sh->depth + 1; } /* insert item at coarser scale and insist that item is not placed in * "current" list */ return schedule_insert(sh->next_scale, data, 0); } return 0; }