int yr_scan_verify_match( YR_SCAN_CONTEXT* context, YR_AC_MATCH* ac_match, const uint8_t* data, size_t data_size, uint64_t data_base, size_t offset) { YR_STRING* string = ac_match->string; int result; if (data_size - offset <= 0) return ERROR_SUCCESS; if (STRING_IS_DISABLED(string)) return ERROR_SUCCESS; if (context->flags & SCAN_FLAGS_FAST_MODE && STRING_IS_SINGLE_MATCH(string) && string->matches[context->tidx].head != NULL) return ERROR_SUCCESS; if (STRING_IS_FIXED_OFFSET(string) && string->fixed_offset != data_base + offset) return ERROR_SUCCESS; #ifdef PROFILING_ENABLED uint64_t start_time = yr_stopwatch_elapsed_us(&context->stopwatch); #endif if (STRING_IS_LITERAL(string)) { result = _yr_scan_verify_literal_match( context, ac_match, data, data_size, data_base, offset); } else { result = _yr_scan_verify_re_match( context, ac_match, data, data_size, data_base, offset); } if (result != ERROR_SUCCESS) context->last_error_string = string; #ifdef PROFILING_ENABLED uint64_t finish_time = yr_stopwatch_elapsed_us(&context->stopwatch); #ifdef _WIN32 InterlockedAdd64(&string->time_cost, finish_time - start_time); InterlockedAdd64(&string->rule->time_cost, finish_time - start_time); #else __sync_fetch_and_add(&string->time_cost, finish_time - start_time); __sync_fetch_and_add(&string->rule->time_cost, finish_time - start_time); #endif #endif return result; }
void account_mem (MonoMemAccountType type, ssize_t size) { #if SIZEOF_VOID_P == 4 InterlockedAdd ((volatile gint32*)&allocation_count [type], (gint32)size); #else InterlockedAdd64 ((volatile gint64*)&allocation_count [type], (gint64)size); #endif }
void connection::make_sequence() { do { // ID主要用于判定超时的时候,防止地址或名称重用,超时时间内64位整数不可能会重复 #if defined(HIREDIS_HAPP_ATOMIC_STD) static std::atomic<uint64_t> seq_alloc(0); sequence = seq_alloc.fetch_add(1); #elif defined(HIREDIS_HAPP_ATOMIC_MSVC) static LONGLONG volatile seq_alloc = 0; sequence = static_cast<uint64_t>(InterlockedAdd64(&seq_alloc, 1)); #elif defined(HIREDIS_HAPP_ATOMIC_GCC_ATOMIC) static volatile uint64_t seq_alloc = 0; sequence = __atomic_add_fetch(&seq_alloc, 1, __ATOMIC_SEQ_CST); #elif defined(HIREDIS_HAPP_ATOMIC_GCC) static volatile uint64_t seq_alloc = 0; sequence = __sync_fetch_and_add (&seq_alloc, 1); #else static volatile uint64_t seq_alloc = 0; sequence = ++ seq_alloc; #endif } while(0 == sequence); }
static ssize_t ofi_nd_ep_readv(struct fid_ep *pep, const struct iovec *iov, void **desc, size_t count, fi_addr_t src_addr, uint64_t addr, uint64_t key, void *context) { struct fi_rma_iov rma_iov = { .addr = addr, .len = iov[0].iov_len, .key = key }; struct fi_msg_rma msg = { .msg_iov = iov, .desc = desc, .iov_count = count, .addr = src_addr, .rma_iov = &rma_iov, .rma_iov_count = 1, .context = context, .data = 0 }; assert(pep->fid.fclass == FI_CLASS_EP); if (pep->fid.fclass != FI_CLASS_EP) return -FI_EINVAL; struct nd_ep *ep = container_of(pep, struct nd_ep, fid); return ofi_nd_ep_readmsg(pep, &msg, ep->info->rx_attr->op_flags); } static ssize_t ofi_nd_ep_readmsg(struct fid_ep *pep, const struct fi_msg_rma *msg, uint64_t flags) { assert(pep->fid.fclass == FI_CLASS_EP); assert(msg); if (pep->fid.fclass != FI_CLASS_EP) return -FI_EINVAL; size_t msg_len = 0, rma_len = 0, i; HRESULT hr; struct nd_ep *ep = container_of(pep, struct nd_ep, fid); if (!ep->qp) return -FI_EOPBADSTATE; for (i = 0; i < msg->iov_count; i++) { if (msg->msg_iov[i].iov_len && !msg->msg_iov[i].iov_base) return -FI_EINVAL; msg_len += msg->msg_iov[i].iov_len; } for (i = 0; i < msg->rma_iov_count; i++) { if (msg->rma_iov[i].len && !msg->rma_iov[i].addr) return -FI_EINVAL; rma_len += msg->rma_iov[i].len; } /* Check the following: */ if ((msg_len != rma_len) || /* - msg and rma len are correlated */ /* - iov counts are less or equal than supported */ (msg->iov_count > ND_MSG_IOV_LIMIT || msg->rma_iov_count > ND_MSG_IOV_LIMIT) || /* - transmitted length is less or equal than max possible */ (msg_len > ep->domain->info->ep_attr->max_msg_size)) return -FI_EINVAL; struct nd_cq_entry *main_entry = ofi_nd_buf_alloc_nd_cq_entry(); if (!main_entry) return -FI_ENOMEM; memset(main_entry, 0, sizeof(*main_entry)); main_entry->data = msg->data; main_entry->flags = flags; main_entry->domain = ep->domain; main_entry->context = msg->context; main_entry->seq = InterlockedAdd64(&ep->domain->msg_cnt, 1); /* since write operation can't be canceled, set NULL into * the 1st byte of internal data of context */ if (msg->context) ND_FI_CONTEXT(msg->context) = 0; struct fi_rma_iov rma_iovecs[ND_MSG_INTERNAL_IOV_LIMIT]; size_t rma_count = 0; size_t from_split_map[ND_MSG_INTERNAL_IOV_LIMIT]; size_t to_split_map[ND_MSG_INTERNAL_IOV_LIMIT]; uint64_t remote_addr[ND_MSG_INTERNAL_IOV_LIMIT]; ofi_nd_split_msg_iov_2_rma_iov(msg->rma_iov, msg->rma_iov_count, msg->msg_iov, msg->iov_count, rma_iovecs, &rma_count, from_split_map, to_split_map, remote_addr); assert(rma_count <= ND_MSG_INTERNAL_IOV_LIMIT); main_entry->wait_completion.comp_count = 0; main_entry->wait_completion.total_count = rma_count; InitializeCriticalSection(&main_entry->wait_completion.comp_lock); struct nd_cq_entry *entries[ND_MSG_IOV_LIMIT]; for (i = 0; i < rma_count; i++) { entries[i] = ofi_nd_buf_alloc_nd_cq_entry(); if (!entries[i]) goto fn_fail; memset(entries[i], 0, sizeof(*entries[i])); entries[i]->data = msg->data; entries[i]->flags = flags; entries[i]->domain = ep->domain; entries[i]->context = msg->context; entries[i]->seq = main_entry->seq; entries[i]->aux_entry = main_entry; hr = ep->domain->adapter->lpVtbl->CreateMemoryRegion( ep->domain->adapter, &IID_IND2MemoryRegion, ep->domain->adapter_file, (void**)&entries[i]->mr[0]); if (FAILED(hr)) goto fn_fail; entries[i]->mr_count = 1; hr = ofi_nd_util_register_mr( entries[i]->mr[0], (const void *)remote_addr[i], rma_iovecs[i].len, ND_MR_FLAG_ALLOW_LOCAL_WRITE | ND_MR_FLAG_ALLOW_REMOTE_READ | ND_MR_FLAG_ALLOW_REMOTE_WRITE); if (FAILED(hr)) goto fn_fail; ND2_SGE sge = { .Buffer = (void *)remote_addr[i], .BufferLength = (ULONG)rma_iovecs[i].len, .MemoryRegionToken = (UINT32)(uintptr_t)msg->desc[to_split_map[i]] }; hr = ep->qp->lpVtbl->Read(ep->qp, entries[i], &sge, 1, (UINT64)rma_iovecs[i].addr, (UINT32)rma_iovecs[i].key, 0); if (FAILED(hr)) goto fn_fail; } return FI_SUCCESS; fn_fail: while (i-- > 0) ofi_nd_free_cq_entry(entries[i]); ND_LOG_WARN(FI_LOG_EP_DATA, ofi_nd_strerror((DWORD)hr, NULL)); return H2F(hr); } static ssize_t ofi_nd_ep_write(struct fid_ep *ep, const void *buf, size_t len, void *desc, fi_addr_t dest_addr, uint64_t addr, uint64_t key, void *context) { struct iovec iov = { .iov_base = (void*)buf, .iov_len = len }; return ofi_nd_ep_writev(ep, &iov, &desc, 1, dest_addr, addr, key, context); } static ssize_t ofi_nd_ep_writev(struct fid_ep *pep, const struct iovec *iov, void **desc, size_t count, fi_addr_t dest_addr, uint64_t addr, uint64_t key, void *context) { struct fi_rma_iov rma_iov = { .addr = addr, .len = iov[0].iov_len, .key = key }; struct fi_msg_rma msg = { .msg_iov = iov, .desc = desc, .iov_count = count, .addr = dest_addr, .rma_iov = &rma_iov, .rma_iov_count = 1, .context = context, .data = 0 }; assert(pep->fid.fclass == FI_CLASS_EP); if (pep->fid.fclass != FI_CLASS_EP) return -FI_EINVAL; struct nd_ep *ep = container_of(pep, struct nd_ep, fid); return ofi_nd_ep_writemsg(pep, &msg, ep->info->tx_attr->op_flags); } static ssize_t ofi_nd_ep_writemsg(struct fid_ep *pep, const struct fi_msg_rma *msg, uint64_t flags) { assert(pep->fid.fclass == FI_CLASS_EP); assert(msg); if (pep->fid.fclass != FI_CLASS_EP) return -FI_EINVAL; size_t msg_len = 0, rma_len = 0, i; HRESULT hr; struct nd_cq_entry *entries[ND_MSG_IOV_LIMIT]; struct nd_ep *ep = container_of(pep, struct nd_ep, fid); if (!ep->qp) return -FI_EOPBADSTATE; for (i = 0; i < msg->iov_count; i++) { if (msg->msg_iov[i].iov_len && !msg->msg_iov[i].iov_base) return -FI_EINVAL; msg_len += msg->msg_iov[i].iov_len; } if ((msg_len > ep->domain->info->ep_attr->max_msg_size) && (flags & FI_INJECT)) return -FI_EINVAL; for (i = 0; i < msg->rma_iov_count; i++) { if (msg->rma_iov[i].len && !msg->rma_iov[i].addr) return -FI_EINVAL; rma_len += msg->rma_iov[i].len; } /* Check the following: */ if ((msg_len != rma_len) || /* - msg and rma len are correlated */ /* - iov counts are less or equal than supported */ ((msg->iov_count > ND_MSG_IOV_LIMIT || msg->rma_iov_count > ND_MSG_IOV_LIMIT)) || /* - transmitted length is less or equal than max possible */ (msg_len > ep->domain->info->ep_attr->max_msg_size) || /* - if INJECT, data should be inlined */ ((flags & FI_INJECT) && (msg_len > ep->domain->info->tx_attr->inject_size))) return -FI_EINVAL; struct nd_cq_entry *main_entry = ofi_nd_buf_alloc_nd_cq_entry(); if (!main_entry) return -FI_ENOMEM; memset(main_entry, 0, sizeof(*main_entry)); main_entry->data = msg->data; main_entry->flags = flags; main_entry->domain = ep->domain; main_entry->context = msg->context; main_entry->seq = InterlockedAdd64(&ep->domain->msg_cnt, 1); /* since write operation can't be canceled, set NULL into * the 1st byte of internal data of context */ if (msg->context) ND_FI_CONTEXT(msg->context) = 0; /* TODO */ if (msg_len > (size_t)gl_data.inline_thr) { struct fi_rma_iov rma_iovecs[ND_MSG_INTERNAL_IOV_LIMIT]; size_t rma_count = 0; size_t from_split_map[ND_MSG_INTERNAL_IOV_LIMIT]; size_t to_split_map[ND_MSG_INTERNAL_IOV_LIMIT]; uint64_t remote_addr[ND_MSG_INTERNAL_IOV_LIMIT]; ofi_nd_split_msg_iov_2_rma_iov(msg->rma_iov, msg->rma_iov_count, msg->msg_iov, msg->iov_count, rma_iovecs, &rma_count, from_split_map, to_split_map, remote_addr); assert(rma_count <= ND_MSG_INTERNAL_IOV_LIMIT); main_entry->wait_completion.comp_count = 0; main_entry->wait_completion.total_count = rma_count; InitializeCriticalSection(&main_entry->wait_completion.comp_lock); for (i = 0; i < rma_count; i++) { entries[i] = ofi_nd_buf_alloc_nd_cq_entry(); if (!entries[i]) goto fn_fail; memset(entries[i], 0, sizeof(*entries[i])); entries[i]->data = msg->data; entries[i]->flags = flags; entries[i]->domain = ep->domain; entries[i]->context = msg->context; entries[i]->seq = main_entry->seq; entries[i]->aux_entry = main_entry; ND2_SGE sge = { .Buffer = (void *)remote_addr[i], .BufferLength = (ULONG)rma_iovecs[i].len, .MemoryRegionToken = (UINT32)(uintptr_t)msg->desc[to_split_map[i]] }; hr = ep->qp->lpVtbl->Write(ep->qp, entries[i], &sge, 1, (UINT64)rma_iovecs[i].addr, (UINT32)rma_iovecs[i].key, 0); if (FAILED(hr)) goto fn_fail; } return FI_SUCCESS; } else { if (msg_len) { main_entry->inline_buf = __ofi_nd_buf_alloc_nd_inlinebuf(&ep->domain->inlinebuf); if (!main_entry->inline_buf) return -FI_ENOMEM; char *buf = (char*)main_entry->inline_buf->buffer; for (i = 0; i < msg->iov_count; i++) { memcpy(buf, msg->msg_iov[i].iov_base, msg->msg_iov[i].iov_len); buf += msg->msg_iov[i].iov_len; } } for (i = 0; i < msg->rma_iov_count; i++) { char *buf = (char *)main_entry->inline_buf->buffer; entries[i] = ofi_nd_buf_alloc_nd_cq_entry(); if (!entries[i]) goto fn_fail; memset(entries[i], 0, sizeof(*entries[i])); entries[i]->data = msg->data; entries[i]->flags = flags; entries[i]->domain = ep->domain; entries[i]->context = msg->context; entries[i]->seq = main_entry->seq; entries[i]->aux_entry = main_entry; ND2_SGE sge = { .Buffer = (void *)(buf + msg->rma_iov[i].len), .BufferLength = (ULONG)msg->rma_iov[i].len, .MemoryRegionToken = main_entry->inline_buf->token }; hr = ep->qp->lpVtbl->Write(ep->qp, entries[i], &sge, 1, (UINT64)msg->rma_iov[i].addr, (UINT32)msg->rma_iov[i].key, 0); if (FAILED(hr)) goto fn_fail; } return FI_SUCCESS; } fn_fail: while (i-- > 0) ofi_nd_free_cq_entry(entries[i]); ND_LOG_WARN(FI_LOG_EP_DATA, ofi_nd_strerror((DWORD)hr, NULL)); return H2F(hr); } static ssize_t ofi_nd_ep_inject(struct fid_ep *pep, const void *buf, size_t len, fi_addr_t dest_addr, uint64_t addr, uint64_t key) { struct iovec iov = { .iov_base = (void*)buf, .iov_len = len }; struct fi_rma_iov rma_iov = { .addr = addr, .len = len, .key = key }; struct fi_msg_rma msg = { .msg_iov = &iov, .desc = 0, .iov_count = 1, .addr = dest_addr, .rma_iov = &rma_iov, .rma_iov_count = 1, .context = 0, .data = 0 }; return ofi_nd_ep_writemsg(pep, &msg, FI_INJECT); } static ssize_t ofi_nd_ep_writedata(struct fid_ep *pep, const void *buf, size_t len, void *desc, uint64_t data, fi_addr_t dest_addr, uint64_t addr, uint64_t key, void *context) { struct iovec iov = { .iov_base = (void*)buf, .iov_len = len }; struct fi_rma_iov rma_iov = { .addr = addr, .len = len, .key = key }; struct fi_msg_rma msg = { .msg_iov = &iov, .desc = &desc, .iov_count = 1, .addr = dest_addr, .rma_iov = &rma_iov, .rma_iov_count = 1, .context = context, .data = data }; assert(pep->fid.fclass == FI_CLASS_EP); if (pep->fid.fclass != FI_CLASS_EP) return -FI_EINVAL; struct nd_ep *ep = container_of(pep, struct nd_ep, fid); return ofi_nd_ep_writemsg(pep, &msg, ep->info->tx_attr->op_flags | FI_REMOTE_CQ_DATA); } static ssize_t ofi_nd_ep_writeinjectdata(struct fid_ep *ep, const void *buf, size_t len, uint64_t data, fi_addr_t dest_addr, uint64_t addr, uint64_t key) { struct iovec iov = { .iov_base = (void*)buf, .iov_len = len }; struct fi_rma_iov rma_iov = { .addr = addr, .len = len, .key = key }; struct fi_msg_rma msg = { .msg_iov = &iov, .desc = 0, .iov_count = 1, .addr = dest_addr, .rma_iov = &rma_iov, .rma_iov_count = 1, .context = 0, .data = data }; return ofi_nd_ep_writemsg(ep, &msg, FI_INJECT | FI_REMOTE_CQ_DATA); } void ofi_nd_read_event(ND2_RESULT *result) { assert(result); assert(result->RequestType == Nd2RequestTypeRead); nd_cq_entry *entry = (nd_cq_entry*)result->RequestContext; assert(entry); ND_LOG_EVENT_INFO(entry); /* Check whether the operation is complex, i.e. read operation * may consists from several subtasks of read */ if (entry->aux_entry) { EnterCriticalSection(&entry->aux_entry->wait_completion.comp_lock); entry->aux_entry->wait_completion.comp_count++; ND_LOG_DEBUG(FI_LOG_EP_DATA, "READ Event comp_count = %d, total_count = %d\n", entry->aux_entry->wait_completion.comp_count, entry->aux_entry->wait_completion.total_count); if (entry->aux_entry->wait_completion.comp_count < entry->aux_entry->wait_completion.total_count) { /* Should wait some remaining completion events about read operation */ LeaveCriticalSection(&entry->aux_entry->wait_completion.comp_lock); entry->aux_entry = NULL; ofi_nd_free_cq_entry(entry); return; } LeaveCriticalSection(&entry->aux_entry->wait_completion.comp_lock); } /*TODO: Handle erroneous case "result->Status != S_OK" */ ofi_nd_dispatch_cq_event(entry->state == LARGE_MSG_RECV_REQ ? LARGE_MSG_REQ : NORMAL_EVENT, entry, result); } void ofi_nd_write_event(ND2_RESULT *result) { assert(result); assert(result->RequestType == Nd2RequestTypeWrite); nd_cq_entry *entry = (nd_cq_entry*)result->RequestContext; assert(entry); struct nd_ep *ep = (struct nd_ep*)result->QueuePairContext; assert(ep); assert(ep->fid.fid.fclass == FI_CLASS_EP); ND_LOG_EVENT_INFO(entry); /* Check whether the operation is complex, i.e. write operation * may consist from several subtasks of write */ if (entry->aux_entry) { EnterCriticalSection(&entry->aux_entry->wait_completion.comp_lock); entry->aux_entry->wait_completion.comp_count++; if (entry->aux_entry->wait_completion.comp_count < entry->aux_entry->wait_completion.total_count) { /* Should wait some remaining completion events about write operation */ LeaveCriticalSection(&entry->aux_entry->wait_completion.comp_lock); entry->aux_entry = NULL; ofi_nd_free_cq_entry(entry); return; } LeaveCriticalSection(&entry->aux_entry->wait_completion.comp_lock); } if (!entry->context) { /* This means that this write was an internal event, * just release it */ ofi_nd_free_cq_entry(entry); return; } if (entry->flags & FI_REMOTE_CQ_DATA) { if (ofi_nd_ep_injectdata( &ep->fid, 0, 0, entry->data, FI_ADDR_UNSPEC) != FI_SUCCESS) ND_LOG_WARN(FI_LOG_CQ, "failed to write-inject"); } if (ep->cntr_write) { if (result->Status != S_OK) { InterlockedIncrement64(&ep->cntr_write->err); } InterlockedIncrement64(&ep->cntr_write->counter); WakeByAddressAll((void*)&ep->cntr_write->counter); } int notify = ofi_nd_util_completion_blackmagic( ep->info->tx_attr->op_flags, ep->send_flags, entry->flags) || result->Status != S_OK; if (notify) { PostQueuedCompletionStatus( entry->result.Status == S_OK ? ep->cq_send->iocp : ep->cq_send->err, 0, 0, &entry->base.ov); InterlockedIncrement(&ep->cq_send->count); WakeByAddressAll((void*)&ep->cq_send->count); } else { /* if notification is not requested - just free entry */ ofi_nd_free_cq_entry(entry); } } void ofi_nd_split_msg_iov_2_rma_iov(const struct fi_rma_iov *rma_iovecs, const size_t rma_count, const struct iovec *msg_iovecs, const size_t msg_count, struct fi_rma_iov res_iovecs[ND_MSG_INTERNAL_IOV_LIMIT], size_t *res_count, size_t from_split_map[ND_MSG_INTERNAL_IOV_LIMIT], size_t to_split_map[ND_MSG_INTERNAL_IOV_LIMIT], uint64_t remote_addr[ND_MSG_INTERNAL_IOV_LIMIT]) { size_t i; struct iovec from_rma_iovecs[ND_MSG_IOV_LIMIT]; size_t from_rma_count = rma_count; struct iovec res_msg_iovecs[ND_MSG_IOV_LIMIT]; size_t res_msg_count = 0; /* Convert RMA iovecs to MSG iovecs to be able to reuse * them in @ofi_nd_repack_iovecs */ for (i = 0; i < rma_count; i++) { from_rma_iovecs[i].iov_base = (void *)rma_iovecs[i].addr; from_rma_iovecs[i].iov_len = rma_iovecs[i].len; } ofi_nd_repack_iovecs(from_rma_iovecs, from_rma_count, msg_iovecs, msg_count, res_msg_iovecs, &res_msg_count, from_split_map, to_split_map, remote_addr); /* Extract MSG iov to RMA iovecs and returns them */ for (i = 0; i < res_msg_count; i++) { res_iovecs[i].addr = remote_addr[i]; res_iovecs[i].len = res_msg_iovecs[i].iov_len; res_iovecs[i].key = rma_iovecs[from_split_map[i]].key; remote_addr[i] = (uint64_t)res_msg_iovecs[i].iov_base; } *res_count = res_msg_count; }
_ALWAYS_INLINE_ uint64_t _atomic_add_impl(register uint64_t *pw, register uint64_t val) { return InterlockedAdd64((LONGLONG volatile *)pw, val); }
WindowsAtomics::Int64 WindowsAtomics::AtomicAdd( AtomicInt64 &Destination, Int64 Val) { return InterlockedAdd64(&Destination, Val); }
static ssize_t ofi_nd_ep_sendmsg(struct fid_ep *pep, const struct fi_msg *msg, uint64_t flags) { assert(pep->fid.fclass == FI_CLASS_EP); assert(msg); if (pep->fid.fclass != FI_CLASS_EP) return -FI_EINVAL; HRESULT hr; size_t i; size_t len = 0; ssize_t res = FI_SUCCESS; struct nd_cq_entry *wait_ack_entry; nd_send_entry *send_entry; struct nd_ep *ep = container_of(pep, struct nd_ep, fid); if (!ep->qp) return -FI_EOPBADSTATE; for (i = 0; i < msg->iov_count; i++) { if (msg->msg_iov[i].iov_len && !msg->msg_iov[i].iov_base) return -FI_EINVAL; len += msg->msg_iov[i].iov_len; } if ((msg->iov_count > min(ep->domain->ainfo.MaxReceiveSge, ND_MSG_IOV_LIMIT) - 1) || (len > ep->domain->info->ep_attr->max_msg_size)) return -FI_EINVAL; struct nd_cq_entry *entry = ofi_nd_buf_alloc_nd_cq_entry(); if (!entry) return -FI_ENOMEM; memset(entry, 0, sizeof(*entry)); entry->buf = (msg->iov_count == 1) ? msg->msg_iov[0].iov_base : 0; entry->len = len; entry->data = msg->data; entry->flags = flags | FI_MSG | FI_SEND; entry->domain = ep->domain; entry->context = msg->context; entry->seq = InterlockedAdd64(&ep->domain->msg_cnt, 1); /* since send operation can't be canceled, set NULL into * the 1st byte of internal data of context */ if (msg->context) ND_FI_CONTEXT(msg->context) = 0; entry->prefix = __ofi_nd_buf_alloc_nd_msgprefix( &ep->domain->msgfooter); if (!entry->prefix) { res = -FI_ENOMEM; goto fn_fail_int; } if (entry->len <= (size_t)gl_data.inline_thr) { nd_flow_cntrl_flags flow_control_flags = { .req_ack = 0, .ack = 0, .empty = 0 }; struct nd_msgheader header_def = { .data = entry->data, .event = NORMAL_EVENT, .flags = flow_control_flags, .location_cnt = 0 }; entry->prefix->header = header_def; entry->event = NORMAL_EVENT; entry->flow_cntrl_flags = flow_control_flags; if (len) { entry->inline_buf = __ofi_nd_buf_alloc_nd_inlinebuf(&ep->domain->inlinebuf); if (!entry->inline_buf) { res = -FI_ENOMEM; goto fn_fail_int; } char *buf = (char*)entry->inline_buf->buffer; for (i = 0; i < msg->iov_count; i++) { memcpy(buf, msg->msg_iov[i].iov_base, msg->msg_iov[i].iov_len); buf += msg->msg_iov[i].iov_len; } } ND2_SGE sge[2] = { { .Buffer = &entry->prefix->header, .BufferLength = (ULONG)sizeof(entry->prefix->header), .MemoryRegionToken = entry->prefix->token }, { .Buffer = len ? entry->inline_buf->buffer : 0, .BufferLength = len, .MemoryRegionToken = len ? entry->inline_buf->token : 0 } }; nd_sge *sge_entry = ofi_nd_buf_alloc_nd_sge(); if (!sge_entry) { ND_LOG_WARN(FI_LOG_EP_DATA, "SGE entry buffer can't be allocated"); res = -FI_ENOMEM; goto fn_fail_int; } memset(sge_entry, 0, sizeof(*sge_entry)); sge_entry->count = len ? 2 : 1; for (i = 0; i < sge_entry->count; i++) sge_entry->entries[i] = sge[i]; nd_send_entry *send_entry = ofi_nd_buf_alloc_nd_send_entry(); if (!send_entry) { ND_LOG_WARN(FI_LOG_EP_DATA, "Send entry buffer can't be allocated"); res = -FI_ENOMEM; goto fn_fail_int; } memset(send_entry, 0, sizeof(*send_entry)); send_entry->cq_entry = entry; send_entry->sge = sge_entry; send_entry->ep = ep; /* Push the user's transmission request into * the Send Queue for furhter handling */ ofi_nd_queue_push(&ep->send_queue, &send_entry->queue_item); } else { if (flags & FI_INJECT)
/// @brief bool FileInfoCache::get_file_information( _In_ const wchar_t* file_path, _Out_ FileInformation& file_information ) { _ASSERTE(nullptr != file_path); if (nullptr == file_path) return false; // // 캐시 조회를 위한 기본 정보를 구한다. // WIN32_FILE_ATTRIBUTE_DATA fad; if (!GetFileAttributesExW(file_path, GetFileExInfoStandard, &fad)) { log_err "GetFileAttributesExW() failed. file=%ws, gle=%u", file_path, GetLastError() log_end; return false; } if (fad.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { log_warn "Not file. path=%ws", file_path log_end; return false; } uint64_t create_time = file_time_to_int(&fad.ftCreationTime); uint64_t write_time = file_time_to_int(&fad.ftLastWriteTime); uint64_t size = ((uint64_t)fad.nFileSizeHigh << 32) | fad.nFileSizeLow; // // 파일 사이즈가 0 이면 그냥 리턴 // if (size == 0) return true; // // 1st phase, 캐시에서 찾아본다. // std::string md5; std::string sha2; // 캐시 정보가 존재 한다면 캐시 정보를 반환한다. if (get_flie_info(file_path, create_time, write_time, size, md5, sha2)) { file_information.size = size; file_information.create_time = create_time; file_information.write_time = write_time; file_information.md5 = md5; file_information.sha2 = sha2; return true; } // // 2nd phase, 파일정보를 구하고, 캐시에 등록한다. // if (true != file_util_get_hash(file_path, md5, sha2)) { log_err "file_util_get_hash() failed. file=%ws", file_path log_end; return false; } // // 캐시에 등록 하기전 캐시 사이즈가 일정한 개수(기본값: 5000개, // 사용자가 cache_size를 변경 한 경우 달라 질 수 있다) 를 초과하는 경우 // table내의 "hit count"의 평균을 구한 후 평균 이하인 데이터들을 // 삭제한다. // if (_cache_size < _size) { int32_t delete_record_count = 0; try { delete_record_count = _delete_cache_stmt->execDML(); } catch (CppSQLite3Exception& e) { log_err "sqlite exception. get_file_information, code = %d, msg = %s", e.errorCode(), e.errorMessage() log_end; } // // 삭제된 레코드 수가 케시 사이즈보다 큰 경우 0으로 초기화 시킨다. // if (_size < delete_record_count) { _ASSERTE(!"oops, deleted record is larger than cache size"); InterlockedExchange64(&_size, 0); } // // 데이터 삭제 이후 현재 캐시 사이즈에서 삭제된 레코드 수 만큼 // 빼준다. // =====================참고=========================== // 현재 코드에서 기본 캐시 사이즈(5000개) 이상의 파일 정보가 // 캐싱이 되어 레코드가 삭제 되는 코드를 테스트 해보지 못해 // 다음과 같은 로깅코드를 남겨 두었으며 추후 삭제 할 수 있다. // =================================================== // InterlockedAdd64(&_size,-delete_record_count); log_dbg "delete file info cache record(count:%lu)", delete_record_count log_end; } if (true != insert_file_info(file_path, create_time, write_time, size, md5.c_str(), sha2.c_str())) { log_err "insert_file_info() failed. file=%ws", file_path log_end; return false; } // // 파일정보를 리턴한다. // file_information.size = size; file_information.create_time = create_time; file_information.write_time = write_time; file_information.md5 = md5; file_information.sha2 = sha2; log_dbg "File hash registered. file=%ws", file_path log_end; return true; }