static int sendfile_complete_cb (eio_req *req) { callback_data_t *data = (callback_data_t *) req->data; ssize_t length = req->result; if (length == -1) { if (req->errorno == EAGAIN || req->errorno == EINTR) { queue_sendfile (data); return 0; } eio_close (data->fd, 0, sendfile_close_cb, data); return 0; } if (length + data->offset < data->length) { data->offset += length; eio_sendfile (data->socket, data->fd, data->offset, data->length - data->offset, 0, sendfile_complete_cb, data); return 0; } eio_close (data->fd, 0, sendfile_close_cb, data); return 0; }
/* start simulation, program loaded, processor precise state initialized */ void sim_main(void) { md_inst_t inst; register md_addr_t addr; enum md_opcode op; register bool_t is_write; enum md_fault_type fault; /* set up initial default next PC */ regs.regs_NPC = regs.regs_PC + sizeof(md_inst_t); /* check for DLite debugger entry condition */ if (dlite_check_break(regs.regs_PC, /* !access */0, /* addr */0, 0, 0)) dlite_main(regs.regs_PC - sizeof(md_inst_t), regs.regs_PC, sim_num_insn, ®s, mem); /* fast forward simulator loop, performs functional simulation for FASTFWD_COUNT insts, then turns on performance (timing) simulation */ if (fastfwd_count > 0) { int icount; fprintf(stderr, "sim: ** fast forwarding %d insts **\n", fastfwd_count); fastfwding = TRUE; for (icount=0; icount < fastfwd_count; icount++) { /* maintain $r0 semantics */ regs.regs_R[MD_REG_ZERO] = 0; #ifdef TARGET_ALPHA regs.regs_F.d[MD_REG_ZERO] = 0.0; #endif /* TARGET_ALPHA */ /* get the next instruction to execute */ inst = __UNCHK_MEM_READ(mem, regs.regs_PC, md_inst_t); /* set default reference address */ addr = 0; is_write = FALSE; /* set default fault - none */ fault = md_fault_none; /* decode the instruction */ MD_SET_OPCODE(op, inst); /* execute the instruction */ switch (op) { #define DEFINST(OP,MSK,NAME,OPFORM,RES,FLAGS,O1,O2,I1,I2,I3) \ case OP: \ SYMCAT(OP,_IMPL); \ break; #define DEFLINK(OP,MSK,NAME,MASK,SHIFT) \ case OP: \ panic("attempted to execute a linking opcode"); #define CONNECT(OP) #undef DECLARE_FAULT #define DECLARE_FAULT(FAULT) \ { fault = (FAULT); break; } #include "machine.def" default: panic("attempted to execute a bogus opcode"); } if (fault != md_fault_none) fatal("fault (%d) detected @ 0x%08p", fault, regs.regs_PC); /* update memory access stats */ if (MD_OP_FLAGS(op) & F_MEM) { if (MD_OP_FLAGS(op) & F_STORE) is_write = TRUE; } /* check for DLite debugger entry condition */ if (dlite_check_break(regs.regs_NPC, is_write ? ACCESS_WRITE : ACCESS_READ, addr, sim_num_insn, sim_num_insn)) dlite_main(regs.regs_PC, regs.regs_NPC, sim_num_insn, ®s, mem); /* go to the next instruction */ regs.regs_PC = regs.regs_NPC; regs.regs_NPC += sizeof(md_inst_t); } } fastfwding = FALSE; if (trace_fd != NULL) { fprintf(stderr, "sim: writing EIO file initial checkpoint...\n"); if (eio_write_chkpt(®s, mem, trace_fd) != -1) panic("checkpoint code is broken"); } fprintf(stderr, "sim: ** starting functional simulation **\n"); /* set up initial default next PC */ regs.regs_NPC = regs.regs_PC + sizeof(md_inst_t); while (TRUE) { /* maintain $r0 semantics */ regs.regs_R[MD_REG_ZERO] = 0; #ifdef TARGET_ALPHA regs.regs_F.d[MD_REG_ZERO] = 0.0; #endif /* TARGET_ALPHA */ /* check if checkpoint should be generated here... */ if (chkpt_active && !range_cmp_range1(&chkpt_range, regs.regs_NPC, sim_num_insn, sim_num_insn)) { fprintf(stderr, "sim: writing checkpoint file `%s' @ inst %.0f...\n", chkpt_fname, (double)sim_num_insn); /* write the checkpoint file */ eio_write_chkpt(®s, mem, chkpt_fd); /* close the checkpoint file */ eio_close(chkpt_fd); /* exit jumps to the target set in main() */ longjmp(sim_exit_buf, /* exitcode + fudge */0+1); } /* get the next instruction to execute */ inst = __UNCHK_MEM_READ(mem, regs.regs_PC, md_inst_t); /* keep an instruction count */ sim_num_insn++; /* set default reference address and access mode */ addr = 0; is_write = FALSE; /* set default fault - none */ fault = md_fault_none; /* decode the instruction */ MD_SET_OPCODE(op, inst); /* execute the instruction */ switch (op) { #define DEFINST(OP,MSK,NAME,OPFORM,RES,FLAGS,O1,O2,I1,I2,I3) \ case OP: \ SYMCAT(OP,_IMPL); \ break; #define DEFLINK(OP,MSK,NAME,MASK,SHIFT) \ case OP: \ panic("attempted to execute a linking opcode"); #define CONNECT(OP) #define DECLARE_FAULT(FAULT) \ { fault = (FAULT); break; } #include "machine.def" default: panic("bogus opcode"); } if (fault != md_fault_none) fatal("fault (%d) detected @ 0x%08p", fault, regs.regs_PC); if (MD_OP_FLAGS(op) & F_MEM) { sim_num_refs++; if (MD_OP_FLAGS(op) & F_STORE) is_write = TRUE; } /* check for DLite debugger entry condition */ if (dlite_check_break(regs.regs_NPC, is_write ? ACCESS_WRITE : ACCESS_READ, addr, sim_num_insn, sim_num_insn)) dlite_main(regs.regs_PC, regs.regs_NPC, sim_num_insn, ®s, mem); /* go to the next instruction */ regs.regs_PC = regs.regs_NPC; regs.regs_NPC += sizeof(md_inst_t); /* finish early? */ if (max_insts && sim_num_insn >= max_insts) return; } }
void eio_test() { /* avoid relative paths yourself(!) */ printf("step: %d\n", eio_test_step); int s = eio_test_step++; switch(s) { case 0: eio_mkdir("/tmp/eio-test-dir", 0777, 0, res_cb, "mkdir"); break; case 1: { eio_nop(0, res_cb, "nop"); }; break; case 2: eio_stat("/tmp/eio-test-dir", 0, stat_cb, "stat"); break; case 3: eio_lstat("/tmp/eio-test-dir", 0, stat_cb, "stat"); break; case 4: eio_open("/tmp/eio-test-dir/eio-test-file", O_RDWR | O_CREAT, 0777, 0, open_cb, "open"); break; case 5: eio_symlink("test", "/tmp/eio-test-dir/eio-symlink", 0, res_cb, "symlink"); break; case 6: eio_mknod("/tmp/eio-test-dir/eio-fifo", S_IFIFO, 0, 0, res_cb, "mknod"); break; case 7: eio_utime("/tmp/eio-test-dir", 12345.678, 23456.789, 0, res_cb, "utime"); break; case 8: eio_futime(last_fd, 92345.678, 93456.789, 0, res_cb, "futime"); break; case 9: eio_chown("/tmp/eio-test-dir", getuid(), getgid(), 0, res_cb, "chown"); break; case 10: eio_fchown(last_fd, getuid(), getgid(), 0, res_cb, "fchown"); break; case 11: eio_fchmod(last_fd, 0723, 0, res_cb, "fchmod"); break; case 12: eio_readdir("/tmp/eio-test-dir", 0, 0, readdir_cb, "readdir"); break; case 13: eio_readdir("/nonexistant", 0, 0, readdir_cb, "readdir"); break; case 14: eio_fstat(last_fd, 0, stat_cb, "stat"); break; case 15: { eio_write(last_fd, "test\nfail\n", 10, 4, 0, res_cb, "write"); }; break; case 16: eio_read(last_fd, 0, 8, 0, EIO_PRI_DEFAULT, read_cb, "read"); break; case 17: eio_readlink("/tmp/eio-test-dir/eio-symlink", 0, res_cb, "readlink"); break; case 18: eio_dup2(1, 2, EIO_PRI_DEFAULT, res_cb, "dup"); break; // dup stdout to stderr case 19: eio_chmod("/tmp/eio-test-dir", 0765, 0, res_cb, "chmod"); break; case 20: eio_ftruncate(last_fd, 9, 0, res_cb, "ftruncate"); break; case 21: eio_fdatasync(last_fd, 0, res_cb, "fdatasync"); break; case 22: eio_fsync(last_fd, 0, res_cb, "fsync"); break; case 23: eio_sync(0, res_cb, "sync"); break; case 24: eio_busy(0.5, 0, res_cb, "busy"); break; case 25: eio_sendfile(1, last_fd, 4, 5, 0, res_cb, "sendfile"); break; // write "test\n" to stdout case 26: eio_fstat(last_fd, 0, stat_cb, "stat"); break; case 27: eio_truncate("/tmp/eio-test-dir/eio-test-file", 6, 0, res_cb, "truncate"); break; case 28: eio_readahead(last_fd, 0, 64, 0, res_cb, "readahead"); break; case 29: eio_close(last_fd, 0, res_cb, "close"); break; case 30: eio_link("/tmp/eio-test-dir/eio-test-file", "/tmp/eio-test-dir/eio-test-file-2", 0, res_cb, "link"); break; case 31: eio_rename("/tmp/eio-test-dir/eio-test-file", "/tmp/eio-test-dir/eio-test-file-renamed", 0, res_cb, "rename"); break; case 32: eio_unlink("/tmp/eio-test-dir/eio-fifo", 0, res_cb, "unlink"); break; case 33: eio_unlink("/tmp/eio-test-dir/eio-symlink", 0, res_cb, "unlink"); break; case 34: eio_unlink("/tmp/eio-test-dir/eio-test-file-2", 0, res_cb, "unlink"); break; case 35: eio_unlink("/tmp/eio-test-dir/eio-test-file-renamed", 0, res_cb, "unlink"); break; case 36: eio_rmdir("/tmp/eio-test-dir", 0, res_cb, "rmdir"); break; } }
/* un-initialize simulator-specific state */ void sim_uninit(void) { if (trace_fd != NULL) eio_close(trace_fd); }
int main (void) { printf ("pipe ()\n"); if (pipe (respipe)) abort (); printf ("eio_init ()\n"); if (eio_init (want_poll, done_poll)) abort (); do { /* avoid relative paths yourself(!) */ eio_mkdir ("eio-test-dir", 0777, 0, res_cb, "mkdir"); eio_nop (0, res_cb, "nop"); event_loop (); eio_stat ("eio-test-dir", 0, stat_cb, "stat"); eio_lstat ("eio-test-dir", 0, stat_cb, "stat"); eio_open ("eio-test-dir/eio-test-file", O_RDWR | O_CREAT, 0777, 0, open_cb, "open"); eio_symlink ("test", "eio-test-dir/eio-symlink", 0, res_cb, "symlink"); eio_mknod ("eio-test-dir/eio-fifo", S_IFIFO, 0, 0, res_cb, "mknod"); event_loop (); eio_utime ("eio-test-dir", 12345.678, 23456.789, 0, res_cb, "utime"); eio_futime (last_fd, 92345.678, 93456.789, 0, res_cb, "futime"); eio_chown ("eio-test-dir", getuid (), getgid (), 0, res_cb, "chown"); eio_fchown (last_fd, getuid (), getgid (), 0, res_cb, "fchown"); eio_fchmod (last_fd, 0723, 0, res_cb, "fchmod"); eio_readdir ("eio-test-dir", 0, 0, readdir_cb, "readdir"); eio_readdir ("/nonexistant", 0, 0, readdir_cb, "readdir"); eio_fstat (last_fd, 0, stat_cb, "stat"); eio_write (last_fd, "test\nfail\n", 10, 4, 0, res_cb, "write"); event_loop (); eio_read (last_fd, 0, 8, 0, EIO_PRI_DEFAULT, read_cb, "read"); eio_readlink ("eio-test-dir/eio-symlink", 0, res_cb, "readlink"); event_loop (); eio_dup2 (1, 2, EIO_PRI_DEFAULT, res_cb, "dup"); // dup stdout to stderr eio_chmod ("eio-test-dir", 0765, 0, res_cb, "chmod"); eio_ftruncate (last_fd, 9, 0, res_cb, "ftruncate"); eio_fdatasync (last_fd, 0, res_cb, "fdatasync"); eio_fsync (last_fd, 0, res_cb, "fsync"); eio_sync (0, res_cb, "sync"); eio_busy (0.5, 0, res_cb, "busy"); event_loop (); eio_sendfile (1, last_fd, 4, 5, 0, res_cb, "sendfile"); // write "test\n" to stdout eio_fstat (last_fd, 0, stat_cb, "stat"); event_loop (); eio_truncate ("eio-test-dir/eio-test-file", 6, 0, res_cb, "truncate"); eio_readahead (last_fd, 0, 64, 0, res_cb, "readahead"); event_loop (); eio_close (last_fd, 0, res_cb, "close"); eio_link ("eio-test-dir/eio-test-file", "eio-test-dir/eio-test-file-2", 0, res_cb, "link"); event_loop (); eio_rename ("eio-test-dir/eio-test-file", "eio-test-dir/eio-test-file-renamed", 0, res_cb, "rename"); event_loop (); eio_unlink ("eio-test-dir/eio-fifo", 0, res_cb, "unlink"); eio_unlink ("eio-test-dir/eio-symlink", 0, res_cb, "unlink"); eio_unlink ("eio-test-dir/eio-test-file-2", 0, res_cb, "unlink"); eio_unlink ("eio-test-dir/eio-test-file-renamed", 0, res_cb, "unlink"); event_loop (); eio_rmdir ("eio-test-dir", 0, res_cb, "rmdir"); event_loop (); } while (0); return 0; }