int numDecodings(string s) { if (0 == s.length()) { return 0; } vector<int> save_vec(s.length() + 1, -1); return _tryCurStr(s, save_vec); }
/* * Finish a fork operation, with process p2 nearly set up. */ void cpu_fork(struct proc *p1, struct proc *p2, void *stack, size_t stacksize, void (*func)(void *), void *arg) { struct trapframe *tf; struct callframe *cf; struct switchframe *sf; caddr_t stktop1, stktop2; extern void fork_trampoline(void); struct pcb *pcb = &p2->p_addr->u_pcb; struct cpu_info *ci = curcpu(); if (p1 == ci->ci_fpuproc) save_fpu(); *pcb = p1->p_addr->u_pcb; #ifdef ALTIVEC if (p1->p_addr->u_pcb.pcb_vr != NULL) { if (p1 == ci->ci_vecproc) save_vec(p1); pcb->pcb_vr = pool_get(&ppc_vecpl, PR_WAITOK); *pcb->pcb_vr = *p1->p_addr->u_pcb.pcb_vr; } else pcb->pcb_vr = NULL; #endif /* ALTIVEC */ pcb->pcb_pm = p2->p_vmspace->vm_map.pmap; pmap_extract(pmap_kernel(), (vaddr_t)pcb->pcb_pm, (paddr_t *)&pcb->pcb_pmreal); /* * Setup the trap frame for the new process */ stktop1 = (caddr_t)trapframe(p1); stktop2 = (caddr_t)trapframe(p2); bcopy(stktop1, stktop2, sizeof(struct trapframe)); /* * If specified, give the child a different stack. */ if (stack != NULL) { tf = trapframe(p2); tf->fixreg[1] = (register_t)stack + stacksize; } stktop2 = (caddr_t)((u_long)stktop2 & ~15); /* Align stack pointer */ /* * There happens to be a callframe, too. */ cf = (struct callframe *)stktop2; cf->lr = (int)fork_trampoline; /* * Below the trap frame, there is another call frame: */ stktop2 -= 16; cf = (struct callframe *)stktop2; cf->r31 = (register_t)func; cf->r30 = (register_t)arg; /* * Below that, we allocate the switch frame: */ /* must match SFRAMELEN in genassym */ stktop2 -= roundup(sizeof *sf, 16); sf = (struct switchframe *)stktop2; bzero((void *)sf, sizeof *sf); /* just in case */ sf->sp = (int)cf; sf->user_sr = pmap_kernel()->pm_sr[PPC_USER_SR]; /* just in case */ pcb->pcb_sp = (int)stktop2; }
void trap(struct trapframe *frame) { struct thread *td; struct proc *p; #ifdef KDTRACE_HOOKS uint32_t inst; #endif int sig, type, user; u_int ucode; ksiginfo_t ksi; PCPU_INC(cnt.v_trap); td = curthread; p = td->td_proc; type = ucode = frame->exc; sig = 0; user = frame->srr1 & PSL_PR; CTR3(KTR_TRAP, "trap: %s type=%s (%s)", td->td_name, trapname(type), user ? "user" : "kernel"); #ifdef KDTRACE_HOOKS /* * A trap can occur while DTrace executes a probe. Before * executing the probe, DTrace blocks re-scheduling and sets * a flag in its per-cpu flags to indicate that it doesn't * want to fault. On returning from the probe, the no-fault * flag is cleared and finally re-scheduling is enabled. * * If the DTrace kernel module has registered a trap handler, * call it and if it returns non-zero, assume that it has * handled the trap and modified the trap frame so that this * function can return normally. */ if (dtrace_trap_func != NULL && (*dtrace_trap_func)(frame, type) != 0) return; #endif if (user) { td->td_pticks = 0; td->td_frame = frame; if (td->td_cowgen != p->p_cowgen) thread_cow_update(td); /* User Mode Traps */ switch (type) { case EXC_RUNMODETRC: case EXC_TRC: frame->srr1 &= ~PSL_SE; sig = SIGTRAP; ucode = TRAP_TRACE; break; #ifdef __powerpc64__ case EXC_ISE: case EXC_DSE: if (handle_user_slb_spill(&p->p_vmspace->vm_pmap, (type == EXC_ISE) ? frame->srr0 : frame->dar) != 0){ sig = SIGSEGV; ucode = SEGV_MAPERR; } break; #endif case EXC_DSI: case EXC_ISI: sig = trap_pfault(frame, 1); if (sig == SIGSEGV) ucode = SEGV_MAPERR; break; case EXC_SC: syscall(frame); break; case EXC_FPU: KASSERT((td->td_pcb->pcb_flags & PCB_FPU) != PCB_FPU, ("FPU already enabled for thread")); enable_fpu(td); break; case EXC_VEC: KASSERT((td->td_pcb->pcb_flags & PCB_VEC) != PCB_VEC, ("Altivec already enabled for thread")); enable_vec(td); break; case EXC_VSX: KASSERT((td->td_pcb->pcb_flags & PCB_VSX) != PCB_VSX, ("VSX already enabled for thread")); if (!(td->td_pcb->pcb_flags & PCB_VEC)) enable_vec(td); if (!(td->td_pcb->pcb_flags & PCB_FPU)) save_fpu(td); td->td_pcb->pcb_flags |= PCB_VSX; enable_fpu(td); break; case EXC_VECAST_G4: case EXC_VECAST_G5: /* * We get a VPU assist exception for IEEE mode * vector operations on denormalized floats. * Emulating this is a giant pain, so for now, * just switch off IEEE mode and treat them as * zero. */ save_vec(td); td->td_pcb->pcb_vec.vscr |= ALTIVEC_VSCR_NJ; enable_vec(td); break; case EXC_ALI: if (fix_unaligned(td, frame) != 0) { sig = SIGBUS; ucode = BUS_ADRALN; } else frame->srr0 += 4; break; case EXC_DEBUG: /* Single stepping */ mtspr(SPR_DBSR, mfspr(SPR_DBSR)); frame->srr1 &= ~PSL_DE; frame->cpu.booke.dbcr0 &= ~(DBCR0_IDM || DBCR0_IC); sig = SIGTRAP; ucode = TRAP_TRACE; break; case EXC_PGM: /* Identify the trap reason */ #ifdef AIM if (frame->srr1 & EXC_PGM_TRAP) { #else if (frame->cpu.booke.esr & ESR_PTR) { #endif #ifdef KDTRACE_HOOKS inst = fuword32((const void *)frame->srr0); if (inst == 0x0FFFDDDD && dtrace_pid_probe_ptr != NULL) { struct reg regs; fill_regs(td, ®s); (*dtrace_pid_probe_ptr)(®s); break; } #endif sig = SIGTRAP; ucode = TRAP_BRKPT; } else { sig = ppc_instr_emulate(frame, td->td_pcb); if (sig == SIGILL) { if (frame->srr1 & EXC_PGM_PRIV) ucode = ILL_PRVOPC; else if (frame->srr1 & EXC_PGM_ILLEGAL) ucode = ILL_ILLOPC; } else if (sig == SIGFPE) ucode = FPE_FLTINV; /* Punt for now, invalid operation. */ } break; case EXC_MCHK: /* * Note that this may not be recoverable for the user * process, depending on the type of machine check, * but it at least prevents the kernel from dying. */ sig = SIGBUS; ucode = BUS_OBJERR; break; default: trap_fatal(frame); } } else { /* Kernel Mode Traps */ KASSERT(cold || td->td_ucred != NULL, ("kernel trap doesn't have ucred")); switch (type) { #ifdef KDTRACE_HOOKS case EXC_PGM: if (frame->srr1 & EXC_PGM_TRAP) { if (*(uint32_t *)frame->srr0 == EXC_DTRACE) { if (dtrace_invop_jump_addr != NULL) { dtrace_invop_jump_addr(frame); return; } } } break; #endif #ifdef __powerpc64__ case EXC_DSE: if ((frame->dar & SEGMENT_MASK) == USER_ADDR) { __asm __volatile ("slbmte %0, %1" :: "r"(td->td_pcb->pcb_cpu.aim.usr_vsid), "r"(USER_SLB_SLBE)); return; } break; #endif case EXC_DSI: if (trap_pfault(frame, 0) == 0) return; break; case EXC_MCHK: if (handle_onfault(frame)) return; break; default: break; } trap_fatal(frame); }
int main( int argc, char* argv[] ) { int writeOutX = 0; int n, k; int maxiterations = 1000; int niters=0; double norm; double* b; double* x; double time; double t1, t2; MPI_Init( &argc, &argv ); MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &size); // Read command line args. // 1st case runs model problem, 2nd Case allows you to specify your own b vector if ( argc == 3 ) { k = atoi( argv[1] ); n = k*k; // each processor calls cs240_getB to build its own part of the b vector! } else if ( !strcmp( argv[1], "-i" ) && argc == 4 ) { b = load_vec( argv[2], &k ); } else { printf( "\nCGSOLVE Usage: \n\t" "Model Problem:\tmpirun -np [number_procs] cgsolve [k] [output_1=y_0=n]\n\t" "Custom Input:\tmpirun -np [number_procs] cgsolve -i [input_filename] [output_1=y_0=n]\n\n"); exit(0); } writeOutX = atoi( argv[argc-1] ); // Write X to file if true, do not write if unspecified. // Start Timer t1 = MPI_Wtime(); // CG Solve here! x = cgsolve(k); // End Timer t2 = MPI_Wtime(); printf("TEST: %s\n", cs240_verify(x, k, 0.0) ? "PASSED" : "FAILED"); if ( writeOutX ) { save_vec( k, x ); } // Output printf( "Problem size (k): %d\n",k); if(niters>0){ printf( "Norm of the residual after %d iterations: %lf\n",niters,norm); } printf( "Elapsed time during CGSOLVE: %lf\n", t2-t1); // Deallocate if(niters > 0){ free(b); } if(niters > 0){ free(x); } MPI_Finalize(); return 0; }