void binary_semaphore_down(struct binary_semaphore* semaphore) { alarm(0); if (semaphore->value ==0) { semaphore->waiting[threadTable.runningThread->tid] = semaphore->counter++; uthread_sleep(); } semaphore->waiting[threadTable.runningThread->tid] = -1; semaphore->value = 0; alarm(UTHREAD_QUANTA); }
int armice_codelet_test(armice_ctrl_t * ctrl, FILE * f) { armice_codelet_t * cl = &codelet_step2; struct armice_context ct0; struct armice_context ct1; int dbg_status; uint32_t addr = ctrl->work_addr; uint32_t reg[16]; int ret; int i; fprintf(f, " == ARM CODELET TEST ==\n"); fprintf(f, " - Loading codelet @ addr:0x%08x, size:%d ...\n", addr, cl->size); if ((ret = armice_code_load(ctrl, addr, cl->code, cl->size)) < 0) { fprintf(f, "# Error: arm7ice_code_load()!\n"); return ret; } for (i = 0; i < 12; i++) { ct0.r[i] = 0xf0000000 + i; } ct0.sp = 0xdddd0000; ct0.lr = 0xeeee0000; ct0.pc = 0xffff0000; ct0.cpsr = ARM_MODE_SYSTEM | ARM_DISABLE_IRQ | ARM_DISABLE_FIQ; fprintf(f, " - Installing a fresh ARM context >>> >>>\n"); ctrl->arm_context_restore(ctrl->tap, &ct0); reg[0] = 0x00000000; reg[1] = 0x11111111; reg[2] = 0x22222222; reg[3] = 0x33333333; reg[4] = 0x44444444; reg[5] = 0x55555555; reg[6] = 0x66666666; reg[7] = 0x77777777; reg[8] = 0x88888888; reg[9] = 0x99999999; reg[10] = 0x10101010; reg[11] = 0x11111111; reg[12] = 0x12121212; reg[12] = 0x13131313; if ((ret = armice_code_exec(ctrl, addr, reg, 13)) < 0) { fprintf(f, " # ERROR: armice_code_exec()!\n"); return ret; } if ((dbg_status = ctrl->jtag_arm_dbg_status(ctrl->tap)) < 0) { DCC_LOG1(LOG_ERROR, "arm7ice_get_status(): %d", dbg_status); return dbg_status; } if ((dbg_status & ARMICE_ST_DBGACK) != 0) { fprintf(f, " # ERROR: Core is stopped!!!!!!!\n"); } fprintf(f, " - Wait 10 ms...\n"); uthread_sleep(10); armice_code_stop(ctrl); if ((dbg_status = test_save_context(f, ctrl, &ct0)) < 0) return -1; if (dbg_status & ARMICE_ST_TBIT) { fprintf(f, " #ERROR: THUMB state!!\n"); return -1; } fprintf(f, " - TARGET context, before step:\n"); arm_show_cpsr(f, ct0.cpsr); arm_show_regs(f, ct0.r); show_insn(f, ctrl, &ct0); fprintf(f, " - Step @ 0x%08x:\n", addr); fprintf(f, " - ARM step ...\n"); if ((ret = ctrl->arm_insn_step(ctrl->tap, &ct0)) < 0) { fprintf(f, "# ARM step error!!!!\n"); return -1; } if ((dbg_status = test_save_context(f, ctrl, &ct1)) < 0) return -1; fprintf(f, " - TARGET context, after step:\n"); arm_show_cpsr(f, ct1.cpsr); arm_show_regs(f, ct1.r); show_insn(f, ctrl, &ct1); return 0; }
int armice_thumb_codelet_test(armice_ctrl_t * ctrl, FILE * f) { armice_codelet_t * cl = &codelet_step_thumb; struct armice_context ct0; struct armice_context ct1; int dbg_status; uint32_t addr = ctrl->work_addr; uint32_t reg[16]; int ret; fprintf(f, " == THUMB CODELET TEST ==\n"); if (test_save_context(f, ctrl, &ct0) < 0) return -1; fprintf(f, "- Loading codelet: %p, size:%d ...\n", cl, cl->size); if ((ret = armice_code_load(ctrl, addr, cl->code, cl->size)) < 0) { fprintf(f, "# Error: arm7ice_code_load()!\n"); return ret; } reg[0] = 0x0000; reg[1] = 0x11111111; reg[2] = 0x22222222; reg[3] = 0x33333333; reg[4] = 0x44444444; reg[5] = 0x55555555; reg[6] = 0x66666666; reg[7] = 0x77777777; reg[8] = 0x88888888; reg[9] = 0x99999999; reg[10] = 0x10101010; reg[11] = 0x11111111; reg[12] = 0x12121212; if ((ret = armice_code_exec(ctrl, addr, reg, 13)) < 0) { fprintf(f, "# Error: armice_code_exec()!\n"); return ret; } if ((dbg_status = ctrl->jtag_arm_dbg_status(ctrl->tap)) < 0) { DCC_LOG1(LOG_ERROR, "arm7ice_get_status(): %d", dbg_status); return dbg_status; } if ((dbg_status & ARMICE_ST_DBGACK) != 0) { fprintf(f, "# Core is stopped!!!!!!!\n"); } fprintf(f, " - Wait 50 ms...\n"); uthread_sleep(50); armice_code_stop(ctrl); if (test_save_context(f, ctrl, &ct0) < 0) return -1; arm_show_cpsr(f, ct0.cpsr); arm_show_regs(f, ct0.r); fprintf(f, " - TARGET context, before step:\n"); arm_show_cpsr(f, ct0.cpsr); arm_show_regs(f, ct0.r); show_insn(f, ctrl, &ct0); fprintf(f, " - Step @ 0x%08x:\n", addr); if (ct0.cpsr & ARM_STATE_THUMB) { fprintf(f, " - THUMB step ...\n"); if ((ret = ctrl->thumb_insn_step(ctrl->tap, &ct0)) < 0) { fprintf(f, "# THUMB step error!!!!\n"); return -1; } } else { fprintf(f, " - ARM step ...\n"); if ((ret = ctrl->arm_insn_step(ctrl->tap, &ct0)) < 0) { fprintf(f, "# ARM step error!!!!\n"); return -1; } } if (test_save_context(f, ctrl, &ct1) < 0) return -1; fprintf(f, " - TARGET context, after step:\n"); arm_show_cpsr(f, ct1.cpsr); arm_show_regs(f, ct1.r); show_insn(f, ctrl, &ct1); return 0; }
int main(int argc, char **argv) { int ctlfd, timerfd, alarm_nr, ret, srvfd; char buf[20]; char path[32]; struct event_queue *ev_q; printf("Starting alarm test\n"); /* standard 9ns stuff: clone and read it to get our path, ending up with the * ctlfd and timerfd for #A/aN/{ctl,timer}. if you plan to fork, you can * open CLOEXEC. */ ctlfd = open("#A/clone", O_RDWR | O_CLOEXEC); if (ctlfd < 0) { perror("Can't clone an alarm"); exit(-1); } ret = read(ctlfd, buf, sizeof(buf) - 1); if (ret <= 0) { if (!ret) printf("Got early EOF from ctl\n"); else perror("Can't read ctl"); exit(-1); } buf[ret] = 0; snprintf(path, sizeof(path), "#A/a%s/timer", buf); /* Don't open CLOEXEC if you want to post it to srv later */ timerfd = open(path, O_RDWR); if (timerfd < 0) { perror("Can't open timer"); exit(-1); } /* Since we're doing SPAM_PUBLIC later, we actually don't need a big ev_q. * But someone might copy/paste this and change a flag. */ register_ev_handler(EV_ALARM, handle_alarm, 0); if (!(ev_q = get_big_event_q())) { perror("Failed ev_q"); /* it'll actually PF if malloc fails */ exit(-1); } ev_q->ev_vcore = 0; /* I think this is all the flags we need; gotta write that dissertation * chapter (and event how-to)! We may get more than one event per alarm, if * we have concurrent preempts/yields. */ ev_q->ev_flags = EVENT_IPI | EVENT_SPAM_PUBLIC; /* Register the ev_q for our alarm */ ret = snprintf(path, sizeof(path), "evq %llx", ev_q); ret = write(ctlfd, path, ret); if (ret <= 0) { perror("Failed to write ev_q"); exit(-1); } /* Try to set, then cancel before it should go off */ ret = snprintf(buf, sizeof(buf), "%llx", read_tsc() + sec2tsc(1)); ret = write(timerfd, buf, ret); if (ret <= 0) { perror("Failed to set timer"); exit(-1); } ret = snprintf(buf, sizeof(buf), "cancel"); ret = write(ctlfd, buf, ret); if (ret <= 0) { perror("Failed to cancel timer"); exit(-1); } uthread_sleep(2); printf("No alarm should have fired yet\n"); /* Try to set and receive */ ret = snprintf(buf, sizeof(buf), "%llx", read_tsc() + sec2tsc(1)); ret = write(timerfd, buf, ret); if (ret <= 0) { perror("Failed to set timer"); exit(-1); } uthread_sleep(2); close(ctlfd); /* get crazy: post the timerfd to #s, then sleep (or even try to exit), and * then echo into it remotely! A few limitations: * - if the process is DYING, you won't be able to send an event to it. * - the process won't leave DYING til the srv file is removed. */ srvfd = open("#s/alarmtest", O_WRONLY | O_CREAT | O_EXCL, 0666); if (srvfd < 0) { perror("Failed to open srv file"); exit(-1); } ret = snprintf(buf, sizeof(buf), "%d", timerfd); ret = write(srvfd, buf, ret); if (ret <= 0) { perror("Failed to post timerfd"); exit(-1); } printf("Sleeping for 10 sec, try to echo 111 > '#s/alarmtest' now!\n"); uthread_sleep(10); ret = unlink("#s/alarmtest"); if (ret < 0) { perror("Failed to remove timerfd from #s, proc will never be freed"); exit(-1); } printf("Done\n"); return 0; }