void suspend_current(struct list_node *queue) { kthread_t *cur; /* current thread must be on the run queue */ cur = current; if(list_ismember(&run_list, cur)) { list_del_obj(current); list_append_obj(queue, current); } else { printk("error: can't suspend thread not on run queue\n"); } schedule(); }
int NLEnergy_parse_eval(NLEnergy *p, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], int evalType) { enum { KEYWD, ATOM, BOND, ANGLE, DIHED, IMPR, ELEC, VDW, NONB }; const Topology *topo = &(p->topo); const int32 natoms = Topology_atom_array_length(topo); const int32 nbonds = Topology_bond_array_length(topo); const int32 nangles = Topology_angle_array_length(topo); const int32 ndiheds = Topology_dihed_array_length(topo); const int32 nimprs = Topology_impr_array_length(topo); int32 ninvs; char *atomsel, *nonbsel, *bondsel, *anglesel, *dihedsel, *imprsel, *invsel; int32 i; int state = KEYWD, s; int setnum = 0, mark = FALSE; boolean invert = FALSE; TEXT("eval"); if (Array_length(&(p->atomsel)) != natoms && (s=Array_resize(&(p->atomsel), natoms)) != OK) return ERROR(s); atomsel = Array_data(&(p->atomsel)); if (Array_length(&(p->nonbsel)) != natoms && (s=Array_resize(&(p->nonbsel), natoms)) != OK) return ERROR(s); nonbsel = Array_data(&(p->nonbsel)); if (Array_length(&(p->bondsel)) != nbonds && (s=Array_resize(&(p->bondsel), nbonds)) != OK) return ERROR(s); bondsel = Array_data(&(p->bondsel)); if (Array_length(&(p->anglesel)) != nangles && (s=Array_resize(&(p->anglesel), nangles)) != OK) return ERROR(s); anglesel = Array_data(&(p->anglesel)); if (Array_length(&(p->dihedsel)) != ndiheds && (s=Array_resize(&(p->dihedsel), ndiheds)) != OK) return ERROR(s); dihedsel = Array_data(&(p->dihedsel)); if (Array_length(&(p->imprsel)) != nimprs && (s=Array_resize(&(p->imprsel), nimprs)) != OK) return ERROR(s); imprsel = Array_data(&(p->imprsel)); /* find max length for inverse selection array */ ninvs = natoms; if (ninvs < nbonds) ninvs = nbonds; if (ninvs < nangles) ninvs = nangles; if (ninvs < ndiheds) ninvs = ndiheds; if (ninvs < nimprs) ninvs = nimprs; if (Array_length(&(p->invsel)) != ninvs && (s=Array_resize(&(p->invsel), ninvs)) != OK) return ERROR(s); invsel = Array_data(&(p->invsel)); if (0 == objc) { memset(atomsel, 0, natoms); memset(nonbsel, ASEL_NONB, natoms); memset(bondsel, TRUE, nbonds); memset(anglesel, TRUE, nangles); memset(dihedsel, TRUE, ndiheds); memset(imprsel, TRUE, nimprs); } else { const char *t = NULL; state = KEYWD; memset(atomsel, 0, natoms); memset(nonbsel, 0, natoms); memset(bondsel, 0, nbonds); memset(anglesel, 0, nangles); memset(dihedsel, 0, ndiheds); memset(imprsel, 0, nimprs); i = 0; INT(objc); while (i <= objc) { INT(i); switch (state) { case KEYWD: if (i == objc) { i++; break; } t = Tcl_GetString(objv[i]); setnum = 0; invert = FALSE; if ('-'==t[0]) { invert = TRUE; t++; } else if ('+'==t[0]) { t++; } if (strcmp(t,"atom")==0) state = ATOM; else if (strcmp(t,"bond")==0) state = BOND; else if (strcmp(t,"angle")==0) state = ANGLE; else if (strcmp(t,"dihed")==0) state = DIHED; else if (strcmp(t,"impr")==0) state = IMPR; else if (strcmp(t,"elec")==0) state = ELEC; else if (strcmp(t,"vdw")==0) state = VDW; else if (strcmp(t,"nonb")==0) state = NONB; else return ERROR(ERR_EXPECT); i++; break; case BOND: s = FAIL; if (i<objc && (s=parse_bondlist(p,interp,objv[i],invert))==OK) i++; //else if (s < FAIL) return ERROR(s); else if ( ! invert ) memset(bondsel, TRUE, nbonds); state = KEYWD; break; case ANGLE: s = FAIL; if (i<objc && (s=parse_anglelist(p,interp,objv[i],invert))==OK) i++; //else if (s < FAIL) return ERROR(s); else if ( ! invert ) memset(anglesel, TRUE, nangles); state = KEYWD; break; case DIHED: s = FAIL; if (i<objc && (s=parse_dihedlist(p,interp,objv[i],invert))==OK) i++; //else if (s < FAIL) return ERROR(s); else if ( ! invert ) memset(dihedsel, TRUE, ndiheds); state = KEYWD; break; case IMPR: s = FAIL; if (i<objc && (s=parse_imprlist(p,interp,objv[i],invert))==OK) i++; //else if (s < FAIL) return ERROR(s); else if ( ! invert ) memset(imprsel, TRUE, nimprs); state = KEYWD; break; default: /* ATOM, ELEC, VDW, or NONB */ if (i==objc && setnum > 0) { state = KEYWD; continue; } if (ATOM==state) mark = (0==setnum ? -ASEL_NONB : -ASEL_NONB_B); else if (ELEC==state) mark = (0==setnum ? ASEL_ELEC : ASEL_ELEC_B); else if (VDW==state) mark = (0==setnum ? ASEL_VDW : ASEL_VDW_B); else mark = (0==setnum ? ASEL_NONB : ASEL_NONB_B); INT(ASEL_NONB==mark); INT(ASEL_NONB_B==mark); s = FAIL; if (i<objc && (s=parse_atomlist(p,interp,objv[i],invert,mark))==OK) { i++; setnum++; if (invert || 2==setnum) state = KEYWD; } #if 0 else if (s < FAIL) { if (setnum > 0) continue; else return ERROR(s); } #endif else if (0==setnum && !invert) { if (mark > 0) { memset(nonbsel, mark, natoms); } else { memset(atomsel, -mark, natoms); } state = KEYWD; } else state = KEYWD; } /* switch */ } /* while */ } /* else */ if ((s=select_from_atomlist(p)) != OK) return ERROR(s); /* evaluation */ if (EVAL_ENERGY==evalType || EVAL_FORCE==evalType) { if ((s=NLEnergy_eval_force(p)) != OK) return ERROR(s); } else { /* minimize not yet supported */ return ERROR(ERR_EXPECT); } /* output */ if (EVAL_ENERGY==evalType) { Tcl_Obj *a = NULL; if ((s=NLEnergy_new_obj_dreal(interp, &a, p->ener.pe * ENERGY_EXTERNAL)) != OK) { return ERROR(s); } if ((s=NLEnergy_set_obj_result(interp, a)) != OK) return ERROR(s); } else if (EVAL_FORCE==evalType || EVAL_MINIMIZE==evalType) { const dvec *f = Coord_force_const(&(p->coord)); Tcl_Obj *r = NULL; /* return list of lists */ Tcl_Obj *a = NULL; /* list of atom index */ Tcl_Obj *b = NULL; /* list of force or potentials (MINIMIZE) */ if ((s=atomlist_contrib(p)) != OK) return ERROR(s); if ((s=new_list(interp, &r)) != OK) return ERROR(s); if ((s=new_list(interp, &a)) != OK) return ERROR(s); if ((s=new_list(interp, &b)) != OK) return ERROR(s); for (i = 0; i < natoms; i++) { if (atomsel[i]) { if ((s=list_append_atomid(p,interp,a,i)) != OK) return ERROR(s); if (EVAL_FORCE==evalType) { dvec fs; VECMUL(fs, ENERGY_EXTERNAL, f[i]); if ((s=list_append_dvec(interp,b,&fs)) != OK) return ERROR(s); } } } if (EVAL_MINIMIZE==evalType) { return ERROR(ERR_EXPECT); } if ((s=list_append_obj(interp, r, a)) != OK) return ERROR(s); if ((s=list_append_obj(interp, r, b)) != OK) return ERROR(s); if ((s=set_obj_result(interp, r)) != OK) return ERROR(s); } else { /* nothing else is supported */ return ERROR(ERR_EXPECT); } #if 0 if (objc >= 1) { const char *t = Tcl_GetString(objv[0]); if (strcmp(t,"bond")==0) { return NLEnergy_energy_bond(p, interp, objc-1, objv+1); } if (strcmp(t,"angle")==0) { return NLEnergy_energy_angle(p, interp, objc-1, objv+1); } if (strcmp(t,"dihed")==0) { return NLEnergy_energy_dihed(p, interp, objc-1, objv+1); } if (strcmp(t,"impr")==0) { return NLEnergy_energy_impr(p, interp, objc-1, objv+1); } if (strcmp(t,"elec")==0) { return NLEnergy_energy_nonbonded(p, FNBCUT_ELEC, interp, objc-1, objv+1); } if (strcmp(t,"vdw")==0) { return NLEnergy_energy_nonbonded(p, FNBCUT_VDW, interp, objc-1, objv+1); } if (strcmp(t,"nonbonded")==0) { return NLEnergy_energy_nonbonded(p, FNBCUT_ELEC | FNBCUT_VDW, interp, objc-1, objv+1); } } return ERROR(ERR_EXPECT); #endif return OK; }
void make_runnable(kthread_t *th) { /* delete this thread from any other potential list */ list_del_obj(th); list_append_obj(&run_list, th); }