double get_latency_bc(int n, size_t size) { int idx, i; char *data; bc_plist_t *other = NULL; bc_chan_t *src = NULL, *sink = NULL; bc_dtype_t *ntype; double start, *times; data = (char *) malloc(sizeof (char)*size); ntype = bc_dtype_create(sizeof (char)*size); /* We collect the value of the second get() * Rank 0 is sender, Rank 1 is producer. */ if (bc_rank == 0) { other = bc_plist_create(1, 1); sink = bc_sink_create(other, ntype, 10, BC_ROLE_PIPE); for (i = 0; i < n; i++) { memset(data, bc_rank + 'a', size); /* Put data. */ bc_put(sink, data, 1); bc_put(sink, data, 1); } bc_chan_destroy(sink); bc_plist_destroy(other); bc_dtype_destroy(ntype); return 0; } else { times = (double *) malloc(sizeof (double)*n); other = bc_plist_create(1, 0); src = bc_src_create(other, ntype, BC_ROLE_PIPE); for (i = 0; i < n; i++) { /* Get data. */ bc_get(src, data, 1); /* Ignore this. */ start = bc_gettime_usec(); bc_get(src, data, 1); /* Take this value. */ times[i] = bc_gettime_usec() - start; } bc_chan_destroy(src); bc_plist_destroy(other); bc_dtype_destroy(ntype); /* Find the median. */ qsort(times, n, sizeof (double), comp); idx = n / 2; if (n % 2) { start = times[idx]; } else { start = (times[idx - 1] + times[idx + 1]) / 2; } free(data); free(times); return start; } }
double reduce_bc(int n, size_t size) { int idx, i; char *data, value; bc_plist_t *other = NULL; bc_chan_t *src = NULL, *sink = NULL; bc_dtype_t *ntype; double start, *times; data = (char *) malloc(sizeof (char)*size); ntype = bc_dtype_create(sizeof (char)*size); times = (double *) malloc(sizeof (double)*n); /* Root of the reduction. */ if (bc_rank == 0) { sink = bc_sink_create(bc_plist_xall, ntype, 2, BC_ROLE_REPLICATE); src = bc_src_create(bc_plist_xall, ntype, BC_ROLE_REDUCE_SUM); for (i = 0; i < n; i++) { /* Put data. */ start = bc_gettime_usec(); bc_get(src, &value, 1); times[i] = bc_gettime_usec() - start; bc_put(sink, &value, 1); /* Wait for acknowledgement. */ } } else { other = bc_plist_create(1, 0); src = bc_src_create(other, ntype, BC_ROLE_PIPE); sink = bc_sink_create(other, ntype, 1, BC_ROLE_PIPE); for (i = 0; i < n; i++) { memset(data, bc_rank + 'a', size * bc_size); /* Get data. */ start = bc_gettime_usec(); bc_get(src, data, 1); /* Take this value. */ times[i] = bc_gettime_usec() - start; bc_put(sink, data, 1); /* Send acknowledgement. */ } bc_plist_destroy(other); } bc_chan_destroy(src); bc_chan_destroy(sink); bc_dtype_destroy(ntype); /* Find the median. */ qsort(times, n, sizeof (double), comp); idx = n / 2; if (n % 2) { start = times[idx]; } else { start = (times[idx - 1] + times[idx + 1]) / 2; } free(data); free(times); return start; }
static int mva (int print_intermediate) { int i = bc_rank, j; float one_less; /* Queue length with one less class r request. */ float sum_qlens; /* Sum of the queue lengths except for the current class. */ float sum_resis; /* Sum of the residence times for the current class. */ bc_chan_t *src_data, *sink_data; bc_chan_t *src_err, *sink_err; /* Estimate queue lengths. */ for (j = 0; j < nqueue; j++) if (val(serv_demand,i,j) > 0) val(qlen_est,i,j) = (float)load_vect[i]/visit_vect[i]; /* Create communication structure for data transfer. */ sink_data = bc_sink_create (bc_plist_xall, bc_float, 10, BC_ROLE_REPLICATE); src_data = bc_src_create (bc_plist_xall, bc_float, BC_ROLE_REDUCE_SUM); /* Create communication structure for relative error. */ sink_err = bc_sink_create (bc_plist_xall, bc_float, 10, BC_ROLE_REPLICATE); src_err = bc_src_create (bc_plist_xall, bc_float, BC_ROLE_REDUCE_MAX); /* During parallelisation, the following do loop is executed at * each process, which represents a class. The interprocess * communications happens during the calculation of 'sum_qlens' * and determination of the relative error. */ do { for (j = 0; j < nqueue; j++) val(qlen,i,j) = val(qlen_est,i,j); for (j = 0; j < nqueue; j++) { /* Queue length with one less class i request. */ bc_put (sink_data, ptr(qlen,i,j), 1); bc_get (src_data, &sum_qlens, 1); one_less = (load_vect[i] - 1)/load_vect[i]*val(qlen,i,j) + sum_qlens; /* Class i residence time at queue j. */ if (qtype[j] == DELAY) val(res_time,i,j) = val(serv_demand,i,j); else val(res_time,i,j) = val(serv_demand,i,j)*(1.0 + one_less); } /* Throughput for class i. */ sum_resis = 0.0; for (j = 0; j < nqueue; j++) sum_resis += val(res_time,i,j); throughput[i] = load_vect[i]/sum_resis; /* Compute new estimates for the queue lengths. */ for (j = 0; j < nqueue; j++) val(qlen_est,i,j) = throughput[i]*val(res_time,i,j); } while (!isdone(src_err, sink_err)); /* Destroy communication structure. */ bc_chan_destroy (src_data); bc_chan_destroy (sink_data); bc_chan_destroy (src_err); bc_chan_destroy (sink_err); return 0; }
static int isdone(bc_chan_t *src, bc_chan_t *sink) { int i = bc_rank, j; float rerror = 0.0; /* Relative error. */ float merror = 0.0; /* Maximum relative error. */ float r_error; /* Maximum error from remote. */ for (j = 0; j < nqueue; j++) { rerror = fabs((val(qlen_est,i,j) - val(qlen,i,j))/val(qlen_est,i,j)); if (rerror > merror) merror = rerror; } bc_put (sink, &merror, 1); bc_get (src, &r_error, 1); if (merror > r_error) merror = r_error; if (merror < epsilon) return 1; else return 0; }
char *hs_get(HStore *store, char *key, int *vlen, uint32_t *flag) { if (!key || !store) return NULL; if (key[0] == '@'){ char *r = hs_list(store, key+1); if (r) *vlen = strlen(r); *flag = 0; return r; } bool info = false; if (key[0] == '?'){ info = true; key ++; } int index = get_index(store, key); DataRecord *r = bc_get(store->bitcasks[index], key); if (r == NULL){ return NULL; } char *res = NULL; if (info){ res = malloc(256); if (!res) { free_record(r); return NULL; } uint16_t hash = 0; if (r->version > 0){ hash = gen_hash(r->value, r->vsz); } *vlen = snprintf(res, 255, "%d %u %u %u %u", r->version, hash, r->flag, r->vsz, r->tstamp); *flag = 0; }else if (r->version > 0){ res = record_value(r); r->value = NULL; *vlen = r->vsz; *flag = r->flag; } free_record(r); return res; }
void stage_4(void *out) { bc_plist_t *ipl; bc_chan_t *ibc; int i = 0; ipl = bc_plist_create(1, 2); ibc = bc_src_create(ipl, bc_int, BC_ROLE_PIPE); *((int *) out + 0) = 0; for (i= 0; i < 20; i++) { bc_get(ibc, (int *)out + 1, 1); *((int *) out + 0) += *((int *) out + 1); } bc_chan_destroy(ibc); bc_plist_destroy(ipl); }
bool bc_set(Bitcask *bc, const char* key, char* value, int vlen, int flag, int version) { if (version < 0 && vlen > 0 || vlen > MAX_RECORD_SIZE) { fprintf(stderr, "invalid set cmd \n"); return false; } bool suc = false; pthread_mutex_lock(&bc->write_lock); int oldv = 0, ver = version; Item *it = ht_get(bc->tree, key); if (it != NULL) { oldv = it->ver; } if (version == 0 && oldv > 0) // replace { ver = oldv + 1; } else if (version == 0 && oldv <= 0) // add { ver = -oldv + 1; } else if (version < 0 && oldv <= 0) // delete, not exist { goto SET_FAIL; } else if (version == -1) // delete { ver = - abs(oldv) - 1; } else if (abs(version) <= abs(oldv)) // sync { goto SET_FAIL; } else // sync { ver = version; } uint16_t hash = gen_hash(value, vlen); if (ver < 0) hash = 0; if (NULL != it && hash == it->hash) { DataRecord *r = bc_get(bc, key); if (r != NULL && r->flag == flag && vlen == r->vsz && memcmp(value, r->value, vlen) == 0) { if (version != 0) { // update version if (it->pos & 0xff == bc->curr) { ht_add(bc->curr_tree, key, it->pos, it->hash, ver); } ht_add(bc->tree, key, it->pos, it->hash, ver); } suc = true; free_record(r); goto SET_FAIL; } if (r != NULL) free_record(r); } int klen = strlen(key); DataRecord *r = (DataRecord*)malloc(sizeof(DataRecord) + klen); r->ksz = klen; memcpy(r->key, key, klen); r->vsz = vlen; r->value = value; r->free_value = false; r->flag = flag; r->version = ver; r->tstamp = time(NULL); int rlen; char *rbuf = encode_record(r, &rlen); if (rbuf == NULL || (rlen & 0xff) != 0) { fprintf(stderr, "encode_record() failed with %d\n", rlen); if (rbuf != NULL) free(rbuf); goto SET_FAIL; } pthread_mutex_lock(&bc->buffer_lock); // record maybe larger than buffer if (bc->wbuf_curr_pos + rlen > bc->wbuf_size) { pthread_mutex_unlock(&bc->buffer_lock); bc_flush(bc, 0, 0); pthread_mutex_lock(&bc->buffer_lock); while (rlen > bc->wbuf_size) { bc->wbuf_size *= 2; free(bc->write_buffer); bc->write_buffer = (char*)malloc(bc->wbuf_size); } if (bc->wbuf_start_pos + bc->wbuf_size > MAX_BUCKET_SIZE) { bc_rotate(bc); } } memcpy(bc->write_buffer + bc->wbuf_curr_pos, rbuf, rlen); int pos = (bc->wbuf_start_pos + bc->wbuf_curr_pos) | bc->curr; bc->wbuf_curr_pos += rlen; pthread_mutex_unlock(&bc->buffer_lock); ht_add(bc->curr_tree, key, pos, hash, ver); ht_add(bc->tree, key, pos, hash, ver); suc = true; free(rbuf); free_record(r); SET_FAIL: pthread_mutex_unlock(&bc->write_lock); if (it != NULL) free(it); return suc; }