int kcinth() { u16 segment, offset; int a,b,c,d, r; segment = running->uss; offset = running->usp; a = get_word(segment, offset + 2*PA); b = get_word(segment, offset + 2*PB); c = get_word(segment, offset + 2*PC); d = get_word(segment, offset + 2*PD); /*printf("interupthandler a = %d\n", a); printf("b = %d\n", b); printf("string: %s\n", c); printf("n = %d\n", d);*/ switch(a){ case 0 : r = running->pid; break; case 1 : r = do_ps(); break; case 2 : r = kchname(b); break; case 3 : r = kmode(); break; case 4 : r = tswitch(); break; case 5 : r = do_wait(b); break; case 6 : r = do_exit(b); break; case 7 : r = fork(); break; case 8 : r = exec(b); break; /****** these are YOUR pipe functions ************/ case 30 : r = kpipe(b); break; case 31 : r = read_pipe(b,c,d); break; case 32 : r = write_pipe(b,c,d); break; case 33 : r = close_pipe(b); break; case 34 : r = pfd(); break; /**************** end of pipe functions ***********/ case 90: r = getc(); break; case 91: color=running->pid+11; r = putc(b); break; case 99: do_exit(b); break; default: printf("invalid syscall # : %d\n", a); } //printf("interupthandler r = %d\n", r); //getc(); put_word(r, segment, offset + 2*AX); }
void excrate_handle(struct excrate *e) { assert(e->pid != 0); if (e->pe == NULL) return; if (e->pe->revents == 0) return; if (read_from_pipe(e) != -1) return; do_wait(e); fire(&e->completion, NULL); list_del(&e->rig); excrate_release(e); /* may invalidate e */ }
void gomp_barrier_wait_end (gomp_barrier_t *bar, gomp_barrier_state_t state) { if (__builtin_expect (state & BAR_WAS_LAST, 0)) { /* Next time we'll be awaiting TOTAL threads again. */ bar->awaited = bar->total; __atomic_store_n (&bar->generation, bar->generation + BAR_INCR, MEMMODEL_RELEASE); futex_wake ((int *) &bar->generation, INT_MAX); } else { do do_wait ((int *) &bar->generation, state); while (__atomic_load_n (&bar->generation, MEMMODEL_ACQUIRE) == state); } }
void gomp_team_barrier_wait_end (gomp_barrier_t *bar, gomp_barrier_state_t state) { unsigned int generation, gen; if (__builtin_expect (state & BAR_WAS_LAST, 0)) { /* Next time we'll be awaiting TOTAL threads again. */ struct gomp_thread *thr = gomp_thread (); struct gomp_team *team = thr->ts.team; bar->awaited = bar->total; team->work_share_cancelled = 0; if (__builtin_expect (team->task_count, 0)) { gomp_barrier_handle_tasks (state); state &= ~BAR_WAS_LAST; } else { state &= ~BAR_CANCELLED; state += BAR_INCR - BAR_WAS_LAST; __atomic_store_n (&bar->generation, state, MEMMODEL_RELEASE); futex_wake ((int *) &bar->generation, INT_MAX); return; } } generation = state; state &= ~BAR_CANCELLED; do { do_wait ((int *) &bar->generation, generation); gen = __atomic_load_n (&bar->generation, MEMMODEL_ACQUIRE); if (__builtin_expect (gen & BAR_TASK_PENDING, 0)) { gomp_barrier_handle_tasks (state); gen = __atomic_load_n (&bar->generation, MEMMODEL_ACQUIRE); } generation |= gen & BAR_WAITING_FOR_TASK; } while (gen != state + BAR_INCR); }
static waitres_t discard_wait(ptrace_context *ctx) { for(;;) { waitres_t wres = do_wait(ctx, false); switch (wres) { case WR_NOTHING: case WR_FINISHED: case WR_NEED_DETACH: return wres; case WR_STOPPED: ptrace_verbose(PTRACE_CONT, ctx->pid, 0, ctx->stop_signal == SIGSTOP ? 0 : ctx->stop_signal); break; } } }
int kcinth() { u16 segment, offset; int a,b,c,d, r; segment = running->uss; offset = running->usp; a = get_word(segment, offset + 2*PA); b = get_word(segment, offset + 2*PB); c = get_word(segment, offset + 2*PC); d = get_word(segment, offset + 2*PD); switch(a){ case 0 : r = running->pid; break; case 1 : r = do_ps(); break; case 2 : r = chname(b); break; case 3 : r = kmode(); break; case 4 : r = tswitch(); break; case 5 : r = do_wait(b); break; case 6 : r = do_exit(b); break; case 7 : r = fork(); break; case 8 : r = exec(b); break; case 9 : r = vfork(); break; case 30 : r = kpipe(b); break; case 31 : r = read_pipe(b,c,d); break; case 32 : r = write_pipe(b,c,d); break; case 33 : r = close_pipe(b); break; case 34 : r = pfd(); break; case 90: r = getc(); break; case 91: color=running->pid+11; r = putc(b); break; case 99: do_exit(b); break; default: printf("invalid syscall # : %d\n", a); } put_word(r, segment, offset + 2*AX); }
void gomp_barrier_wait_end (gomp_barrier_t *bar, gomp_barrier_state_t state) { if (__builtin_expect ((state & 1) != 0, 0)) { /* Next time we'll be awaiting TOTAL threads again. */ bar->awaited = bar->total; atomic_write_barrier (); bar->generation += 4; futex_wake ((int *) &bar->generation, INT_MAX); } else { unsigned int generation = state; do do_wait ((int *) &bar->generation, generation); while (bar->generation == generation); } }
int body() { char c; while(1){ printf("\n\n\n"); ps(); printf("I am Proc %d in body()\n", running->pid); printf("Input a char : [s|q|f|z|a|w]: "); c=getc(); switch(c){ case 's': tswitch(); break; case 'q': do_exit(); break; case 'f': kfork(); break; case 'z': do_sleep(); break; case 'a': do_wakeup(); break; case 'w': do_wait(); break; default : break; } } }
/* Kernel thread */ static int uh_thread(void *data) { struct uh_data *uh = (struct uh_data *)data; while (!kthread_should_stop()) { do_wait(uh); if (kthread_should_stop()) break; do_detect(uh); do_notify(uh); do_done(uh); } D("Exit.\n"); return 0; }
void gomp_team_barrier_wait_end (gomp_barrier_t *bar, gomp_barrier_state_t state) { unsigned int generation, gen; if (__builtin_expect ((state & 1) != 0, 0)) { /* Next time we'll be awaiting TOTAL threads again. */ struct gomp_thread *thr = gomp_thread (); struct gomp_team *team = thr->ts.team; bar->awaited = bar->total; if (__builtin_expect (team->task_count, 0)) { gomp_barrier_handle_tasks (state); state &= ~1; } else { __atomic_store_n (&bar->generation, state + 3, MEMMODEL_RELEASE); futex_wake ((int *) &bar->generation, INT_MAX); return; } } generation = state; do { do_wait ((int *) &bar->generation, generation); gen = __atomic_load_n (&bar->generation, MEMMODEL_ACQUIRE); if (__builtin_expect (gen & 1, 0)) { gomp_barrier_handle_tasks (state); gen = __atomic_load_n (&bar->generation, MEMMODEL_ACQUIRE); } if ((gen & 2) != 0) generation |= 2; } while (gen != state + 4); }
int body() { char c; printf("proc %d resumes to body()\n", running->pid); while(1) { printf("-----------------------------------------\n"); //print freeList; printf("Free List:\n"); printQueue(freeList); // print readyQueue; printf("Ready Queue:\n"); printQueue(readyQueue); // print sleepList; printf("Sleep List:\n"); // printSleepQueue(sleepList); printSleepQueue(sleepList); printf("-----------------------------------------\n"); printf("proc %d[%d] running: parent=%d\n", running->pid, running->priority, running->ppid); printf("type a command [s|f|q|w| u ] : "); c = getc(); printf("%c\n", c); switch(c){ case 's' : do_tswitch(); break; case 'f' : do_kfork(); break; case 'q' : do_exit(); break; case 'w' : do_wait(); break; case 'u' : // printf("Running->uss: %x\n", running->uss); // printf("Running->usp: %x\n", running->usp); goUmode(); break; // let process goUmode } } }
void gomp_set_nest_lock_25 (omp_nest_lock_25_t *lock) { int otid, tid = gomp_tid (); while (1) { otid = __sync_val_compare_and_swap (&lock->owner, 0, tid); if (otid == 0) { lock->count = 1; return; } if (otid == tid) { lock->count++; return; } do_wait (&lock->owner, otid); } }
/** * <Ring 1> The main loop of TASK MM. * *****************************************************************************/ PUBLIC void task_mm() { init_mm(); while (1) { send_recv(RECEIVE, ANY, &mm_msg); int src = mm_msg.source; int reply = 1; int msgtype = mm_msg.type; switch (msgtype) { case FORK: mm_msg.RETVAL = do_fork(); break; case EXIT: do_exit(mm_msg.STATUS); reply = 0; break; case EXEC: mm_msg.RETVAL = do_exec(); break; case WAIT: do_wait(); reply = 0; break; default: dump_msg("MM::unknown msg", &mm_msg); assert(0); break; } if (reply) { mm_msg.type = SYSCALL_RET; send_recv(SEND, src, &mm_msg); } } }
static void do_lipo (int start_outfile_index, const char *out_file) { int i, j, pid; char *errmsg_fmt, *errmsg_arg; /* Populate lipo arguments. */ lipo_argv[0] = "lipo"; lipo_argv[1] = "-create"; lipo_argv[2] = "-o"; lipo_argv[3] = out_file; /* Already 4 lipo arguments are set. Now add all lipo inputs. */ j = 4; for (i = 0; i < num_arches; i++) lipo_argv[j++] = out_files[start_outfile_index + i]; /* Add the NULL at the end. */ lipo_argv[j++] = NULL; #ifdef DEBUG debug_command_line (lipo_argv, j); #endif if (verbose_flag) { for (i = 0; lipo_argv[i]; i++) fprintf (stderr, "%s ", lipo_argv[i]); fprintf (stderr, "\n"); } pid = pexecute (lipo_argv[0], (char *const *)lipo_argv, progname, NULL, &errmsg_fmt, &errmsg_arg, PEXECUTE_SEARCH | PEXECUTE_ONE); if (pid == -1) pfatal_pexecute (errmsg_fmt, errmsg_arg); do_wait (pid, lipo_argv[0]); }
void gomp_set_nest_lock_25 (omp_nest_lock_25_t *lock) { int otid, tid = gomp_tid (); while (1) { otid = 0; if (__atomic_compare_exchange_n (&lock->owner, &otid, tid, false, MEMMODEL_ACQUIRE, MEMMODEL_RELAXED)) { lock->count = 1; return; } if (otid == tid) { lock->count++; return; } do_wait (&lock->owner, otid); } }
int kern_init(void) { extern char edata[], end[]; memset(edata, 0, end - edata); cons_init(); // init the console const char *message = "(THU.CST) os is loading ..."; cprintf("%s\n\n", message); print_kerninfo(); pmm_init(); // init physical memory management pic_init(); // init interrupt controller idt_init(); // init interrupt descriptor table proc_init(); // init process table clock_init(); // init clock interrupt intr_enable(); // enable irq interrupt schedule(); //let init proc run while (do_wait(1, NULL) == 0) { schedule(); } }
int body(){ char c; printf("proc %d resumes to body()\n", running->pid); while(1){ printf("-----------------------------------------\n"); printList("freelist ", freeList); printList("readyQueue", readyQueue); printList("sleepList ", sleepList); printf("-----------------------------------------\n"); printf("proc %d running: parent = %d enter a char [s|f|w|q|u] : ", running->pid, running->parent->pid); c = getc(); printf("%c\n", c); switch(c){ case 's' : do_tswitch(); break; case 'f' : do_kfork(); break; case 'w' : do_wait(0); break; case 'q' : do_exit(100); break; case 'u' : goUmode(); break; } } }
int kcinth() { ushort seg, off, r; int x, y, z, w; seg = running->uss; off = running->usp; x = get_word(seg, off + 2*13); y = get_word(seg, off + 2*14); z = get_word(seg, off + 2*15); w = get_word(seg, off + 2*16); switch(x){ case 0 : r = running->pid; break; case 1 : r = do_ps(); break; case 2 : r = chname(y); break; case 3 : r = kmode(); break; case 4 : r = tswitch(); break; case 5 : r = do_wait(y); break; case 6 : r = do_exit(y); break; case 7 : r = ufork(); break; case 8 : r = exec(y); break; case 9 : r = chcolor(y); break; case 10: r = putc(y); break; case 11: mysleep(y); break; case 99 : do_exit(y); break; default: printf("invalid syscall # : %d\n", x); break; } put_word(r, seg, off + 2*8); }
void gomp_team_barrier_wait_end (gomp_barrier_t *bar, gomp_barrier_state_t state) { unsigned int generation; if (__builtin_expect ((state & 1) != 0, 0)) { /* Next time we'll be awaiting TOTAL threads again. */ struct gomp_thread *thr = gomp_thread (); struct gomp_team *team = thr->ts.team; bar->awaited = bar->total; atomic_write_barrier (); if (__builtin_expect (team->task_count, 0)) { gomp_barrier_handle_tasks (state); state &= ~1; } else { bar->generation = state + 3; futex_wake ((int *) &bar->generation, INT_MAX); return; } } generation = state; do { do_wait ((int *) &bar->generation, generation); if (__builtin_expect (bar->generation & 1, 0)) gomp_barrier_handle_tasks (state); if ((bar->generation & 2)) generation |= 2; } while (bar->generation != state + 4); }
int body() { char c; printf("proc %d resumes to body()\n", running->pid); while(1) { printf("-----------------------------------------\n"); //print freeList; printf("Free List:\n"); printQueue(freeList); // print readyQueue; printf("Ready Queue:\n"); printQueue(readyQueue); // print sleepList; printf("Sleep List:\n"); printSleepQueue(sleepList); printf("-----------------------------------------\n"); printf("proc %d[%d] running: parent=%d\n", running->pid, running->priority, running->ppid); printf("type a char [s|f|q| p|z|a| w ] : "); c = getc(); printf("%c\n", c); switch(c){ case 's' : do_tswitch(); break; case 'f' : do_kfork(); break; case 'q' : do_exit(); break; case 'p' : do_ps(); break; case 'z' : do_sleep(); break; case 'a' : do_wakeup(); break; case 'w' : do_wait(); break; } } }
APR_DECLARE(apr_status_t) apr_thread_cond_timedwait(apr_thread_cond_t *cond, apr_thread_mutex_t *mutex, apr_interval_time_t timeout) { return do_wait(cond, mutex, timeout); }
APR_DECLARE(apr_status_t) apr_thread_cond_wait(apr_thread_cond_t *cond, apr_thread_mutex_t *mutex) { return do_wait(cond, mutex, 0); }
static int InitPortConnections(pscom_socket_t *socket) { char key[50]; unsigned long guard_pmi_key = MAGIC_PMI_KEY; int i; int mpi_errno = MPI_SUCCESS; int pg_rank = MPIDI_Process.my_pg_rank; int pg_size = MPIDI_Process.my_pg_size; char *pg_id = MPIDI_Process.pg_id_name; char *listen_socket; char **psp_port = NULL; /* Distribute my contact information */ snprintf(key, sizeof(key), "psp%d", pg_rank); listen_socket = MPL_strdup(pscom_listen_socket_str(socket)); PMICALL(PMI_KVS_Put(pg_id, key, listen_socket)); #define INIT_VERSION "ps_v5.0" i_version_set(pg_id, pg_rank, INIT_VERSION); PMICALL(PMI_KVS_Commit(pg_id)); PMICALL(PMI_Barrier()); i_version_check(pg_id, pg_rank, INIT_VERSION); init_grank_port_mapping(); /* Get portlist */ psp_port = MPL_malloc(pg_size * sizeof(*psp_port), MPL_MEM_OBJECT); assert(psp_port); for (i = 0; i < pg_size; i++) { char val[100]; unsigned long guard_pmi_value = MAGIC_PMI_VALUE; if (i != pg_rank) { snprintf(key, sizeof(key), "psp%d", i); checked_PMI_KVS_Get(pg_id, key, val, sizeof(val)); /* simple_pmi.c has a bug.(fixed in mpich2-1.0.5) Test for the bugfix: */ assert(guard_pmi_value == MAGIC_PMI_VALUE); assert(guard_pmi_key == MAGIC_PMI_KEY); } else { /* myself: Dont use PMI_KVS_Get, because this fail in the case of no pm (SINGLETON_INIT_BUT_NO_PM) */ strcpy(val, listen_socket); } psp_port[i] = MPL_strdup(val); } /* connect ranks pg_rank..(pg_rank + pg_size/2) */ for (i = 0; i <= pg_size / 2; i++) { int dest = (pg_rank + i) % pg_size; int src = (pg_rank + pg_size - i) % pg_size; if (!i || (pg_rank / i) % 2) { /* connect, accept */ if (do_connect(socket, pg_rank, dest, psp_port[dest])) goto fn_fail; if (!i || src != dest) { do_wait(pg_rank, src); } } else { /* accept, connect */ do_wait(pg_rank, src); if (src != dest) { if (do_connect(socket, pg_rank, dest, psp_port[dest])) goto fn_fail; } } } /* Wait for all connections: (already done?) */ for (i = 0; i < pg_size; i++) { while (!grank2con_get(i)) { pscom_wait_any(); } } /* ToDo: */ pscom_stop_listen(socket); fn_exit: if (psp_port) { for (i = 0; i < pg_size; i++) { MPL_free(psp_port[i]); psp_port[i] = NULL; } MPL_free(psp_port); } MPL_free(listen_socket); return mpi_errno; /* --- */ fn_fail: mpi_errno = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_FATAL, "InitPortConnections", __LINE__, MPI_ERR_OTHER, "**connfailed", 0); goto fn_exit; }
static uint32_t sys_wait(uint32_t arg[]) { int pid = (int)arg[0]; int *store = (int *)arg[1]; return do_wait(pid, store); }
int driWaitForVBlank( __DRIdrawablePrivate *priv, GLboolean * missed_deadline ) { drmVBlank vbl; unsigned original_seq; unsigned deadline; unsigned interval; unsigned diff; *missed_deadline = GL_FALSE; if ( (priv->vblFlags & (VBLANK_FLAG_INTERVAL | VBLANK_FLAG_THROTTLE | VBLANK_FLAG_SYNC)) == 0 || (priv->vblFlags & VBLANK_FLAG_NO_IRQ) != 0 ) { return 0; } /* VBLANK_FLAG_SYNC means to wait for at least one vertical blank. If * that flag is not set, do a fake wait for zero vertical blanking * periods so that we can get the current MSC. * * VBLANK_FLAG_INTERVAL and VBLANK_FLAG_THROTTLE mean to wait for at * least one vertical blank since the last wait. Since do_wait modifies * priv->vblSeq, we have to save the original value of priv->vblSeq for the * VBLANK_FLAG_INTERVAL / VBLANK_FLAG_THROTTLE calculation later. */ original_seq = priv->vblSeq; interval = driGetVBlankInterval(priv); deadline = original_seq + interval; vbl.request.type = DRM_VBLANK_RELATIVE; if ( priv->vblFlags & VBLANK_FLAG_SECONDARY ) { vbl.request.type |= DRM_VBLANK_SECONDARY; } vbl.request.sequence = ((priv->vblFlags & VBLANK_FLAG_SYNC) != 0) ? 1 : 0; if ( do_wait( & vbl, &priv->vblSeq, priv->driScreenPriv->fd ) != 0 ) { return -1; } diff = priv->vblSeq - deadline; /* No need to wait again if we've already reached the target */ if (diff <= (1 << 23)) { *missed_deadline = (priv->vblFlags & VBLANK_FLAG_SYNC) ? (diff > 0) : GL_TRUE; return 0; } /* Wait until the target vertical blank. */ vbl.request.type = DRM_VBLANK_ABSOLUTE; if ( priv->vblFlags & VBLANK_FLAG_SECONDARY ) { vbl.request.type |= DRM_VBLANK_SECONDARY; } vbl.request.sequence = deadline; if ( do_wait( & vbl, &priv->vblSeq, priv->driScreenPriv->fd ) != 0 ) { return -1; } diff = priv->vblSeq - deadline; *missed_deadline = diff > 0 && diff <= (1 << 23); return 0; }
int fprintf_process(pid_t pid) { // attach to the process if (ptrace(PTRACE_ATTACH, pid, NULL, NULL)) { perror("PTRACE_ATTACH"); check_yama(); return -1; } // wait for the process to actually stop if (waitpid(pid, 0, WSTOPPED) == -1) { perror("wait"); return -1; } // save the register state of the remote process struct user_regs_struct oldregs; if (ptrace(PTRACE_GETREGS, pid, NULL, &oldregs)) { perror("PTRACE_GETREGS"); ptrace(PTRACE_DETACH, pid, NULL, NULL); return -1; } void *rip = (void *)oldregs.rip; printf("their %%rip %p\n", rip); // First, we are going to allocate some memory for ourselves so we don't // need // to stop on the remote process' memory. We will do this by directly // invoking // the mmap(2) system call and asking for a single page. struct user_regs_struct newregs; memmove(&newregs, &oldregs, sizeof(newregs)); newregs.rax = 9; // mmap newregs.rdi = 0; // addr newregs.rsi = PAGE_SIZE; // length newregs.rdx = PROT_READ | PROT_EXEC; // prot newregs.r10 = MAP_PRIVATE | MAP_ANONYMOUS; // flags newregs.r8 = -1; // fd newregs.r9 = 0; // offset uint8_t old_word[8]; uint8_t new_word[8]; new_word[0] = 0x0f; // SYSCALL new_word[1] = 0x05; // SYSCALL new_word[2] = 0xff; // JMP %rax new_word[3] = 0xe0; // JMP %rax // insert the SYSCALL instruction into the process, and save the old word if (poke_text(pid, rip, new_word, old_word, sizeof(new_word))) { goto fail; } // set the new registers with our syscall arguments if (ptrace(PTRACE_SETREGS, pid, NULL, &newregs)) { perror("PTRACE_SETREGS"); goto fail; } // invoke mmap(2) if (singlestep(pid)) { goto fail; } // read the new register state, so we can see where the mmap went if (ptrace(PTRACE_GETREGS, pid, NULL, &newregs)) { perror("PTRACE_GETREGS"); return -1; } // this is the address of the memory we allocated void *mmap_memory = (void *)newregs.rax; if (mmap_memory == (void *)-1) { printf("failed to mmap\n"); goto fail; } printf("allocated memory at %p\n", mmap_memory); printf("executing jump to mmap region\n"); if (singlestep(pid)) { goto fail; } if (ptrace(PTRACE_GETREGS, pid, NULL, &newregs)) { perror("PTRACE_GETREGS"); goto fail; } if (newregs.rip == (long)mmap_memory) { printf("successfully jumped to mmap area\n"); } else { printf("unexpectedly jumped to %p\n", (void *)newregs.rip); goto fail; } // Calculate the position of the fprintf routine in the other process' // address // space. This is a little bit tricky because of ASLR on Linux. What we do // is // we find the offset in memory that libc has been loaded in their process, // and then we find the offset in memory that libc has been loaded in our // process. Then we take the delta betwen our fprintf and our libc start, // and // assume that the same delta will apply to the other process. // // For this mechanism to work, this program must be compiled with -fPIC to // ensure that our fprintf has an address relative to the one in libc. // // Additionally, this could fail if libc has been updated since the remote // process has been restarted. This is a pretty unlikely situation, but if // the // remote process has been running for a long time and you update libc, the // offset of the symbols could have changed slightly. void *their_libc = find_library(pid, libc_string); void *our_libc = find_library(getpid(), libc_string); void *their_fprintf = their_libc + ((void *)fprintf - our_libc); FILE *their_stderr = their_libc + ((void *)stderr - our_libc); printf("their libc %p\n", their_libc); printf("their fprintf %p\n", their_libc); printf("their stderr %p\n", their_stderr); // We want to make a call like: // // fprintf(stderr, "instruction pointer = %p\n", rip); // // To do this we're going to do the following: // // * put a CALL instruction into the mmap area that calls fprintf // * put a TRAP instruction right after the CALL // * put the format string right after the TRAP // * use the TRAP to restore the original text/program state // memory we are going to copy into our mmap area uint8_t new_text[32]; memset(new_text, 0, sizeof(new_text)); // insert a CALL instruction size_t offset = 0; new_text[offset++] = 0xe8; // CALL rel32 int32_t fprintf_delta = compute_jmp(mmap_memory, their_fprintf); memmove(new_text + offset, &fprintf_delta, sizeof(fprintf_delta)); offset += sizeof(fprintf_delta); // insert a TRAP instruction new_text[offset++] = 0xcc; // copy our fprintf format string right after the TRAP instruction memmove(new_text + offset, format, strlen(format)); // update the mmap area printf("inserting code/data into the mmap area at %p\n", mmap_memory); if (poke_text(pid, mmap_memory, new_text, NULL, sizeof(new_text))) { goto fail; } if (poke_text(pid, rip, new_word, NULL, sizeof(new_word))) { goto fail; } // set up our registers with the args to fprintf // memmove(&newregs, &oldregs, sizeof(newregs)); newregs.rax = 0; // no vector registers are used newregs.rdi = (long)their_stderr; // pointer to stderr in the caller newregs.rsi = (long)mmap_memory + offset; // pointer to the format string newregs.rdx = oldregs.rip; // the integer we want to print printf("setting the registers of the remote process\n"); if (ptrace(PTRACE_SETREGS, pid, NULL, &newregs)) { perror("PTRACE_SETREGS"); goto fail; } // continue the program, and wait for the trap printf("continuing execution\n"); ptrace(PTRACE_CONT, pid, NULL, NULL); if (do_wait("PTRACE_CONT")) { goto fail; } if (ptrace(PTRACE_GETREGS, pid, NULL, &newregs)) { perror("PTRACE_GETREGS"); goto fail; } newregs.rax = (long)rip; if (ptrace(PTRACE_SETREGS, pid, NULL, &newregs)) { perror("PTRACE_SETREGS"); goto fail; } new_word[0] = 0xff; // JMP %rax new_word[1] = 0xe0; // JMP %rax poke_text(pid, (void *)newregs.rip, new_word, NULL, sizeof(new_word)); printf("jumping back to original rip\n"); if (singlestep(pid)) { goto fail; } if (ptrace(PTRACE_GETREGS, pid, NULL, &newregs)) { perror("PTRACE_GETREGS"); goto fail; } if (newregs.rip == (long)rip) { printf("successfully jumped back to original %%rip at %p\n", rip); } else { printf("unexpectedly jumped to %p (expected to be at %p)\n", (void *)newregs.rip, rip); goto fail; } // unmap the memory we allocated newregs.rax = 11; // munmap newregs.rdi = (long)mmap_memory; // addr newregs.rsi = PAGE_SIZE; // size if (ptrace(PTRACE_SETREGS, pid, NULL, &newregs)) { perror("PTRACE_SETREGS"); goto fail; } // make the system call printf("making call to mmap\n"); if (singlestep(pid)) { goto fail; } if (ptrace(PTRACE_GETREGS, pid, NULL, &newregs)) { perror("PTRACE_GETREGS"); goto fail; } printf("munmap returned with status %llu\n", newregs.rax); printf("restoring old text at %p\n", rip); poke_text(pid, rip, old_word, NULL, sizeof(old_word)); printf("restoring old registers\n"); if (ptrace(PTRACE_SETREGS, pid, NULL, &oldregs)) { perror("PTRACE_SETREGS"); goto fail; } // detach the process printf("detaching\n"); if (ptrace(PTRACE_DETACH, pid, NULL, NULL)) { perror("PTRACE_DETACH"); goto fail; } return 0; fail: poke_text(pid, rip, old_word, NULL, sizeof(old_word)); if (ptrace(PTRACE_DETACH, pid, NULL, NULL)) { perror("PTRACE_DETACH"); } return 1; }
int do_test (int argc, char *argv[]) { struct aiocb64 cbs[10]; struct aiocb64 cbs_fsync; struct aiocb64 *cbp[10]; struct aiocb64 *cbp_fsync[1]; char buf[1000]; size_t cnt; int result = 0; /* Preparation. */ for (cnt = 0; cnt < 10; ++cnt) { cbs[cnt].aio_fildes = fd; cbs[cnt].aio_reqprio = 0; cbs[cnt].aio_buf = memset (&buf[cnt * 100], '0' + cnt, 100); cbs[cnt].aio_nbytes = 100; cbs[cnt].aio_offset = cnt * 100; cbs[cnt].aio_sigevent.sigev_notify = SIGEV_NONE; cbp[cnt] = &cbs[cnt]; } /* First a simple test. */ for (cnt = 10; cnt > 0; ) if (aio_write64 (cbp[--cnt]) < 0 && errno == ENOSYS) { error (0, 0, "no aio support in this configuration"); return 0; } /* Wait 'til the results are there. */ result |= do_wait (cbp, 10, 0); /* Test this. */ result |= test_file (buf, sizeof (buf), fd, "aio_write"); /* Read now as we've written it. */ memset (buf, '\0', sizeof (buf)); /* Issue the commands. */ for (cnt = 10; cnt > 0; ) { --cnt; cbp[cnt] = &cbs[cnt]; aio_read64 (cbp[cnt]); } /* Wait 'til the results are there. */ result |= do_wait (cbp, 10, 0); /* Test this. */ for (cnt = 0; cnt < 1000; ++cnt) if (buf[cnt] != '0' + (cnt / 100)) { result = 1; error (0, 0, "comparison failed for aio_read test"); break; } if (cnt == 1000) puts ("aio_read test ok"); /* Remove the test file contents. */ if (ftruncate64 (fd, 0) < 0) { error (0, errno, "ftruncate failed\n"); result = 1; } /* Test lio_listio. */ for (cnt = 0; cnt < 10; ++cnt) { cbs[cnt].aio_lio_opcode = LIO_WRITE; cbp[cnt] = &cbs[cnt]; } /* Issue the command. */ lio_listio64 (LIO_WAIT, cbp, 10, NULL); /* ...and immediately test it since we started it in wait mode. */ result |= test_file (buf, sizeof (buf), fd, "lio_listio (write)"); /* Test aio_fsync. */ cbs_fsync.aio_fildes = fd; cbs_fsync.aio_sigevent.sigev_notify = SIGEV_NONE; cbp_fsync[0] = &cbs_fsync; /* Remove the test file contents first. */ if (ftruncate64 (fd, 0) < 0) { error (0, errno, "ftruncate failed\n"); result = 1; } /* Write again. */ for (cnt = 10; cnt > 0; ) aio_write64 (cbp[--cnt]); if (aio_fsync64 (O_SYNC, &cbs_fsync) < 0) { error (0, errno, "aio_fsync failed\n"); result = 1; } result |= do_wait (cbp_fsync, 1, 0); /* ...and test since all data should be on disk now. */ result |= test_file (buf, sizeof (buf), fd, "aio_fsync (aio_write)"); /* Test aio_cancel. */ /* Remove the test file contents first. */ if (ftruncate64 (fd, 0) < 0) { error (0, errno, "ftruncate failed\n"); result = 1; } /* Write again. */ for (cnt = 10; cnt > 0; ) aio_write64 (cbp[--cnt]); /* Cancel all requests. */ if (aio_cancel64 (fd, NULL) == -1) printf ("aio_cancel64 (fd, NULL) cannot cancel anything\n"); result |= do_wait (cbp, 10, ECANCELED); /* Another test for aio_cancel. */ /* Remove the test file contents first. */ if (ftruncate64 (fd, 0) < 0) { error (0, errno, "ftruncate failed\n"); result = 1; } /* Write again. */ for (cnt = 10; cnt > 0; ) { --cnt; cbp[cnt] = &cbs[cnt]; aio_write64 (cbp[cnt]); } puts ("finished3"); /* Cancel all requests. */ for (cnt = 10; cnt > 0; ) if (aio_cancel64 (fd, cbp[--cnt]) == -1) /* This is not an error. The request can simply be finished. */ printf ("aio_cancel64 (fd, cbp[%Zd]) cannot be canceled\n", cnt); puts ("finished2"); result |= do_wait (cbp, 10, ECANCELED); puts ("finished"); return result; }
void wait(Lock&) { do_wait(); }
// seg001:09D7 void __pascal far end_sequence() { peel_type* peel; short bgcolor; short color; rect_type rect; short hof_index; short i; color = 0; bgcolor = 15; load_intro(1, &end_sequence_anim, 1); clear_screen_and_sounds(); load_opt_sounds(sound_56_ending_music, sound_56_ending_music); // winning theme play_sound_from_buffer(sound_pointers[sound_56_ending_music]); // winning theme if(offscreen_surface) free_surface(offscreen_surface); // missing in original offscreen_surface = make_offscreen_buffer(&screen_rect); load_title_images(0); current_target_surface = offscreen_surface; draw_image_2(0 /*story frame*/, chtab_title40, 0, 0, 0); draw_image_2(3 /*The tyrant Jaffar*/, chtab_title40, 24, 25, get_text_color(15, color_15_brightwhite, 0x800)); fade_in_2(offscreen_surface, 0x800); pop_wait(timer_0, 900); start_timer(timer_0, 240); draw_image_2(0 /*main title image*/, chtab_title50, 0, 0, 0); transition_ltr(); do_wait(timer_0); for (hof_index = 0; hof_index < hof_count; ++hof_index) { if (hof[hof_index].min < rem_min || (hof[hof_index].min == rem_min && hof[hof_index].tick < rem_tick) ) break; } if (hof_index < MAX_HOF_COUNT && hof_index <= hof_count) { fade_out_2(0x1000); for (i = 5; hof_index + 1 <= i; --i) { hof[i] = hof[i - 1]; } hof[i].name[0] = 0; hof[i].min = rem_min; hof[i].tick = rem_tick; if (hof_count < MAX_HOF_COUNT) { ++hof_count; } draw_image_2(0 /*story frame*/, chtab_title40, 0, 0, 0); draw_image_2(3 /*Prince Of Persia*/, chtab_title50, 24, 24, blitters_10h_transp); show_hof(); offset4_rect_add(&rect, &hof_rects[hof_index], -4, -1, -40, -1); peel = read_peel_from_screen(&rect); if (graphics_mode == gmMcgaVga) { color = 0xBE; bgcolor = 0xB7; } draw_rect(&rect, bgcolor); fade_in_2(offscreen_surface, 0x1800); current_target_surface = onscreen_surface_; while(input_str(&rect, hof[hof_index].name, 24, "", 0, 4, color, bgcolor) <= 0); restore_peel(peel); show_hof_text(&hof_rects[hof_index], -1, 0, hof[hof_index].name); hof_write(); pop_wait(timer_0, 120); current_target_surface = offscreen_surface; draw_image_2(0 /*main title image*/, chtab_title50, 0, 0, blitters_0_no_transp); transition_ltr(); } while (check_sound_playing() && !key_test_quit()) idle(); fade_out_2(0x1000); start_level = 0; start_game(); }
// init_main - the second kernel thread used to create kswapd_main & user_main kernel threads static int init_main(void *arg) { int pid; #ifndef CONFIG_NO_SWAP if ((pid = kernel_thread(kswapd_main, NULL, 0)) <= 0) { panic("kswapd init failed.\n"); } kswapd = find_proc(pid); set_proc_name(kswapd, "kswapd"); #else #warning swapping disabled #endif int ret; char root[] = "disk0:"; if ((ret = vfs_set_bootfs(root)) != 0) { panic("set boot fs failed: %e.\n", ret); } size_t nr_used_pages_store = nr_used_pages(); size_t slab_allocated_store = slab_allocated(); unsigned int nr_process_store = nr_process; pid = kernel_thread(user_main, NULL, 0); if (pid <= 0) { panic("create user_main failed.\n"); } while (do_wait(0, NULL) == 0) { if (nr_process_store == nr_process) { break; } schedule(); } #ifndef CONFIG_NO_SWAP assert(kswapd != NULL); int i; for (i = 0; i < 10; i ++) { if (kswapd->wait_state == WT_TIMER) { wakeup_proc(kswapd); } schedule(); } #endif mbox_cleanup(); fs_cleanup(); kprintf("all user-mode processes have quit, no /bin/sh?.\n"); #ifndef CONFIG_NO_SWAP assert(initproc->cptr == kswapd && initproc->yptr == NULL && initproc->optr == NULL); assert(kswapd->cptr == NULL && kswapd->yptr == NULL && kswapd->optr == NULL); assert(nr_process == 2 + pls_read(lcpu_count)); #else assert(nr_process == 1 + pls_read(lcpu_count)); #endif assert(nr_used_pages_store == nr_used_pages()); assert(slab_allocated_store == slab_allocated()); kprintf("init check memory pass.\n"); return 0; }