Ejemplo n.º 1
0
// userdata, is a curl_iovec_t. This is set to be passed into this function, when we
// call CURLOPT_WRITEDATA in curl_preadv and curl_readv.
// FUTURE: If we have filled the iovec, but have not finished reading from the curl
// handle, pause it (i.e., return CURL_WRITE_PAUSE).
static
size_t buf_writer(char* ptr_data, size_t size, size_t nmemb, void* userdata)
{
  size_t realsize = size*nmemb;
  size_t real_realsize = realsize;
  struct curl_iovec_t* ret = ((struct curl_iovec_t *)userdata);

  // so that we can "seek" when we cannot request byteranges
  if (realsize < ret->offset) {
    ret->offset -= realsize;
    return realsize;
  } else {
    // nop when we are done -- non-zero the first time through
    ptr_data = &(ptr_data[ret->offset]);
    realsize -= ret->offset;
    ret->offset = 0;
  }

  // The amount that we have been given by curl is more than we can stick into a
  // single iovbuf. So we need to go from one iovbuf to the other
  while (realsize > ret->vec[ret->curr].iov_len*size - ret->amt_read)  {
    // This cast to char* is to get rid "subscript of pointer to incomplete type" warnings
    chpl_memcpy(&(((char*)ret->vec[ret->curr].iov_base)[ret->amt_read]), ptr_data, ret->vec[ret->curr].iov_len*size - ret->amt_read);
    ret->total_read += (ret->vec[ret->curr].iov_len*size - ret->amt_read);
    realsize -= ret->vec[ret->curr].iov_len*size - ret->amt_read;
    ptr_data = &(ptr_data[(ret->vec[ret->curr].iov_len*size - ret->amt_read)]);
    // Reset the amount that we have read into this vector.
    ret->amt_read = 0;
    if (ret->curr == ret->count-1) { // last iovbuf in this vector, so stop reading
      return 0; // stop reading
    } else { // go to the next buf in this vector
      ret->curr++;
    }
  }

  // The amount of data that we have been given by curl is <= to the amount of space
  // that we have left in this iovbuf. So we can simply read it all in.
  if (realsize <= (ret->vec[ret->curr].iov_len*size - ret->amt_read)) {
    chpl_memcpy(&(((char*)ret->vec[ret->curr].iov_base)[ret->amt_read]), ptr_data, realsize);
    ret->total_read += realsize;
    ret->amt_read += realsize;
    // We have fully populated this iovbuf
    if (ret->vec[ret->curr].iov_len*size == ret->amt_read) {
      if (ret->curr == ret->count -1) // last iovbuf in this vector
        return 0; // stop reading
      else { // else, step to the next buf.
        ret->curr++;
        ret->amt_read = 0;
      }
    }
  }
  return real_realsize;
}
Ejemplo n.º 2
0
void chpl_comm_ofi_oob_allgather(void* const in, void* out, size_t len) {
  if (chpl_numNodes == 1) {
    chpl_memcpy(out, in, len);
  } else {
    INTERNAL_ERROR_V("multi-locale allgather not supported");
  }
}
// Note that this function can be called in parallel and more notably it can be
// called with non-monotonic pid's. e.g. this may be called with pid 27, and
// then pid 2, so it has to ensure that the privatized array has at least pid+1
// elements. Be __very__ careful if you have to update it.
void chpl_newPrivatizedClass(void* v, int64_t pid) {
  chpl_sync_lock(&privatizationSync);

  // initialize array to a default size
  if (chpl_privateObjects == NULL) {
    chpl_capPrivateObjects = 2*max(pid, 4);
    chpl_privateObjects =
        chpl_mem_allocMany(chpl_capPrivateObjects, sizeof(void *),
                           CHPL_RT_MD_COMM_PRV_OBJ_ARRAY, 0, 0);
  } else {
    // if we're out of space, double (or more) the array size
    if (pid >= chpl_capPrivateObjects) {
      void** tmp;
      int64_t oldCap;

      oldCap = chpl_capPrivateObjects;
      chpl_capPrivateObjects = 2*max(pid, oldCap);

      tmp = chpl_mem_allocMany(chpl_capPrivateObjects, sizeof(void *),
                               CHPL_RT_MD_COMM_PRV_OBJ_ARRAY, 0, 0);
      chpl_memcpy((void*)tmp, (void*)chpl_privateObjects, (oldCap)*sizeof(void*));
      chpl_privateObjects = tmp;
      // purposely leak old copies of chpl_privateObject to avoid the need to
      // lock chpl_getPrivatizedClass; TODO: fix with lock free data structure
    }
  }
  chpl_privateObjects[pid] = v;

  chpl_sync_unlock(&privatizationSync);
}
Ejemplo n.º 4
0
chpl_comm_nb_handle_t chpl_comm_get_nb(void* addr, c_nodeid_t node, void* raddr,
                                       size_t size, int32_t typeIndex,
                                       int ln, int32_t fn)
{
  assert(node == 0);
  chpl_memcpy(addr, raddr, size);
  return NULL;
}
Ejemplo n.º 5
0
void chpl_task_taskCall(chpl_fn_p fp, void* arg, size_t arg_size,
                        c_sublocid_t subloc,
                        int lineno, int32_t filename) {
  void *arg_copy = NULL;

  if (arg != NULL) {
    arg_copy = chpl_mem_allocMany(1, arg_size, CHPL_RT_MD_TASK_ARG, 0, 0);
    chpl_memcpy(arg_copy, arg, arg_size);
  }
  taskCallBody(fp, NULL, arg_copy, subloc, false, lineno, filename);
}
Ejemplo n.º 6
0
// We want to upload data from the iovec passed into curl_writev. We populate a
// curl_iovec_t in curl_writev, and set it to be passed in when we call
// CURLOPT_READDATA. Note, that we can only return a chunk of memory at most
// size*nmemb big to curl (i.e., sizeof(ptr) <= size*nmemb after this function is
// called by CURL).
static
size_t read_data(void *ptr, size_t size, size_t nmemb, void *userp)
{
  size_t realsize = size*nmemb;
  struct curl_iovec_t* ret = ((struct curl_iovec_t *)userp);

  if((size == 0) || (nmemb == 0) || ((size*nmemb) < 1) || (ret->curr >= ret->count)) {
    return 0; // stop putting data
  }

  // We can upload more than one iovbuf at once, so do it.
  while (realsize > ret->vec[ret->curr].iov_len*size - ret->amt_read)  {
    chpl_memcpy(ptr, &(((char*)ret->vec[ret->curr].iov_base)[ret->amt_read]), ret->vec[ret->curr].iov_len*size - ret->amt_read);
    ret->total_read += (ret->vec[ret->curr].iov_len*size - ret->amt_read);
    realsize -= ret->vec[ret->curr].iov_len*size - ret->amt_read;
    ptr = &(((char*)ptr)[(ret->vec[ret->curr].iov_len*size - ret->amt_read)]);
    // Reset the amount that we have read out of this vector.
    ret->amt_read = 0;
    // go to the next vector
    ret->curr++;
    if (ret->curr >= ret->count)
      return ret->total_read;
  }

  // The amount of data that we need to hand to curl is <= the amount of space
  // that we have left in this iovbuf, so we have to be careful not to exceed it
  if (realsize <= (ret->vec[ret->curr].iov_len*size - ret->amt_read)) {
    chpl_memcpy(ptr, &(((char*)ret->vec[ret->curr].iov_base)[ret->amt_read]), realsize);
    ret->total_read += realsize;
    ret->amt_read += realsize;
    // We have fully read this iovbuf
    if (ret->vec[ret->curr].iov_len*size == ret->amt_read) {
      ret->curr++;
      ret->amt_read = 0;
    }
  }
  return ret->total_read;
}
Ejemplo n.º 7
0
void string_from_c_string(chpl_string *ret, c_string str, int haslen, int64_t len, int32_t lineno, chpl_string filename)
{
  char* s;

  if( str == NULL ) {
    *ret = NULL;
    return;
  }
  if( ! haslen ) len = strlen(str);

  s = (char*)chpl_mem_alloc(len+1, CHPL_RT_MD_STRING_COPY_DATA,
                              lineno, filename);
  chpl_memcpy(s, str, len);
  s[len] = '\0';
  *ret = s;
}
Ejemplo n.º 8
0
// Write from curl to a string. Note that userdata is a str_t, since nuch as we have
// to keep track of how much we read in  buf_writer, we have to keep track of how
// long our string is so that we cann lengthen it via realloc as we need to.
static
size_t chpl_curl_write_string(void *contents, size_t size, size_t nmemb, void *userp)
{
  size_t realsize = size * nmemb;
  struct str_t *str = (struct str_t *)userp;

  str->mem = (char*)qio_realloc(str->mem, str->size + realsize + 1);
  if(str->mem == NULL) {
    return 0;
  }

  chpl_memcpy(&(str->mem[str->size]), contents, realsize);
  str->size += realsize;
  str->mem[str->size] = 0;

  return realsize;
}
Ejemplo n.º 9
0
void wide_string_from_c_string(chpl____wide_chpl_string *ret, c_string str, int haslen, int64_t len, int32_t lineno, chpl_string filename)
{
  char* s;

  ret->locale = chpl_gen_getLocaleID();
  if( str == NULL ) {
    ret->addr = NULL;
    ret->size = 0;
    return;
  }
  if( ! haslen ) len = strlen(str);

  s = chpl_mem_alloc(len+1, CHPL_RT_MD_STRING_COPY_DATA, lineno, filename);
  chpl_memcpy(s, str, len);
  s[len] = '\0';

  ret->addr = s;
  ret->size = len + 1; // this size includes the terminating NUL
}
Ejemplo n.º 10
0
// un-macro'd CHPL_COMM_WIDE_GET_STRING
void
chpl_comm_wide_get_string(chpl_string* local, struct chpl_chpl____wide_chpl_string_s* x, int32_t tid, int32_t lineno, chpl_string filename)
{
  char* chpl_macro_tmp;

  if (x->addr == NULL)
  {
    *local = NULL;
    return;
  }

  chpl_macro_tmp =
      chpl_mem_calloc(x->size, CHPL_RT_MD_GET_WIDE_STRING, lineno, filename);
  if (chpl_nodeID == chpl_rt_nodeFromLocaleID(x->locale))
    chpl_memcpy(chpl_macro_tmp, x->addr, x->size);
  else
    chpl_gen_comm_get((void*) &(*chpl_macro_tmp),
                  chpl_rt_nodeFromLocaleID(x->locale),
                  (void*)(x->addr),
                  sizeof(char), tid, x->size, lineno, filename);
  *local = chpl_macro_tmp;
}
Ejemplo n.º 11
0
// This copies the remote string data into a local wide string representation
// of the same.
// This routine performs a deep copy of the character array data 
// after fetching the string descriptor from the remote node.  (The char*
// field in the local copy of the remote descriptor has no meaning in the 
// context of the local node, since it refers to elements in the address 
// space on the remote node.)  
// In chpl_comm_wide_get_string() a buffer of the right size is allocated 
// to receive the bytes copied from the remote node.  This buffer will be leaked,
// since no corresponding free is added to the generated code.
void chpl_gen_comm_wide_string_get(void *addr, c_nodeid_t node, void *raddr,
                                   size_t size, int32_t typeIndex,
                                   int ln, int32_t fn) {
  // This part just copies the descriptor.
  if (chpl_nodeID == node) {
    chpl_memcpy(addr, raddr, size);
  } else {
    chpl_gen_comm_get(addr, node, raddr, size, typeIndex, ln, fn);
  }

  // And now we copy the bytes in the string itself.
  {
    struct chpl_chpl____wide_chpl_string_s* local_str =
      (struct chpl_chpl____wide_chpl_string_s*) addr;
    // Accessing the addr field of the incomplete struct declaration
    // would not work in this context except that this function
    // is always inlined.
    chpl_comm_wide_get_string((chpl_string*) &(local_str->addr),
                              local_str, typeIndex, ln, fn);
    // The bytes live locally, so we have to update the locale.
    local_str->locale = chpl_gen_getLocaleID();
  }
}