void _opque_start_execution(opque_t *que) { int n, i; callback_t *cb; op_generic_t *gop; que_data_t *q = &(que->qd); gop = opque_get_gop(que); if (gop->base.started_execution != 0) { return; } gop->base.started_execution = 1; n = stack_size(q->list); move_to_top(q->list); for (i=0; i<n; i++) { cb = (callback_t *)pop(q->list); gop = (op_generic_t *)cb->priv; if (gop->type == Q_TYPE_OPERATION) { log_printf(15, "qid=%d gid=%d\n",gop_id(opque_get_gop(que)), gop_get_id(gop)); gop->base.started_execution = 1; gop->base.pc->fn->submit(gop->base.pc->arg, gop); } else { //** It's a queue log_printf(15, "qid=%d Q gid=%d\n",gop_id(opque_get_gop(que)), gop_get_id(gop)); lock_opque(gop->q); _opque_start_execution(gop->q->opque); unlock_opque(gop->q); } } // unlock_opque(q); }
void gop_generic_free(op_generic_t *gop, int mode) { log_printf(20, "op_generic_free: before lock gid=%d\n", gop_get_id(gop)); lock_gop(gop); //** Make sure I own the lock just to be safe log_printf(20, "op_generic_free: AFTER lock gid=%d\n", gop_get_id(gop)); callback_destroy(gop->base.cb); //** Free the callback chain as well unlock_gop(gop); //** Make sure the lock is left in the proper state for reuse release_pigeon_coop_hole(_gop_control, &(gop->base.ctl->pch)); }
void _gop_start_execution(op_generic_t *g) { if (gop_get_type(g) == Q_TYPE_QUE) { _opque_start_execution(g->q->opque); } else if (g->base.started_execution == 0) { log_printf(15, "gid=%d started_execution=%d\n", gop_get_id(g), g->base.started_execution); g->base.started_execution = 1; g->base.pc->fn->submit(g->base.pc->arg, g); } }
int internal_opque_add(opque_t *que, op_generic_t *gop, int dolock) { int err = 0; callback_t *cb; que_data_t *q = &(que->qd); //** Create the callback ** type_malloc(cb, callback_t, 1); callback_set(cb, _opque_cb, (void *)gop); //** Set the global callback for the list if (dolock != 0) lock_opque(q); log_printf(15, "opque_add: qid=%d gid=%d\n", que->op.base.id, gop_get_id(gop)); //** Add the list CB to the the op // lock_gop(gop) gop->base.parent_q = que; callback_append(&(gop->base.cb), cb); // unlock_gop(gop) //**Add the op to the q q->nsubmitted++; q->nleft++; if (q->opque->op.base.started_execution == 0) { move_to_bottom(q->list); insert_below(q->list, (void *)cb); } if (dolock != 0) unlock_opque(q); if (q->opque->op.base.started_execution == 1) { if (gop->type == Q_TYPE_OPERATION) { log_printf(15, "gid=%d started_execution=%d\n", gop_get_id(gop), gop->base.started_execution); gop->base.started_execution = 1; gop->base.pc->fn->submit(gop->base.pc->arg, gop); } else { //** It's a queue opque_start_execution(gop->q->opque); } } return(err); }
double write_allocs(ibp_capset_t *caps, int qlen, int n, int asize, int block_size) { int count, i, j, nleft, nblocks, rem, len, err, block_start, alloc_start; int *slot; op_status_t status; int64_t nbytes, last_bytes, print_bytes, delta_bytes; apr_int32_t nfds, finished; double dbytes, r1, r2; apr_pool_t *pool; apr_file_t *fd_in; opque_t *q; op_generic_t *op; char *buffer = (char *)malloc(block_size); apr_interval_time_t dt = 10; apr_pollfd_t pfd; apr_time_t stime, dtime; int *tbuf_index; tbuffer_t *buf; Stack_t *tbuf_free; tbuf_free = new_stack(); type_malloc_clear(tbuf_index, int, qlen); type_malloc_clear(buf, tbuffer_t, qlen); for (i=0; i<qlen; i++) { tbuf_index[i] = i; push(tbuf_free, &(tbuf_index[i])); } //** Make the stuff to capture the kbd apr_pool_create(&pool, NULL); nfds = 1; apr_file_open_stdin(&fd_in, pool); pfd.p = pool; pfd.desc_type = APR_POLL_FILE; pfd.reqevents = APR_POLLIN|APR_POLLHUP; pfd.desc.f = fd_in; pfd.client_data = NULL; //** Init the ibp stuff init_buffer(buffer, 'W', block_size); q = new_opque(); opque_start_execution(q); nblocks = asize / block_size; rem = asize % block_size; if (rem > 0) nblocks++; block_start = 0; alloc_start = 0; finished = 0; apr_poll(&pfd, nfds, &finished, dt); count = 0; nbytes=0; last_bytes = 0; delta_bytes = 1024 * 1024 * 1024; print_bytes = delta_bytes; stime = apr_time_now(); while (finished == 0) { // nleft = qlen - opque_tasks_left(q); nleft = stack_size(tbuf_free); // printf("\nLOOP: nleft=%d qlen=%d\n", nleft, qlen); if (nleft > 0) { for (j=block_start; j < nblocks; j++) { for (i=alloc_start; i<n; i++) { nleft--; if (nleft <= 0) { block_start = j; alloc_start = i; goto skip_submit; } slot = (int *)pop(tbuf_free); if ((j==(nblocks-1)) && (rem > 0)) { len = rem; } else { len = block_size; } // printf("%d=(%d,%d) ", count, j, i); tbuffer_single(&(buf[*slot]), len, buffer); op = new_ibp_write_op(ic, get_ibp_cap(&(caps[i]), IBP_WRITECAP), j*block_size, &(buf[*slot]), 0, len, ibp_timeout); gop_set_id(op, *slot); ibp_op_set_cc(ibp_get_iop(op), cc); ibp_op_set_ncs(ibp_get_iop(op), ncs); opque_add(q, op); } alloc_start = 0; } block_start = 0; } skip_submit: finished = 1; apr_poll(&pfd, nfds, &finished, dt); do { //** Empty the finished queue. Always wait for for at least 1 to complete op = opque_waitany(q); status = gop_get_status(op); if (status.error_code != IBP_OK) { printf("ERROR: Aborting with error code %d\n", status.error_code); finished = 0; } count++; i = gop_get_id(op); nbytes = nbytes + tbuffer_size(&(buf[i])); if (nbytes > print_bytes) { dbytes = nbytes / (1.0*1024*1024*1024); dtime = apr_time_now() - stime; r2 = dtime / (1.0 * APR_USEC_PER_SEC); r1 = nbytes - last_bytes; r1 = r1 / (r2 * 1024.0 * 1024.0); printf("%.2lfGB written (%.2lfMB/s : %.2lf secs)\n", dbytes, r1, r2); print_bytes = print_bytes + delta_bytes; last_bytes = nbytes; stime = apr_time_now(); } push(tbuf_free, &(tbuf_index[i])); gop_free(op, OP_DESTROY); } while (opque_tasks_finished(q) > 0); } err = opque_waitall(q); if (err != OP_STATE_SUCCESS) { printf("write_allocs: At least 1 error occured! * ibp_errno=%d * nfailed=%d\n", err, opque_tasks_failed(q)); } opque_free(q, OP_DESTROY); free_stack(tbuf_free, 0); free(tbuf_index); free(buf); free(buffer); apr_pool_destroy(pool); dbytes = nbytes; return(dbytes); }