Пример #1
0
/* flush current message queue to a registered 
 * console widget, if such a thing exists.
 * since vmdcon_append() allocates the storage,
 * for everything, we have to free the msg structs
 * and the strings. */
int vmdcon_purge(void) 
{
    struct vmdcon_msg *msg;
    const char *res;

    wkf_mutex_lock(&vmdcon_status_lock);
    /* purge message queue only if we have a working console window */
    if ( ! ((vmdcon_status == VMDCON_UNDEF) || (vmdcon_status == VMDCON_NONE)
        || ((vmdcon_status == VMDCON_WIDGET) &&
            ((vmdcon_interp == NULL) || (vmdcon_wpath == NULL))) ) ) {

        wkf_mutex_lock(&vmdcon_output_lock);
        while (vmdcon_pending != NULL) {
            msg=vmdcon_pending;

            switch (vmdcon_status) {
              case VMDCON_TEXT:
                  fputs(msg->txt,stdout);
                  break;
                  
              case VMDCON_WIDGET: 
                  res = tcl_vmdcon_insert(vmdcon_interp, vmdcon_wpath, 
                                          vmdcon_mark, msg->txt);
                  /* handle errors writing to a tcl console window.
                   * unregister widget, don't free current message 
                   * and append error message into holding buffer. */
                  if (res) {
                      wkf_mutex_unlock(&vmdcon_status_lock);
                      vmdcon_register(NULL, NULL, vmdcon_interp);
                      wkf_mutex_unlock(&vmdcon_output_lock);
                      vmdcon_printf(VMDCON_ERROR,
                                    "Problem writing to text widget: %s\n", res);
                      return 1;
                  }
                  break;

              default:
                  /* unknown console type */
                  return 1;
            }
            free(msg->txt);
            vmdcon_pending=msg->next;
            free(msg);

        }
        if (vmdcon_status == VMDCON_TEXT) 
            fflush(stdout);

        wkf_mutex_unlock(&vmdcon_output_lock);
    }
    wkf_mutex_unlock(&vmdcon_status_lock);
    return 0;
}
Пример #2
0
/* register a tk/tcl widget to be the console window.
 * we get the widget path directly from tcl, 
 * so we have to create a copy (and free it later).
 * we also need a pointer to the tcl interpreter.
 */
int vmdcon_register(const char *w_path, const char *mark, void *interp)
{
    wkf_mutex_lock(&vmdcon_status_lock);
    vmdcon_interp=interp;

    /* unregister current console widget */
    if(w_path == NULL) {
        if (vmdcon_wpath != NULL) {
            free(vmdcon_wpath);
            free(vmdcon_mark);
        }
        vmdcon_wpath=NULL;
        vmdcon_mark=NULL;
        /* we have to indicate that no console is available */
        if (vmdcon_status == VMDCON_WIDGET) vmdcon_status=VMDCON_NONE;
    } else {
        int len;
        
        if (vmdcon_wpath != NULL) {
            free(vmdcon_wpath);
            free(vmdcon_mark);
        }
    
        len=strlen(w_path);
        vmdcon_wpath=(char*)malloc(len+1);
        strcpy(vmdcon_wpath, w_path);
        len=strlen(mark);
        vmdcon_mark=(char*)malloc(len+1);
        strcpy(vmdcon_mark, mark);
    }
    wkf_mutex_unlock(&vmdcon_status_lock);

    /* try to flush pending console log text. */
    return vmdcon_purge();
}
Пример #3
0
/* set current vmdcon status */
void vmdcon_set_status(int status, void *interp)
{
    wkf_mutex_lock(&vmdcon_status_lock);
    if (interp != NULL) vmdcon_interp=interp;
    vmdcon_status=status;
    tcl_vmdcon_set_status_var(vmdcon_interp, status);
    wkf_mutex_unlock(&vmdcon_status_lock);
}
Пример #4
0
/* append text from to console log buffer to queue. */
int vmdcon_showlog(void)
{
    struct vmdcon_msg *log, *msg;

    wkf_mutex_lock(&vmdcon_output_lock);
    log=vmdcon_logmsgs;
    do {
        /* append to message queue. */
        msg=(struct vmdcon_msg *)malloc(sizeof(struct vmdcon_msg));
        msg->txt=(char *) malloc(strlen(log->txt)+1);
        msg->lvl=VMDCON_ALWAYS;
        strcpy(msg->txt,log->txt);
        msg->next=NULL;
    
        if (vmdcon_pending == NULL) {
            vmdcon_pending=msg;
            vmdcon_lastmsg=msg;
        } else {
            vmdcon_lastmsg->next=msg;
            vmdcon_lastmsg=msg;
        }
        log=log->next;
    } while (log->next != NULL);

    /* terminate the dmesg output with a newline */
    msg=(struct vmdcon_msg *)malloc(sizeof(struct vmdcon_msg));
    msg->txt=(char *) malloc(strlen("\n")+1);
    msg->lvl=VMDCON_ALWAYS;
    strcpy(msg->txt,"\n");
    msg->next=NULL;
    
    if (vmdcon_pending == NULL) {
        vmdcon_pending=msg;
        vmdcon_lastmsg=msg;
    } else {
        vmdcon_lastmsg->next=msg;
        vmdcon_lastmsg=msg;
    }
    log=log->next;

    wkf_mutex_unlock(&vmdcon_output_lock);
    return vmdcon_purge();
}
Пример #5
0
/* append text to console log queue.
 * we have to make copies as we might get handed 
 * a tcl object or a pointer to some larger buffer. */
int vmdcon_append(int level, const char *txt, int len) 
{
    struct vmdcon_msg *msg;
    char *buf;

    /* len=0: don't print. len=-1, autodetect. */
    if (len == 0 ) return 0;
    if (len < 0) {
        len=strlen(txt);
    }

    wkf_mutex_lock(&vmdcon_output_lock);
    
    /* append to message queue. */
    /* but don't print stuff below the current loglevel */
    if (level >= vmdcon_loglvl) {
      /* create copy of text. gets free'd after it has been 'printed'. */
      buf=(char *)calloc(len+1,1);
      strncpy(buf,txt,len);
    
      msg=(struct vmdcon_msg *)malloc(sizeof(struct vmdcon_msg));
      msg->txt=buf;
      msg->lvl=level;
      msg->next=NULL;
      
      if (vmdcon_pending == NULL) {
        vmdcon_pending=msg;
        vmdcon_lastmsg=msg;
      } else {
        vmdcon_lastmsg->next=msg;
        vmdcon_lastmsg=msg;
      }
    }
    
    /* messages are added to the log regardless of loglevel.
     * this way we can silence the log window and still retrieve
     * useful information with 'vmdcon -dmesg'. */
    buf=(char *)calloc(len+1,1);
    strncpy(buf,txt,len);

    /* append to log message list. */
    msg=(struct vmdcon_msg *)malloc(sizeof(struct vmdcon_msg));
    msg->txt=buf;
    msg->lvl=level;
    msg->next=NULL;
        
    if (vmdcon_logmsgs == NULL) {
        vmdcon_logmsgs=msg;
        vmdcon_lastlog=msg;
        ++vmdcon_loglen;
    } else {
        vmdcon_lastlog->next=msg;
        vmdcon_lastlog=msg;
        ++vmdcon_loglen;
    }
    
    /* remove message from the front of the queue
     * in case we have too long a list */
    while (vmdcon_loglen > vmdcon_max_loglen) {
        msg=vmdcon_logmsgs;
        vmdcon_logmsgs=msg->next;
        free(msg->txt);
        free(msg);
        --vmdcon_loglen;
    }
    
    wkf_mutex_unlock(&vmdcon_output_lock);

    return 0;
}
Пример #6
0
/* set current vmdcon log level */
void vmdcon_set_loglvl(int lvl)
{
    wkf_mutex_lock(&vmdcon_status_lock);
    vmdcon_loglvl=lvl;
    wkf_mutex_unlock(&vmdcon_status_lock);
}
Пример #7
0
extern "C" void * bondsearchthread(void *voidparms) {
  int i, j, aindex;
  int paircount = 0;

  bondsearchthrparms *parms = (bondsearchthrparms *) voidparms;

  const int threadid = parms->threadid;
  const int threadcount = parms->threadcount;
  wkf_mutex_t *pairlistmutex = parms->pairlistmutex;
  const float *pos = parms->pos;
  const float *radii = parms->radii;
  const int totb = parms->totb;
  const int **boxatom = (const int **) parms->boxatom;
  const int *numinbox = parms->numinbox;
  const int **nbrlist = (const int **) parms->nbrlist; 
  const int maxpairs = parms->maxpairs;
  const float pairdist = parms->pairdist;

  ResizeArray<int> *pairs = new ResizeArray<int>;
  float sqdist = pairdist * pairdist;

  wkfmsgtimer *msgt = wkf_msg_timer_create(5);
  for (aindex = threadid; (aindex < totb) && (paircount < maxpairs); aindex+=threadcount) {
    const int *tmpbox, *nbr;
    tmpbox = boxatom[aindex];
    int anbox = numinbox[aindex];

    if (((aindex & 255) == 0) && wkf_msg_timer_timeout(msgt)) {
      char tmpbuf[128];
      sprintf(tmpbuf, "%6.2f", (100.0f * aindex) / (float) totb);
//  XXX: we have to use printf here as msgInfo is not thread-safe.
//  msgInfo << "vmd_gridsearch_bonds (thread " << threadid << "): " 
//          << tmpbuf << "% complete" << sendmsg;
      printf("vmd_gridsearch_bonds (thread %d): %s %% complete\n", 
        threadid, tmpbuf); 
    }

    for (nbr = nbrlist[aindex]; (*nbr != -1) && (paircount < maxpairs); nbr++) {
      int nnbr=*nbr;
      const int *nbrbox = boxatom[nnbr];
      int nbox=numinbox[nnbr];
      int self = (aindex == nnbr) ? 1 : 0;

      for (i=0; (i<anbox) && (paircount < maxpairs); i++) {
        int ind1 = tmpbox[i];
        const float *p1 = pos + 3L*ind1;

        // skip over self and already-tested atoms
        int startj = (self) ? i+1 : 0;

        for (j=startj; (j<nbox) && (paircount < maxpairs); j++) {
          int ind2 = nbrbox[j];
          const float *p2 = pos + 3L*ind2;
          float dx = p1[0] - p2[0];
          float dy = p1[1] - p2[1];
          float dz = p1[2] - p2[2];
          float ds2 = dx*dx + dy*dy + dz*dz;

          // perform distance test, but ignore pairs between atoms
          // with nearly identical coords
          if ((ds2 > sqdist) || (ds2 < 0.001))
            continue;

          if (radii) { // Do atom-specific distance check
            float cut = 0.6f * (radii[ind1] + radii[ind2]);
            if (ds2 > cut*cut)
              continue;
          }

          pairs->append(ind1);
          pairs->append(ind2);
          paircount++;
        }
      }
    }
  }

  // setup results pairlist node
  GridSearchPairlist *head;
  head = (GridSearchPairlist *) malloc(sizeof(GridSearchPairlist));
  head->next = NULL;
  head->pairlist = pairs;

  wkf_mutex_lock(pairlistmutex);   // lock pairlist before update
  parms->head = head;
  wkf_mutex_unlock(pairlistmutex); // unlock pairlist after update

  wkf_msg_timer_destroy(msgt);

  return NULL;
}