void dc_controller_device::maple_w(const UINT32 *data, UINT32 in_size) { switch(data[0] & 0xff) { case 0x01: // Device request reply_start(5, 0x20, 29); fixed_status(reply_buffer+1); reply_ready_with_delay(); break; case 0x02: // All status request reply_start(6, 0x20, 49); fixed_status(reply_buffer+1); free_status(reply_buffer+29); reply_ready_with_delay(); break; case 0x03: // reset - we're stateless where it matters reply_start(7, 0x20, 0); reply_ready_with_delay(); break; case 0x09: // get condition if(1 || (in_size >= 2 && data[1] == 0x01000000)) { reply_start(8, 0x20, 4); read(reply_buffer+1); reply_ready_with_delay(); } break; } }
/* * The worst case solver assigns all tasks to one processor. */ int worstcase_solver(char *stg_filename, char *ssf_filename) { int malloced; int freed; struct stg *tg; struct ssf_status *status; struct ssf *schedule; int ok; int tlist[] = { 2, 3, 4}; printf("** Worst Case Solver\n"); /* Allocate data structures. */ malloced = 0; freed = 0; tg = new_task_graph_from_file(stg_filename, &malloced); status = new_status(&malloced); strncpy(status->name, "YASA worstcase", 20); schedule = new_schedule(tg, &malloced); printf("malloced %d bytes\n", malloced); /* Solve. */ print_task_graph(tg); printf("twiddle. twiddle, crunch, crunch..\n"); ok = is_tinsert_ok(tg, 1, 0, tlist); printf("is_tinsert_ok = %u\n", ok); print_schedule(schedule); write_schedule_to_file(ssf_filename, schedule, status); /* Free data structures. */ free_schedule(schedule, &freed); free_status(status, &freed); free_task_graph(tg, &freed); printf("freed %d bytes => ", freed); if (malloced == freed) printf("OK.\n"); else { printf("Error: malloced != freed!\n"); return (1); } return (0); }
/* * This routine seizes task putting it into a special * state where we can manipulate the task via ptrace * interface, and finally we can detach ptrace out of * of it so the task would not know if it was saddled * up with someone else. */ int compel_wait_task(int pid, int ppid, int (*get_status)(int pid, struct seize_task_status *, void *), void (*free_status)(int pid, struct seize_task_status *, void *), struct seize_task_status *ss, void *data) { siginfo_t si; int status, nr_sigstop; int ret = 0, ret2, wait_errno = 0; /* * It's ugly, but the ptrace API doesn't allow to distinguish * attaching to zombie from other errors. Thus we have to parse * the target's /proc/pid/stat. Sad, but parse whatever else * we might need at that early point. */ try_again: ret = wait4(pid, &status, __WALL, NULL); if (ret < 0) { /* * wait4() can expectedly fail only in a first time * if a task is zombie. If we are here from try_again, * this means that we are tracing this task. * * So here we can be only once in this function. */ wait_errno = errno; } ret2 = get_status(pid, ss, data); if (ret2) goto err; if (ret < 0 || WIFEXITED(status) || WIFSIGNALED(status)) { if (ss->state != 'Z') { if (pid == getpid()) pr_err("The criu itself is within dumped tree.\n"); else pr_err("Unseizable non-zombie %d found, state %c, err %d/%d\n", pid, ss->state, ret, wait_errno); return -1; } if (ret < 0) return COMPEL_TASK_ZOMBIE; else return COMPEL_TASK_DEAD; } if ((ppid != -1) && (ss->ppid != ppid)) { pr_err("Task pid reused while suspending (%d: %d -> %d)\n", pid, ppid, ss->ppid); goto err; } if (!WIFSTOPPED(status)) { pr_err("SEIZE %d: task not stopped after seize\n", pid); goto err; } ret = ptrace(PTRACE_GETSIGINFO, pid, NULL, &si); if (ret < 0) { pr_perror("SEIZE %d: can't read signfo", pid); goto err; } if (PTRACE_SI_EVENT(si.si_code) != PTRACE_EVENT_STOP) { /* * Kernel notifies us about the task being seized received some * event other than the STOP, i.e. -- a signal. Let the task * handle one and repeat. */ if (ptrace(PTRACE_CONT, pid, NULL, (void *)(unsigned long)si.si_signo)) { pr_perror("Can't continue signal handling, aborting"); goto err; } ret = 0; if (free_status) free_status(pid, ss, data); goto try_again; } if (ss->seccomp_mode != SECCOMP_MODE_DISABLED && ptrace_suspend_seccomp(pid) < 0) goto err; nr_sigstop = 0; if (ss->sigpnd & (1 << (SIGSTOP - 1))) nr_sigstop++; if (ss->shdpnd & (1 << (SIGSTOP - 1))) nr_sigstop++; if (si.si_signo == SIGSTOP) nr_sigstop++; if (nr_sigstop) { if (skip_sigstop(pid, nr_sigstop)) goto err_stop; return COMPEL_TASK_STOPPED; } if (si.si_signo == SIGTRAP) return COMPEL_TASK_ALIVE; else { pr_err("SEIZE %d: unsupported stop signal %d\n", pid, si.si_signo); goto err; } err_stop: kill(pid, SIGSTOP); err: if (ptrace(PTRACE_DETACH, pid, NULL, NULL)) pr_perror("Unable to detach from %d", pid); return -1; }
/* * Sequential version. */ int seqsa_solver(char *stg_filename, char *ssf_filename) { int malloced; int freed; int malloced_initial; int freed_initial; int malloced_select; int freed_select; struct stg *tg; struct ssf_status *status; struct ssf *schedule; double eps; unsigned seed; int i; double t0; double t; struct iss *alpha; /* present solution */ struct iss *beta; /* neighbour solution of alpha */ double cost_alpha; double cost_beta; double r; double bf; /* Boltzmann Factor p(alpha -> beta) */ printf("** Sequential Simulated Annealing Solver\n"); /* Allocate data structures. */ malloced = 0; freed = 0; tg = new_task_graph_from_file(stg_filename, &malloced); status = new_status(&malloced); strncpy(status->name, "YASA Sequential", 20); eps = 1e-3; seed = 0; t0 = 1000.0; alpha = NULL; beta = NULL; /* Solve. */ srand(seed); print_task_graph(tg); malloced_initial = 0; freed_initial = 0; alpha = create_initial_solution(tg, &malloced_initial, &freed_initial); printf("malloced %d bytes for initial solution\n", malloced_initial); printf("freed %d bytes for initial solution\n", freed_initial); printf("difference: %d bytes\n", malloced_initial - freed_initial); cost_alpha = cost(tg, alpha); i = 0; t = t0; while (t > eps) { printf("i = %d, t = %f\n", i, t); malloced_select = 0; freed_select = 0; beta = select_neighbour(tg, alpha, &malloced_select, &freed_select); printf("malloced %d bytes for selection\n", malloced_select); printf("freed %d bytes for selection\n", freed_select); printf("difference: %d bytes\n", malloced_select - freed_select); cost_beta = cost(tg, beta); if (cost_beta <= cost_alpha) { /* TODO alpha := beta */ cost_alpha = cost_beta; } else { r = get_random_r(); /* r from (0, 1) */ bf = boltzmann_factor(t, cost_alpha, cost_beta); printf("r = %f, bf = %f\n", r, bf); if (r < bf) { /* TODO alpha := beta */ cost_alpha = cost_beta; } } i++; t = new_temp(t, i); } printf("stopping at i = %d, t = %f.\n", i, t); /* alpha to schedule */ //schedule = new_schedule(tg, alpha, &malloced); schedule = new_schedule(tg, &malloced); printf("malloced %d bytes\n", malloced); /* Display Results */ print_schedule(schedule); write_schedule_to_file(ssf_filename, schedule, status); /* Free data structures. */ free_schedule(schedule, &freed); // TODO free initial solution free_status(status, &freed); free_task_graph(tg, &freed); printf("freed %d bytes => ", freed); if (malloced == freed) printf("OK.\n"); else { printf("Error: malloced != freed!\n"); return (1); } return (0); }