u32 object_write(Worker *worker, u64 oid, u32 mtime, u64 offset, u32 count, u8 *data, void *raw) { struct object_write_env env = { .worker = worker, .oid = oid, .mtime = mtime, .offset = offset, .count = count, .data = data }; Transaction *trans = trans_new(storage_servers[0], NULL, message_new()); struct Rswrite *res; assert(raw != NULL); trans->out->raw = raw; trans->out->tag = ALLOCTAG; trans->out->id = TSWRITE; set_tswrite(trans->out, mtime, offset, count, data, oid); send_request_to_all(trans, (void (*)(void *)) object_write_cb, &env); res = &trans->in->msg.rswrite; return res->count; }
u64 object_reserve_oid(Worker *worker) { assert(storage_server_count > 0); /* is someone else in the process of requesting new oids? */ while (object_reserve_wait != NULL) cond_wait(object_reserve_wait); /* do we need to request a fresh batch of oids? */ if (object_reserve_remaining == 0) { /* the first storage server is considered the master */ Transaction *trans = trans_new(storage_servers[0], NULL, message_new()); struct Rsreserve *res; pthread_cond_t *wait; trans->out->tag = ALLOCTAG; trans->out->id = TSRESERVE; wait = object_reserve_wait = cond_new(); send_request(trans); object_reserve_wait = NULL; cond_broadcast(wait); res = &trans->in->msg.rsreserve; object_reserve_next = res->firstoid; object_reserve_remaining = res->count; } object_reserve_remaining--; return object_reserve_next++; }
void object_delete(Worker *worker, u64 oid) { struct object_delete_env env = { .worker = worker, .oid = oid }; Transaction *trans = trans_new(storage_servers[0], NULL, message_new()); trans->out->tag = ALLOCTAG; trans->out->id = TSDELETE; set_tsdelete(trans->out, oid); send_request_to_all(trans, (void (*)(void *)) object_delete_cb, &env); }
void object_wstat(Worker *worker, u64 oid, struct p9stat *info) { struct object_wstat_env env = { .worker = worker, .oid = oid, .info = info }; Transaction *trans = trans_new(storage_servers[0], NULL, message_new()); trans->out->tag = ALLOCTAG; trans->out->id = TSWSTAT; set_tswstat(trans->out, oid, info); send_request_to_all(trans, (void (*)(void *)) object_wstat_cb, &env); }
struct p9stat *object_stat(Worker *worker, u64 oid, char *filename) { int i; Transaction *trans; struct Rsstat *res; struct p9stat *info; /* handle it from the cache if it exists */ if (object_cache_isvalid(oid)) { info = disk_stat(worker, oid); info->name = filename; return info; } i = randInt(storage_server_count); trans = trans_new(storage_servers[i], NULL, message_new()); trans->out->tag = ALLOCTAG; trans->out->id = TSSTAT; set_tsstat(trans->out, oid); /* send the request to one randomly chosen storage server */ send_request(trans); assert(trans->in != NULL && trans->in->id == RSSTAT); res = &trans->in->msg.rsstat; /* insert the filename supplied by the caller */ res->stat->name = filename; /* check if we have a cache entry with matching stats */ if (objectroot != NULL && (info = disk_stat(worker, oid)) != NULL) { info->name = filename; info->atime = res->stat->atime; /* if it's up-to-date, note it as a valid entry */ if (!p9stat_cmp(info, res->stat)) object_cache_validate(oid); } return res->stat; }
void *object_read(Worker *worker, u64 oid, u32 atime, u64 offset, u32 count, u32 *bytesread, u8 **data) { int i; Transaction *trans; struct Rsread *res; void *result; /* read from the cache if it exists */ if (object_cache_isvalid(oid)) { u8 *raw = raw_new(); int len; *data = raw + RSREAD_DATA_OFFSET; len = disk_read(worker, oid, atime, offset, count, *data); assert(len > 0); *bytesread = len; return raw; } i = randInt(storage_server_count); trans = trans_new(storage_servers[i], NULL, message_new()); trans->out->tag = ALLOCTAG; trans->out->id = TSREAD; set_tsread(trans->out, oid, atime, offset, count); /* send the request to one randomly chosen storage server */ send_request(trans); assert(trans->in != NULL && trans->in->id == RSREAD); res = &trans->in->msg.rsread; *bytesread = res->count; *data = res->data; result = trans->in->raw; trans->in->raw = NULL; return result; }
static void send_request_to_all(Transaction *trans, void (*callback)(void *), void *env) { List *requests = cons(trans, NULL); int i; for (i = 1; i < storage_server_count; i++) { Transaction *newtrans = trans_new(storage_servers[i], NULL, message_new()); /* copy the whole mess over */ memcpy(newtrans->out, trans->out, sizeof(Message)); /* for tswrite, we need to copy the data payload as well */ if (newtrans->out->raw != NULL) { struct Tswrite *req = &newtrans->out->msg.tswrite; assert(trans->out->id == TSWRITE); newtrans->out->raw = raw_new(); req->data = newtrans->out->raw + TWRITE_DATA_OFFSET; memcpy(req->data, trans->out->raw + TWRITE_DATA_OFFSET, req->count); } requests = cons(newtrans, requests); } /* send request to all storage servers and wait for all to respond */ send_requests(requests, callback, env); /* make sure they all succeeded */ while (!null(requests)) { trans = car(requests); assert(trans->in != NULL && trans->in->id == trans->out->id + 1); requests = cdr(requests); } }
struct qid object_create(Worker *worker, u64 oid, u32 mode, u32 ctime, char *uid, char *gid, char *extension) { Transaction *trans = trans_new(storage_servers[0], NULL, message_new()); struct Rscreate *res; int len; /* create it in the cache */ if (objectroot != NULL) { len = disk_create(worker, oid, mode, ctime, uid, gid, extension); assert(len >= 0); object_cache_validate(oid); } /* create it on the storage servers */ trans->out->tag = ALLOCTAG; trans->out->id = TSCREATE; set_tscreate(trans->out, oid, mode, ctime, uid, gid, extension); send_request_to_all(trans, NULL, NULL); res = &trans->in->msg.rscreate; return res->qid; }
int main(int argc, char** argv) { int ret; int xml_file = xml_get_XML_File("gri30.xml", 0); assert(xml_file > 0); int phase_node = xml_findID(xml_file, "gri30_mix"); assert(phase_node > 0); int thermo = thermo_newFromXML(phase_node); assert(thermo > 0); int nsp = thermo_nSpecies(thermo); assert(nsp == 53); ret = thermo_setTemperature(thermo, 500); assert(ret == 0); ret = thermo_setPressure(thermo, 5 * 101325); assert(ret == 0); ret = thermo_setMoleFractionsByName(thermo, "CH4:1.0, O2:2.0, N2:7.52"); assert(ret == 0); ret = thermo_equilibrate(thermo, "HP", 0, 1e-9, 50000, 1000, 0); assert(ret == 0); double T = thermo_temperature(thermo); assert(T > 2200 && T < 2300); ret = thermo_print(thermo, 1, 0); assert(ret == 0); int kin = kin_newFromXML(phase_node, thermo, 0, 0, 0, 0); assert(kin > 0); size_t nr = kin_nReactions(kin); assert(nr == 325 ); ret = thermo_setTemperature(thermo, T - 200); assert(ret == 0); char buf [1000]; double ropf[325]; printf("\n Reaction Forward ROP\n"); kin_getFwdRatesOfProgress(kin, 325, ropf); size_t n; // declare this here for C89 compatibility for (n = 0; n < nr; n++) { kin_getReactionString(kin, n, 1000, buf); printf("%35s %8.6e\n", buf, ropf[n]); } printf("\n Species Mix diff coeff\n"); int tran = trans_new("Mix", thermo, 0); double dkm[53]; trans_getMixDiffCoeffs(tran, 53, dkm); int k; // declare this here for C89 compatibility for (k = 0; k < nsp; k++) { thermo_getSpeciesName(thermo, k, 1000, buf); printf("%10s %8.6e\n", buf, dkm[k]); } ret = thermo_setTemperature(thermo, 1050); assert(ret == 0); ret = thermo_setPressure(thermo, 5 * 101325); assert(ret == 0); ret = thermo_setMoleFractionsByName(thermo, "CH4:1.0, O2:2.0, N2:7.52"); assert(ret == 0); printf("\ntime Temperature\n"); int reactor = reactor_new(5); int net = reactornet_new(); ret = reactor_setThermoMgr(reactor, thermo); assert(ret == 0); ret = reactor_setKineticsMgr(reactor, kin); assert(ret == 0); ret = reactornet_addreactor(net, reactor); assert(ret == 0); double t = 0.0; while (t < 0.1 && ret == 0) { double T = reactor_temperature(reactor); t = reactornet_time(net); printf("%.2e %.3f\n", t, T); ret = reactornet_advance(net, t + 5e-3); assert(ret == 0); } ct_appdelete(); return 0; }
void object_fetch(Worker *worker, u64 oid, struct p9stat *info) { int res; u32 packetsize; u32 packetcount; u64 offset; int i; int start; u32 time = now(); List **queues; struct object_fetch_env env; if (objectroot == NULL || object_cache_isvalid(oid)) return; /* delete any existing entry in the cache */ res = disk_delete(worker, oid); assert(res >= 0 || -res == ENOENT); /* create the file */ disk_create(worker, oid, info->mode, info->mtime, info->uid, info->gid, info->extension); /* empty file? */ if (info->length == 0 || !emptystring(info->extension)) { int res = disk_wstat(worker, oid, info); assert(res == 0); return; } /* stripe the reads across the storage servers */ queues = GC_MALLOC(sizeof(List *) * storage_server_count); assert(queues != NULL); queues[0] = NULL; packetsize = (storage_servers[0]->maxSize / BLOCK_SIZE) * BLOCK_SIZE; for (i = 1; i < storage_server_count; i++) { int size = (storage_servers[i]->maxSize / BLOCK_SIZE) * BLOCK_SIZE; packetsize = min(packetsize, size); queues[i] = NULL; } packetcount = (info->length + (packetsize - 1)) / packetsize; i = 0; offset = 0; start = randInt(storage_server_count); /* create read requests in contiguous chunks for each server */ while (offset < info->length) { u64 size = info->length - offset; if (size > packetsize) size = packetsize; Transaction *trans = trans_new( storage_servers[(i + start) % storage_server_count], NULL, message_new()); trans->out->tag = ALLOCTAG; trans->out->id = TSREAD; set_tsread(trans->out, oid, time, offset, (u32) size); queues[i] = cons(trans, queues[i]); offset += size; /* time to switch to next server? */ if (offset * storage_server_count > info->length * (i + 1)) i++; } /* put the requests in sequential order */ for (i = 0; i < storage_server_count; i++) queues[i] = reverse(queues[i]); env.file = disk_get_openfile(worker, oid); assert(env.file != NULL); env.wait = NULL; if (ftruncate(env.file->fd, info->length) < 0) assert(0); send_requests_streamed(queues, storage_server_count, (void (*)(void *, Transaction *)) object_fetch_iter, &env); if (disk_wstat(worker, oid, info) != 0) assert(0); object_cache_validate(oid); }