char * psi_strdup(const char *str) { char *to; to = psi_malloc((size_t)(strlen(str)+1)); if (to == NULL) return NULL; return strcpy(to, str); }
char * psi_strndup(const char *str, size_t n) { char *to; to = psi_malloc((size_t)(n+1)); if (to == NULL) return NULL; to[n] = '\0'; return strncpy(to, str, n); }
void * psi_calloc(size_t size) { void *value; value = psi_malloc(size); if (value == NULL) return NULL; memset(value, 0, size); return value; }
/** Return list of process environment variables, ending in `\0\0' * * This wraps getevars(3) but allocates the string automatically using * psi_malloc() and guarantees the complete environment is returned. * * Returns -1 in case of an error and -2 if the process is gone. On success * the number of environment variables in the argument list is returned. */ static int mygetevars(struct procentry64 *procent, char **envp) { /* XXX `n' should be `usigned int' and args_sz & i `ssize_t' but getargs() * uses `int' for `args_sz' bizzarly enough. --flub */ char *ptr; int size = 250; /* size of `envp' */ int n; /* number of environment variables */ int r; *envp = (char*)psi_malloc(size); if (*envp == NULL) return -1; r = getevars(procent, sizeof(struct procentry64), *envp, size); if (r < 0) { psi_free(*envp); if (errno == ESRCH) /* proc gone walkies */ return -2; else { PyErr_SetFromErrnoWithFilename(PyExc_OSError, "getevars()"); return -1; } } n = args_complete(*envp, size); while (n < 0) { size += 250; ptr = (char*)psi_realloc(*envp, size); if (ptr == NULL) { psi_free(*envp); return -1; } *envp = ptr; r = getevars(procent, sizeof(struct procentry64), *envp, size); if (r < 0) { psi_free(*envp); if (errno == ESRCH) /* proc gone walkies */ return -2; else { PyErr_SetFromErrnoWithFilename(PyExc_OSError, "getevars()"); return -1; } } n = args_complete(*envp, size); } return n; }
/** Return list of process arguments, ending in `\0\0' * * This wraps getargs(3) but allocates the string automatically using * psi_malloc() and guarantees the complete argument list is returned. * * Returns -1 in case of an error and -2 if the process is gone. On success * the number of arguments in the argument list is returned. */ static int mygetargs(struct procentry64 *procbuff, char **args) { /* XXX nargs should be `usigned int' and args_sz & i `ssize_t' but getargs() * uses int for args_sz bizzarly enough. --flub */ char *ptr; int size = 250; /* size of `args' */ int nargs; int r; *args = (char*)psi_malloc(size); if (*args == NULL) return -1; r = getargs(procbuff, sizeof(struct procentry64), *args, size); if (r < 0) { psi_free(*args); if (errno == ESRCH) /* proc gone walkies */ return -2; else { PyErr_SetFromErrnoWithFilename(PyExc_OSError, "getargs()"); return -1; } } nargs = args_complete(*args, size); while (nargs < 0) { size += 250; ptr = (char*)psi_realloc(*args, size); if (ptr == NULL) { psi_free(*args); return -1; } *args = ptr; r = getargs(procbuff, sizeof(struct procentry64), *args, size); if (r < 0) { psi_free(*args); if (errno == ESRCH) /* proc gone walkies */ return -2; else { PyErr_SetFromErrnoWithFilename(PyExc_OSError, "getargs()"); return -1; } } nargs = args_complete(*args, size); } return nargs; }
static int command_from_argv(char **command, char **argv, int argc){ int i; int command_len = 0; int offset=0; for (i=0; i<argc; i++) command_len += strlen(argv[i]) + 1; *command = psi_malloc(command_len); if (*command == NULL) { return -1; } for (i=0; i<argc; i++) { strcpy(*command+offset, argv[i]); *(*command + offset + strlen(argv[i])) = ' '; offset = offset + strlen(argv[i]) + 1; } *(*command + offset - 1) = '\0'; return 0; }
int load_gadget2(psi_mesh* mesh, const char* filename) { int blksize, p, e, nside, ii, jj, kk, i, j, k; int elemind, locind, vertind; int load_mass; gadget2header header; psi_printf("Loading %s...\n", filename); FILE* f = fopen(filename, "r"); if(!f) { psi_printf("Failed to open %s.\n", filename); return 0; } e = fread(&blksize, sizeof(int), 1, f); e = fread(&header, sizeof(gadget2header), 1, f); e = fread(&blksize, sizeof(int), 1, f); // allocate mesh storage mesh->npart = header.npart[1]; mesh->nelem = header.npart[1]; load_mass = (header.mass[1] == 0); mesh->periodic = 1; mesh->elemtype = PSI_MESH_LINEAR; mesh->dim = 3; for(i = 0; i < 3; ++i) { mesh->box[0].xyz[i] = 0.0; mesh->box[1].xyz[i] = header.BoxSize; } float* tpos = (float*) psi_malloc(mesh->npart*sizeof(psi_rvec)); float* tvel = (float*) psi_malloc(mesh->npart*sizeof(psi_rvec)); int* tid = (int*) psi_malloc(mesh->npart*sizeof(psi_int)); printf("Hubble = %f\n", header.HubbleParam); printf("Box = %f\n", header.BoxSize); printf("load_mass = %d, mass = %f\n", load_mass, header.mass[1]); printf("n_part = %d\n", mesh->npart); // read in position data e = fread(&blksize, sizeof(int), 1, f); psi_assert(blksize==3*mesh->npart*sizeof(float)); e = fread(tpos, 3*sizeof(float), mesh->npart, f); e = fread(&blksize, sizeof(int), 1, f); psi_assert(blksize==3*mesh->npart*sizeof(float)); // read velocities e = fread(&blksize, sizeof(int), 1, f); psi_assert(blksize==3*mesh->npart*sizeof(float)); e = fread(tvel, 3*sizeof(float), mesh->npart, f); e = fread(&blksize, sizeof(int), 1, f); psi_assert(blksize==3*mesh->npart*sizeof(float)); // read ids e = fread(&blksize, sizeof(int), 1, f); psi_assert(blksize==mesh->npart*sizeof(int)); e = fread(tid, sizeof(int), mesh->npart, f); e = fread(&blksize, sizeof(int), 1, f); psi_assert(blksize==mesh->npart*sizeof(int)); // close the input file fclose(f); // make arrays for vertices // NOTE: assumes the arrays have been malloced! for(p = 0; p < mesh->npart; ++p) { mesh->pos[tid[p]].x = tpos[3*p+0]; mesh->pos[tid[p]].y = tpos[3*p+1]; mesh->pos[tid[p]].z = tpos[3*p+2]; mesh->vel[tid[p]].x = tvel[3*p+0]; mesh->vel[tid[p]].y = tvel[3*p+1]; mesh->vel[tid[p]].z = tvel[3*p+2]; mesh->mass[tid[p]] = header.mass[1]/mesh->npart; } psi_free(tpos); psi_free(tvel); psi_free(tid); // now build the mesh connectivity // trilinear elements naturally nside = floor(pow(mesh->npart+0.5, ONE_THIRD)); for(i = 0; i < nside; ++i) for(j = 0; j < nside; ++j) for(k = 0; k < nside; ++k) { elemind = nside*nside*i + nside*j + k; for(ii = 0; ii < 2; ++ii) for(jj = 0; jj < 2; ++jj) for(kk = 0; kk < 2; ++kk) { locind = 4*ii + 2*jj + kk; vertind = nside*nside*((i+ii)%nside) + nside*((j+jj)%nside) + ((k+kk)%nside); mesh->connectivity[8*elemind+locind] = vertind; } } psi_printf("...done.\n"); return 1; }
int load_gevolution(psi_mesh* mesh, const char* filename) { int blksize, p, e, nside, i, j, k; int elemind, locind, vertind, tile_nside; int load_mass; gadget2header header; psi_printf("Loading %s...\n", filename); FILE* f = fopen(filename, "r"); if(!f) { psi_printf("Failed to open %s.\n", filename); return 0; } e = fread(&blksize, sizeof(int), 1, f); e = fread(&header, sizeof(gadget2header), 1, f); e = fread(&blksize, sizeof(int), 1, f); // allocate mesh storage mesh->npart = header.npart[1]; mesh->nelem = header.npart[1]; load_mass = (header.mass[1] == 0); mesh->periodic = 1; mesh->elemtype = PSI_MESH_LINEAR; mesh->dim = 3; for(i = 0; i < 3; ++i) { mesh->box[0].xyz[i] = 0.0; mesh->box[1].xyz[i] = header.BoxSize; } float* tpos = (float*) psi_malloc(mesh->npart*sizeof(psi_rvec)); float* tvel = (float*) psi_malloc(mesh->npart*sizeof(psi_rvec)); long* tid = (long*) psi_malloc(mesh->npart*sizeof(psi_long)); printf("Hubble = %f\n", header.HubbleParam); printf("Box = %f\n", header.BoxSize); printf("z = %f\n", header.redshift); printf("load_mass = %d, mass = %f\n", load_mass, header.mass[1]); printf("n_part = %d\n", mesh->npart); // read in position data e = fread(&blksize, sizeof(int), 1, f); psi_assert(blksize==3*mesh->npart*sizeof(float)); e = fread(tpos, 3*sizeof(float), mesh->npart, f); e = fread(&blksize, sizeof(int), 1, f); psi_assert(blksize==3*mesh->npart*sizeof(float)); // read velocities e = fread(&blksize, sizeof(int), 1, f); psi_assert(blksize==3*mesh->npart*sizeof(float)); e = fread(tvel, 3*sizeof(float), mesh->npart, f); e = fread(&blksize, sizeof(int), 1, f); psi_assert(blksize==3*mesh->npart*sizeof(float)); // read particle ids e = fread(&blksize, sizeof(int), 1, f); psi_assert(blksize==mesh->npart*sizeof(long)); e = fread(tid, sizeof(long), mesh->npart, f); e = fread(&blksize, sizeof(int), 1, f); psi_assert(blksize==mesh->npart*sizeof(long)); // close the input file fclose(f); // make arrays for vertices // NOTE: assumes the arrays have been malloced! for(p = 0; p < mesh->npart; ++p) { mesh->pos[tid[p]].x = tpos[3*p+0]; mesh->pos[tid[p]].y = tpos[3*p+1]; mesh->pos[tid[p]].z = tpos[3*p+2]; mesh->vel[tid[p]].x = tvel[3*p+0]; mesh->vel[tid[p]].y = tvel[3*p+1]; mesh->vel[tid[p]].z = tvel[3*p+2]; mesh->mass[tid[p]] = header.mass[1]/mesh->npart; } psi_free(tpos); psi_free(tvel); psi_free(tid); // generate the mesh connectivity nside = floor(pow(mesh->npart+0.5, ONE_THIRD)); tile_nside = nside/gevolution_ntile; for(p = 0; p < mesh->npart; ++p) { gevolution_lagrangian_cube_indices(p, tile_nside, &mesh->connectivity[8*p]); } psi_printf("...done.\n"); return 1; }
if (to == NULL) return NULL; to[n] = '\0'; return strncpy(to, str, n); } int psi_asprintf(char **ptr, const char *template, ...) { va_list ap; int r; size_t size = 128; char *ptr2; *ptr = (char *)psi_malloc(size); if (*ptr == NULL) { PyErr_NoMemory(); return -1; } va_start(ap, template); r = PyOS_vsnprintf(*ptr, size, template, ap); va_end(ap); if (r < 0) { psi_free(*ptr); *ptr = NULL; PyErr_Format(PyExc_OSError, "PyOS_vsnprintf returned error code: %d", r); return -1; } else if (r > (int)size) {
void psi_do_power_spectrum(psi_grid* grid, psi_real* P, psi_real* kk, psi_real dk, psi_int nbins) { fftw_plan p; fftw_complex* rhok; psi_int ax, i, j, k, ll; psi_dvec halfn, dims; psi_rvec kvec, L; psi_real ksc, zre, zim, kvol, kvolfac; for(ax = 0; ax < 3; ++ax) { dims.ijk[ax] = grid->n.ijk[ax]; halfn.ijk[ax] = dims.ijk[ax]/2 + 1; L.xyz[ax] = grid->window[1].xyz[ax]-grid->window[0].xyz[ax]; } psi_int *cellcount = (psi_int*) psi_malloc(nbins*sizeof(psi_int)); memset(cellcount, 0, nbins*sizeof(psi_int)); // do the FFT and bin the power rhok = (fftw_complex*) fftw_malloc(dims.i*dims.j*halfn.k*sizeof(fftw_complex)); p = fftw_plan_dft_r2c_3d(dims.i, dims.j, dims.k, grid->fields[0], rhok, FFTW_ESTIMATE); fftw_execute(p); fftw_destroy_plan(p); for(i = 0; i < dims.i; ++i) for(j = 0; j < dims.j; ++j) for(k = 0; k < halfn.k; ++k) { // compute wavenumbers (arbitrary units) kvec.x = TWO_PI/L.x * ((i < halfn.i)? i : (i - dims.i)); kvec.y = TWO_PI/L.y * ((j < halfn.j)? j : (j - dims.j)); kvec.z = TWO_PI/L.z * k; ksc = sqrt(kvec.x*kvec.x + kvec.y*kvec.y + kvec.z*kvec.z); // get the index and bin the power ll = floor(ksc/dk); if(ll < nbins) { zre = rhok[dims.j*halfn.k*i + halfn.k*j + k][0]; zim = rhok[dims.j*halfn.k*i + halfn.k*j + k][1]; P[ll] += zre*zre + zim*zim; ++cellcount[ll]; } } fftw_free(rhok); // normalize // the factor of 2 is for the real FFT, // we have only counted the +- mode pairs once //kvolfac = for(ll = 0; ll < nbins; ++ll) { kk[ll] = dk*(ll+0.5); P[ll] *= 2.0/(dims.i*dims.j*dims.k); P[ll] /= cellcount[ll]; //kvol = (FOUR_PI*dk*dk*dk/3.0)*(1+3*ll+3*ll*ll); //P[ll] *= 1.0/kvol; } free(cellcount); }
psi_mountlist_t * psi_arch_mountlist(const int remote) { psi_mountlist_t *ml; psi_mountinfo_t *mounti; struct vmount *mnt; char *vmounts; int vmounts_size = sizeof(struct vmount); int nmounts; int offset = 0; int i; vmounts = psi_malloc(vmounts_size); if (vmounts == NULL) return NULL; nmounts = mntctl(MCTL_QUERY, vmounts_size, vmounts); if (nmounts == 0) { mnt = (struct vmount *)vmounts; vmounts_size = mnt->vmt_revision; psi_free(vmounts); vmounts = psi_malloc(vmounts_size); if (vmounts == NULL) return NULL; nmounts = mntctl(MCTL_QUERY, vmounts_size, vmounts); } if (nmounts == -1) { psi_free(vmounts); PyErr_SetFromErrno(PyExc_OSError); return NULL; } else if (nmounts == 0) { psi_free(vmounts); PyErr_SetString(PyExc_OSError, "Internal race condition"); return NULL; } ml = (psi_mountlist_t *)psi_calloc(sizeof(psi_mountlist_t)); if (ml == NULL) { psi_free(vmounts); return NULL; } ml->mounts = (psi_mountinfo_t **)psi_calloc( nmounts*sizeof(psi_mountinfo_t *)); if (ml->mounts == NULL) { psi_free(vmounts); psi_free(ml); return NULL; } ml->count = 0; for (i = 0; i < nmounts; i++) { mnt = (struct vmount *)(vmounts + offset); if (!remote && strcmp(vmt2dataptr(mnt, VMT_HOST), "-") != 0) continue; mounti = psi_calloc(sizeof(psi_mountinfo_t)); ml->mounts[ml->count] = mounti; ml->count += 1; if (set_vmount(mounti, mnt) < 0) { psi_free(vmounts); psi_free_mountlist(ml); return NULL; } if (posix_set_vfs(mounti) < 0) { psi_free(vmounts); psi_free_mountlist(ml); return NULL; } } return ml; }
/** Find the executable, argument list and environment * * This will also fill in the command attribute. * * The sysctl calls here don't use a wrapper as in darwin_prcesstable.c since * they know the size of the returned structure already. * * The layout of the raw argument space is documented in start.s, which is * part of the Csu project. In summary, it looks like: * * XXX: This layout does not match whith what the code does. The code seems * to think exec_path is in between the first argc and arg[0], also the data * returned by ssyctl() seems to be starting at the first argc according to * the code. * * /---------------\ 0x00000000 * : : * : : * |---------------| * | argc | * |---------------| * | arg[0] | * |---------------| * : : * : : * |---------------| * | arg[argc - 1] | * |---------------| * | 0 | * |---------------| * | env[0] | * |---------------| * : : * : : * |---------------| * | env[n] | * |---------------| * | 0 | * |---------------| <-- Beginning of data returned by sysctl() is here. * | argc | * |---------------| * | exec_path | * |:::::::::::::::| * | | * | String area. | * | | * |---------------| <-- Top of stack. * : : * : : * \---------------/ 0xffffffff */ static int set_exe(struct psi_process *proci, struct kinfo_proc *p) { int mib[3], argmax, nargs; size_t size; char *procargs, *cp; int i; int env_start = 0; /* Get the maximum process arguments size. */ mib[0] = CTL_KERN; mib[1] = KERN_ARGMAX; size = sizeof(argmax); if (sysctl(mib, 2, &argmax, &size, NULL, 0) == -1) { PyErr_SetFromErrnoWithFilename(PyExc_OSError, "sysctl() argmax"); return -1; } /* Allocate space for the arguments. */ procargs = (char *)psi_malloc(argmax); if (procargs == NULL) return -1; /* Make a sysctl() call to get the raw argument space of the process. */ mib[0] = CTL_KERN; mib[1] = KERN_PROCARGS2; mib[2] = p->kp_proc.p_pid; size = (size_t)argmax; if (sysctl(mib, 3, procargs, &size, NULL, 0) == -1) { /* We failed to get the exe info, but it's not fatal. We probably just * didn't have permission to access the KERN_PROCARGS2 for this * process. */ psi_free(procargs); proci->exe_status = PSI_STATUS_PRIVS; proci->argc_status = PSI_STATUS_PRIVS; proci->argv_status = PSI_STATUS_PRIVS; proci->envc_status = PSI_STATUS_PRIVS; proci->envv_status = PSI_STATUS_PRIVS; proci->command_status = PSI_STATUS_PRIVS; return 0; } memcpy(&nargs, procargs, sizeof(nargs)); cp = procargs + sizeof(nargs); /* Save the exe */ proci->exe = psi_strdup(cp); if (proci->exe == NULL) { psi_free(procargs); return -1; } proci->exe_status = PSI_STATUS_OK; /* Skip over the exe. */ cp += strlen(cp); if (cp == &procargs[size]) { psi_free(procargs); PyErr_SetString(PyExc_OSError, "Did not find args and env"); return -1; } /* Skip trailing '\0' characters. */ for (; cp < &procargs[size]; cp++) { if (*cp != '\0') { /* Beginning of first argument reached. */ break; } } if (cp == &procargs[size]) { psi_free(procargs); /* We dont' have any arguments or environment */ if (nargs == 0) { proci->argc = 0; proci->argc_status = PSI_STATUS_OK; proci->argv = NULL; proci->argv_status = PSI_STATUS_OK; proci->envc = 0; proci->envc_status = PSI_STATUS_OK; proci->envv = NULL; proci->envv_status = PSI_STATUS_OK; /* Update proci->command */ if (command_from_argv(&proci->command, proci->argv, proci->argc) < 0) { psi_free(procargs); return -1; } proci->command_status = PSI_STATUS_OK; return 0; } else { PyErr_SetString(PyExc_OSError, "Did not find args and env"); return -1; } } /* The argument list */ proci->argc = nargs; proci->argc_status = PSI_STATUS_OK; proci->argv = psi_strings_to_array(cp, nargs); if (proci->argv == NULL) { psi_free(procargs); return -1; } proci->argv_status = PSI_STATUS_OK; if (command_from_argv(&proci->command, proci->argv, proci->argc) < 0) { psi_free(procargs); return -1; } proci->command_status = PSI_STATUS_OK; /* The environment */ for (i = 0; i < nargs; i++) { env_start += strlen(proci->argv[i])+1; } env_start--; proci->envc = 0; for (i = 0; ; i++) { if (*(cp+env_start + i) == '\0') { if (*(cp+env_start + i + 1) == '\0') break; else proci->envc++; } } proci->envc_status = PSI_STATUS_OK; proci->envv = psi_strings_to_array(cp+env_start+1, proci->envc); psi_free(procargs); if (proci->envv == NULL) return -1; proci->envv_status = PSI_STATUS_OK; return 0; }