ssize_t sock_comm_send(struct sock_pe_entry *pe_entry, const void *buf, size_t len) { ssize_t ret, used; if (len > pe_entry->cache_sz) { used = ofi_rbused(&pe_entry->comm_buf); if (used == sock_comm_flush(pe_entry)) { return sock_comm_send_socket(pe_entry->conn, buf, len); } else { return 0; } } if (ofi_rbavail(&pe_entry->comm_buf) < len) { ret = sock_comm_flush(pe_entry); if (ret <= 0) return 0; } ret = MIN(ofi_rbavail(&pe_entry->comm_buf), len); ofi_rbwrite(&pe_entry->comm_buf, buf, ret); ofi_rbcommit(&pe_entry->comm_buf); SOCK_LOG_DBG("buffered %lu\n", ret); return ret; }
static ssize_t _sock_cq_write(struct sock_cq *cq, fi_addr_t addr, const void *buf, size_t len) { ssize_t ret; struct sock_cq_overflow_entry_t *overflow_entry; fastlock_acquire(&cq->lock); if (ofi_rbfdavail(&cq->cq_rbfd) < len) { SOCK_LOG_ERROR("Not enough space in CQ\n"); overflow_entry = calloc(1, sizeof(*overflow_entry) + len); if (!overflow_entry) { ret = -FI_ENOSPC; goto out; } memcpy(&overflow_entry->cq_entry[0], buf, len); overflow_entry->len = len; overflow_entry->addr = addr; dlist_insert_tail(&overflow_entry->entry, &cq->overflow_list); ret = len; goto out; } ofi_rbwrite(&cq->addr_rb, &addr, sizeof(addr)); ofi_rbcommit(&cq->addr_rb); ofi_rbfdwrite(&cq->cq_rbfd, buf, len); if (cq->domain->progress_mode == FI_PROGRESS_MANUAL) ofi_rbcommit(&cq->cq_rbfd.rb); else ofi_rbfdcommit(&cq->cq_rbfd); ret = len; if (cq->signal) sock_wait_signal(cq->waitset); out: fastlock_release(&cq->lock); return ret; }
static inline void sock_cq_copy_overflow_list(struct sock_cq *cq, size_t count) { size_t i; struct sock_cq_overflow_entry_t *overflow_entry; for (i = 0; i < count && !dlist_empty(&cq->overflow_list); i++) { overflow_entry = container_of(cq->overflow_list.next, struct sock_cq_overflow_entry_t, entry); ofi_rbwrite(&cq->addr_rb, &overflow_entry->addr, sizeof(fi_addr_t)); ofi_rbcommit(&cq->addr_rb); ofi_rbfdwrite(&cq->cq_rbfd, &overflow_entry->cq_entry[0], overflow_entry->len); if (cq->domain->progress_mode == FI_PROGRESS_MANUAL) ofi_rbcommit(&cq->cq_rbfd.rb); else ofi_rbfdcommit(&cq->cq_rbfd); dlist_remove(&overflow_entry->entry); free(overflow_entry); } }
static void sock_comm_recv_buffer(struct sock_pe_entry *pe_entry) { int ret; size_t max_read, avail; avail = ofi_rbavail(&pe_entry->comm_buf); assert(avail == pe_entry->comm_buf.size); pe_entry->comm_buf.rcnt = pe_entry->comm_buf.wcnt = pe_entry->comm_buf.wpos = 0; max_read = pe_entry->rem ? pe_entry->rem : pe_entry->total_len - pe_entry->done_len; ret = sock_comm_recv_socket(pe_entry->conn, (char *) pe_entry->comm_buf.buf, MIN(max_read, avail)); pe_entry->comm_buf.wpos += ret; ofi_rbcommit(&pe_entry->comm_buf); }
int sock_cq_report_error(struct sock_cq *cq, struct sock_pe_entry *entry, size_t olen, int err, int prov_errno, void *err_data, size_t err_data_size) { int ret; struct fi_cq_err_entry err_entry; fastlock_acquire(&cq->lock); if (ofi_rbavail(&cq->cqerr_rb) < sizeof(err_entry)) { ret = -FI_ENOSPC; goto out; } err_entry.err = err; err_entry.olen = olen; err_entry.err_data = err_data; err_entry.err_data_size = err_data_size; err_entry.len = entry->data_len; err_entry.prov_errno = prov_errno; err_entry.flags = entry->flags; err_entry.data = entry->data; err_entry.tag = entry->tag; err_entry.op_context = (void *) (uintptr_t) entry->context; if (entry->type == SOCK_PE_RX) err_entry.buf = (void *) (uintptr_t) entry->pe.rx.rx_iov[0].iov.addr; else err_entry.buf = (void *) (uintptr_t) entry->pe.tx.tx_iov[0].src.iov.addr; ofi_rbwrite(&cq->cqerr_rb, &err_entry, sizeof(err_entry)); ofi_rbcommit(&cq->cqerr_rb); ret = 0; ofi_rbfdsignal(&cq->cq_rbfd); out: fastlock_release(&cq->lock); return ret; }