int sem_down(struct proc *p, int sem) { if (sem < 0) { fprintf(stderr, "sem_down: Invalid semaphor (pid %u)\n", p->pid); return 1; } switch (sem_p(sem)) { case -1: fprintf(stderr, "sem_down: error putting semaphor down (pid %u)\n", p->pid); return 1; case 0: return 0; case 1: if (retry_op(p) != 0) { fprintf(stderr, "sem_down: error resetting IC (pid %u)\n", p->pid); return 1; } sched_suspend(p->pid); if (insert_proc(&sem_wq[sem], p) != 0) { fprintf(stderr, "sem_down: error adding self to wait queue (pid %u)\n", p->pid); return 1; } return 0; default: fprintf(stderr, "sem_down: unexpected value returned from p() (pid %u)\n", p->pid); return 1; } }
bool emu_suspend(const char *file) { gui_busy_raii gui_busy; FILE *fp = fopen_utf8(file, "wb"); if(!fp) return false; int dupfd = dup(fileno(fp)); fclose(fp); fp = nullptr; // gzdopen takes ownership of the fd gzFile gzf = gzdopen(dupfd, "wb"); if(!gzf) { close(dupfd); return false; } size_t size = sizeof(emu_snapshot) + flash_suspend_flexsize(); auto snapshot = (struct emu_snapshot *) malloc(size); if(!snapshot) { gzclose(gzf); return false; } snapshot->product = product; snapshot->asic_user_flags = asic_user_flags; // TODO: Max length strncpy(snapshot->path_boot1, path_boot1.c_str(), sizeof(snapshot->path_boot1) - 1); strncpy(snapshot->path_flash, path_flash.c_str(), sizeof(snapshot->path_flash) - 1); if(!flash_suspend(snapshot) || !cpu_suspend(snapshot) || !sched_suspend(snapshot) || !memory_suspend(snapshot)) { free(snapshot); gzclose(gzf); return false; } snapshot->sig = SNAPSHOT_SIG; snapshot->version = SNAPSHOT_VER; bool success = (size_t) gzwrite(gzf, snapshot, size) == size; free(snapshot); gzclose(gzf); return success; }