// Issue the command to the selected worker static void master_issue(uint64_t cmd_id, int target){ // Wait until we have space to issue while (g_master->queue_depth[target] == ISSUE_BUF_SIZE){ clear_issue(target); } // Issue directly for (int i = 0; i < ISSUE_BUF_SIZE; i++){ if (issue_buf[target].issue_queue[i].io_completed == 1){ // Write issue_buf slot issue_buf[target].issue_queue[i].io_completed = 0; issue_buf[target].issue_queue[i].cmd_id = cmd_id; // Issue the cmd g_master->queue_depth[target] += 1; uint64_t addr = iotasks[cmd_id].asu * f_maxlba + iotasks[cmd_id].lba; // Distinguish the r/w struct issue_task *ptr = &(issue_buf[target].issue_queue[i]); if (iotasks[cmd_id].type == 0) submit_read(tasks[target], addr, iotasks[cmd_id].size, target, ptr); else submit_write(tasks[target], addr, iotasks[cmd_id].size, target, ptr); break; } } }
ssize_t pni_iocp_begin_write(iocpdesc_t *iocpd, const void *buf, size_t len, bool *would_block, pn_error_t *error) { if (len == 0) return 0; *would_block = false; if (is_listener(iocpd)) { set_iocp_error_status(error, PN_ERR, WSAEOPNOTSUPP); return INVALID_SOCKET; } if (iocpd->closing) { set_iocp_error_status(error, PN_ERR, WSAESHUTDOWN); return SOCKET_ERROR; } if (iocpd->write_closed) { assert(pn_error_code(iocpd->error)); pn_error_copy(error, iocpd->error); if (iocpd->iocp->iocp_trace) iocp_log("write error: %s\n", pn_error_text(error)); return SOCKET_ERROR; } if (len == 0) return 0; if (!(iocpd->events & PN_WRITABLE)) { *would_block = true; return SOCKET_ERROR; } size_t written = 0; size_t requested = len; const char *outgoing = (const char *) buf; size_t available = pni_write_pipeline_reserve(iocpd->pipeline, len); if (!available) { *would_block = true; return SOCKET_ERROR; } for (size_t wr_count = 0; wr_count < available; wr_count++) { write_result_t *result = pni_write_pipeline_next(iocpd->pipeline); assert(result); result->base.iocpd = iocpd; ssize_t actual_len = pn_min(len, result->buffer.size); result->requested = actual_len; memmove((void *)result->buffer.start, outgoing, actual_len); outgoing += actual_len; written += actual_len; len -= actual_len; int werror = submit_write(result, result->buffer.start, actual_len); if (werror && WSAGetLastError() != ERROR_IO_PENDING) { pni_write_pipeline_return(iocpd->pipeline, result); iocpdesc_fail(iocpd, WSAGetLastError(), "overlapped send"); return SOCKET_ERROR; } iocpd->ops_in_progress++; } if (!pni_write_pipeline_writable(iocpd->pipeline)) pni_events_update(iocpd, iocpd->events & ~PN_WRITABLE); return written; }