/** * Process a switch that has transitioned states. All debouncing * is fully completed prior to this call. * * The transition is first latched, so that polling the switch level * will return the new state. At the same time, IRQ-level scanning * is restarted, so that further transitions can be detected. * * Second, if the transition requires scheduling, a task is started * to handle it. Eligibility depends on whether or not the switch * is declared as an edge switch (meaning it is scheduled on both * types of transitions) and whether or not it is an opto (i.e. * do we schedule open-to-closed or closed-to-open?) * * The switch is also known not to be in the debounce queue prior to this * function being called. */ void switch_transitioned (const U8 sw) { /* Latch the transition. sw_logical is still an open/closed level. * By clearing the stable/unstable bits, IRQ will begin scanning * for new transitions at this point. */ disable_irq (); bit_toggle (sw_logical, sw); bit_off (sw_stable, sw); bit_off (sw_unstable, sw); enable_irq (); /* See if the transition requires scheduling. It does if the switch is declared 'edge' (it schedules when becoming active or inactive), otherwise only becoming active. Because most switches are not edge, check for the active state first. */ if (switch_poll_logical (sw) || bit_test (mach_edge_switches, sw)) { #ifdef CONFIG_BPT /* One extra condition : do not schedule any switches when the system is paused */ if (db_paused != 0) return; #endif /* Start a task to process the switch event. This task may sleep if necessary, but it should be as fast as possible and push long-lived operations into separate background tasks. It is possible for more than one instance of a task to exist for the same switch, if valid debounced transitions occur quickly. */ task_pid_t tp = task_create_gid (GID_SW_HANDLER, switch_sched_task); task_set_arg (tp, sw); } }
void leff_toggle (lampnum_t lamp) { #ifdef PARANOID if (bit_test (leff_free_set, lamp)) { dbprintf ("unallocated lamp on %d\n", lamp); return; } #endif bit_toggle (leff_data_set, lamp); }
int main(int argc, char *argv[]) { char t[] = "/tmp/journal-XXXXXX"; unsigned n; JournalFile *f; const char *verification_key = argv[1]; usec_t from = 0, to = 0, total = 0; char a[FORMAT_TIMESTAMP_MAX]; char b[FORMAT_TIMESTAMP_MAX]; char c[FORMAT_TIMESPAN_MAX]; struct stat st; uint64_t p; /* journal_file_open requires a valid machine id */ if (access("/etc/machine-id", F_OK) != 0) return EXIT_TEST_SKIP; log_set_max_level(LOG_DEBUG); assert_se(mkdtemp(t)); assert_se(chdir(t) >= 0); log_info("Generating..."); assert_se(journal_file_open("test.journal", O_RDWR|O_CREAT, 0666, true, !!verification_key, NULL, NULL, NULL, &f) == 0); for (n = 0; n < N_ENTRIES; n++) { struct iovec iovec; struct dual_timestamp ts; char *test; dual_timestamp_get(&ts); assert_se(asprintf(&test, "RANDOM=%lu", random() % RANDOM_RANGE)); iovec.iov_base = (void*) test; iovec.iov_len = strlen(test); assert_se(journal_file_append_entry(f, &ts, &iovec, 1, NULL, NULL, NULL) == 0); free(test); } journal_file_close(f); log_info("Verifying..."); assert_se(journal_file_open("test.journal", O_RDONLY, 0666, true, !!verification_key, NULL, NULL, NULL, &f) == 0); /* journal_file_print_header(f); */ journal_file_dump(f); assert_se(journal_file_verify(f, verification_key, &from, &to, &total, true) >= 0); if (verification_key && JOURNAL_HEADER_SEALED(f->header)) log_info("=> Validated from %s to %s, %s missing", format_timestamp(a, sizeof(a), from), format_timestamp(b, sizeof(b), to), format_timespan(c, sizeof(c), total > to ? total - to : 0, 0)); journal_file_close(f); if (verification_key) { log_info("Toggling bits..."); assert_se(stat("test.journal", &st) >= 0); for (p = 38448*8+0; p < ((uint64_t) st.st_size * 8); p ++) { bit_toggle("test.journal", p); log_info("[ %"PRIu64"+%"PRIu64"]", p / 8, p % 8); if (raw_verify("test.journal", verification_key) >= 0) log_notice(ANSI_HIGHLIGHT_RED ">>>> %"PRIu64" (bit %"PRIu64") can be toggled without detection." ANSI_NORMAL, p / 8, p % 8); bit_toggle("test.journal", p); } } log_info("Exiting..."); assert_se(rm_rf(t, REMOVE_ROOT|REMOVE_PHYSICAL) >= 0); return 0; }
void lamp_toggle (lampnum_t lamp) { bit_toggle (lamp_matrix, lamp); }