/* FIXME */ static xcb_context_t xcb_context_init(void) { xcb_context_t c; if (NEW0(c) == NULL) return NULL; c->err = 0; c->errstr[0] = '\0'; c->inpos = 0; return c; }
Tree tree(int op, Type type, Tree left, Tree right) { Tree p; NEW0(p, where); p->op = op; p->type = type; p->kids[0] = left; p->kids[1] = right; return p; }
/* Note: for performance purposes, this function violates the bvt Abstraction. It may need to be changed if bvt changes. */ static ig_t i_igcreate (i_local_t k) { ig_t g; unsigned int i, w = bv_nwords(k)+bv_dx; NEW(g, 1); g->n = k; g->w = w; NEW0(g->d, k*w); for (i = 0; i < k; i++) /* Initialize bit vector metadata */ g->d[g->w*i] = k; return g; }
static void on_deep_market_data(struct CUstpFtdcDepthMarketDataField *deepmd) { Quote *quote; if (deepmd == NULL) { xcb_log(XCB_LOG_WARNING, "deepmd is NULL!"); return; } if (NEW0(quote)) { /* FIXME */ quote->thyquote.m_nLen = sizeof(tHYQuote); RMCHR(deepmd->UpdateTime, ':'); quote->thyquote.m_nTime = atoi(deepmd->UpdateTime) * 1000 + deepmd->UpdateMillisec; strcpy(quote->thyquote.m_cHYDM, deepmd->InstrumentID); quote->thyquote.m_dZJSJ = deepmd->PreSettlementPrice; quote->thyquote.m_dJJSJ = deepmd->SettlementPrice; quote->thyquote.m_dCJJJ = 0; quote->thyquote.m_dZSP = deepmd->PreClosePrice; quote->thyquote.m_dJSP = deepmd->ClosePrice; quote->thyquote.m_dJKP = deepmd->OpenPrice; quote->thyquote.m_nZCCL = deepmd->PreOpenInterest; quote->thyquote.m_nCCL = deepmd->OpenInterest; quote->thyquote.m_dZXJ = deepmd->LastPrice; quote->thyquote.m_nCJSL = deepmd->Volume; quote->thyquote.m_dCJJE = deepmd->Turnover; quote->thyquote.m_dZGBJ = deepmd->UpperLimitPrice; quote->thyquote.m_dZDBJ = deepmd->LowerLimitPrice; quote->thyquote.m_dZGJ = deepmd->HighestPrice; quote->thyquote.m_dZDJ = deepmd->LowestPrice; quote->thyquote.m_dZXSD = deepmd->PreDelta; quote->thyquote.m_dJXSD = deepmd->CurrDelta; quote->thyquote.m_dMRJG1 = deepmd->BidPrice1; quote->thyquote.m_dMCJG1 = deepmd->AskPrice1; quote->thyquote.m_nMRSL1 = deepmd->BidVolume1; quote->thyquote.m_nMCSL1 = deepmd->AskVolume1; quote->thyquote.m_dMRJG2 = deepmd->BidPrice2; quote->thyquote.m_dMCJG2 = deepmd->AskPrice2; quote->thyquote.m_nMRSL2 = deepmd->BidVolume2; quote->thyquote.m_nMCSL2 = deepmd->AskVolume2; quote->thyquote.m_dMRJG3 = deepmd->BidPrice3; quote->thyquote.m_dMCJG3 = deepmd->AskPrice3; quote->thyquote.m_nMRSL3 = deepmd->BidVolume3; quote->thyquote.m_nMCSL3 = deepmd->AskVolume3; quote->thyquote.m_dMRJG4 = deepmd->BidPrice4; quote->thyquote.m_dMCJG4 = deepmd->AskPrice4; quote->thyquote.m_nMRSL4 = deepmd->BidVolume4; quote->thyquote.m_nMCSL4 = deepmd->AskVolume4; quote->thyquote.m_dMRJG5 = deepmd->BidPrice5; quote->thyquote.m_dMCJG5 = deepmd->AskPrice5; quote->thyquote.m_nMRSL5 = deepmd->BidVolume5; quote->thyquote.m_nMCSL5 = deepmd->AskVolume5; process_quote(quote); } else xcb_log(XCB_LOG_WARNING, "Error allocating memory for quote"); }
static void on_best_and_deep(struct MDBestAndDeep *deepmd) { Quote *quote; if (deepmd == NULL) return; if (NEW0(quote)) { /* FIXME */ quote->thyquote.m_nLen = sizeof(tHYQuote); quote->thyquote.m_nTime = atoi(deepmd->GenTime); strcpy(quote->thyquote.m_cJYS, deepmd->Exchange); strcpy(quote->thyquote.m_cHYDM, deepmd->Contract); quote->thyquote.m_bTPBZ = deepmd->SuspensionSign; quote->thyquote.m_dZJSJ = deepmd->LastClearPrice; quote->thyquote.m_dJJSJ = deepmd->ClearPrice; quote->thyquote.m_dCJJJ = deepmd->AvgPrice; quote->thyquote.m_dZSP = deepmd->LastClose; quote->thyquote.m_dJSP = deepmd->Close; quote->thyquote.m_dJKP = deepmd->OpenPrice; quote->thyquote.m_nZCCL = deepmd->LastOpenInterest; quote->thyquote.m_nCCL = deepmd->OpenInterest; quote->thyquote.m_dZXJ = deepmd->LastPrice; quote->thyquote.m_nCJSL = deepmd->MatchTotQty; quote->thyquote.m_dCJJE = deepmd->Turnover; quote->thyquote.m_dZGBJ = deepmd->RiseLimit; quote->thyquote.m_dZDBJ = deepmd->FallLimit; quote->thyquote.m_dZGJ = deepmd->HighPrice; quote->thyquote.m_dZDJ = deepmd->LowPrice; quote->thyquote.m_dZXSD = deepmd->PreDelta; quote->thyquote.m_dJXSD = deepmd->CurrDelta; quote->thyquote.m_dMRJG1 = deepmd->BuyPriceOne; quote->thyquote.m_dMCJG1 = deepmd->SellPriceOne; quote->thyquote.m_nMRSL1 = deepmd->BuyQtyOne; quote->thyquote.m_nMCSL1 = deepmd->SellQtyOne; quote->thyquote.m_dMRJG2 = deepmd->BuyPriceTwo; quote->thyquote.m_dMCJG2 = deepmd->SellPriceTwo; quote->thyquote.m_nMRSL2 = deepmd->BuyQtyTwo; quote->thyquote.m_nMCSL2 = deepmd->SellQtyTwo; quote->thyquote.m_dMRJG3 = deepmd->BuyPriceThree; quote->thyquote.m_dMCJG3 = deepmd->SellPriceThree; quote->thyquote.m_nMRSL3 = deepmd->BuyQtyThree; quote->thyquote.m_nMCSL3 = deepmd->SellQtyThree; quote->thyquote.m_dMRJG4 = deepmd->BuyPriceFour; quote->thyquote.m_dMCJG4 = deepmd->SellPriceFour; quote->thyquote.m_nMRSL4 = deepmd->BuyQtyFour; quote->thyquote.m_nMCSL4 = deepmd->SellQtyFour; quote->thyquote.m_dMRJG5 = deepmd->BuyPriceFive; quote->thyquote.m_dMCJG5 = deepmd->SellPriceFive; quote->thyquote.m_nMRSL5 = deepmd->BuyQtyFive; quote->thyquote.m_nMCSL5 = deepmd->SellQtyFive; process_quote(quote); } else xcb_log(XCB_LOG_WARNING, "Error allocating memory for quote"); }
T Seq_new(int hint) { T seq; assert(hint >=0); NEW0(seq); if (hint == 0) hint = 16; //Elements in seq->array are pointers ArrayRep_init(&seq->array, hint, sizeof(void *), ALLOC(hint * sizeof(void *))); seq->head = 0; return seq; }
list_t list_create(void) { list_t self; NEW0(self); if (NULL != self) { self->node.prev = &self->node; self->node.next = &self->node; } return self; }
static Tree addrtree(Tree e, long n, Type ty) { Symbol p = e->u.sym, q; if (p->scope == GLOBAL || p->sclass == STATIC || p->sclass == EXTERN) NEW0(q, PERM); else NEW0(q, FUNC); q->name = stringd(genlabel(1)); q->sclass = p->sclass; q->scope = p->scope; assert(isptr(ty) || isarray(ty)); q->type = isptr(ty) ? ty->type : ty; q->temporary = p->temporary; q->generated = p->generated; q->addressed = p->addressed; q->computed = 1; q->defined = 1; q->ref = 1; assert(IR->address); if (p->scope == GLOBAL || p->sclass == STATIC || p->sclass == EXTERN) { if (p->sclass == AUTO) q->sclass = STATIC; (*IR->address)(q, p, n); } else { Code cp; addlocal(p); cp = code(Address); cp->u.addr.sym = q; cp->u.addr.base = p; cp->u.addr.offset = n; } e = tree(e->op, ty, NULL, NULL); e->u.sym = q; return e; }
static struct category *category_new(const char *name, const char *file, int lineno) { struct category *cat; if (NEW0(cat) == NULL) return NULL; if ((cat->file = mem_strdup(file)) == NULL) { FREE(cat); return NULL; } /* FIXME */ strncpy(cat->name, name, sizeof cat->name); cat->lineno = lineno; return cat; }
/*===----------------------------------------------------------------------- -----------------------------------------------------------------------===*/ void ast2icode(ast *t) { icode *ic1; /* we need know the stack size to be reserved for locals and register spills, when optput the asm file for IC_FUNC_BEGIN*/ _F.cur_func_end = gen_label("end"); NEW0(ic1, FUNC); ic1->node = IC_FUNC_BEGIN; _F.root_ic = _F.tail_ic = ic1; assert(t->node == AST_FUNC); //assert(t1->right->node == AST_BLOCK); /* local initializers should add after IC_FUNC_BEGIN immediately*/ izs2ic_local(); /* statement list*/ block2ic(t->right); // creat function end mark NEW0(ic1, FUNC); ic1->node = IC_FUNC_END; add2ic_list(ic1); /* free memory*/ zcc_free(AST); return; }
/*===-------------------------------------------------------------------------- after this itmp is means virtual register ---------------------------------------------------------------------------===*/ static symbol *gen_vit_reg(type *ty) { symbol *p; assert(ty); assert(is_scalar_cat(ty->cat)); /* do we need PERM ?*/ NEW0(p, FUNC); //p->name = gen_tmp_name("i"); p->is_itmp = 1; p->is_split = 1; //has no register p->ty = ty; if (ty->cat == CAT_FLOAT || ty->cat == CAT_DOUBLE) p->is_need_st = 1; return p; }
/* bb_alloc: return a new, empty basic block */ static inline i_bb_t bb_alloc (void) { i_bb_t b; num_bb++; NEW0(b, 1); if (num_i) { b->iv_def = bv_new(num_i); b->iv_use = bv_new(num_i); b->ilv_out = bv_new(num_i); } if (num_f) { b->fv_def = bv_new(num_f); b->fv_use = bv_new(num_f); b->flv_out = bv_new(num_f); } return b; }
rate_t *rate_new(int call_rate){ rate_t *r; NEW0(r); r->call_rate = call_rate; r->gtod_rate = call_rate / 10; r->sleep_rate = call_rate / 100; r->ts.tv_sec = 0; r->ts.tv_nsec = 4E6; if(r->gtod_rate == 0) r->gtod_rate = 1; if(r->sleep_rate == 0) r->sleep_rate = 1; gettimeofday(&r->tv[0], NULL); return r; }
/* 创建字符串链表 */ T strlist_new(const char *file) { FILE *fp = efopen(file, "r");; /*模式串文件*/ T strlist; NEW0(strlist); strlist->file = strdup(file); strlist->list = list_new(NULL); strlist->min_strlen = MAX_STR_LEN; uint64_t line_num = 0; char buf[MAX_STR_LEN+1]; /*模式串缓存,包括换行符*/ while (fgets(buf, sizeof(buf), fp)) { line_num++; char *line_break = strchr(buf, '\n'); /*换行符指针*/ if (line_break) *line_break = '\0'; Str_Len_T len = strlen(buf); if (len) { /*非空行*/ /* 插入链表末尾 */ list_push_back(strlist->list, strdup(buf)); if (len < strlist->min_strlen) strlist->min_strlen = len; else if (len > strlist->max_strlen) strlist->max_strlen = len; strlist->total_strlen += len; strlist->strlen_num[len]++; } } //printf("Total line: %ld\n", line_num); strlist->str_num = list_len(strlist->list); /*计算平均串长*/ strlist->avg_strlen = (double) strlist->total_strlen / strlist->str_num; /* 计算串长标准差 */ strlist->strlen_sd = cal_sd(strlist); efclose(fp); return strlist; }
/*===-------------------------------------------------------------------------- ---------------------------------------------------------------------------===*/ static icode *emit_ic(int node, symbol *l, symbol *r) { icode *ic; if (node != IC_MOV) assert(l->ty->cat == r->ty->cat); NEW0(ic, IC); ic->node = node; ic->left = l; ic->right = r; add2ic_list(ic); /* updata ues times*/ if (l) l->use_times++; if (r) r->use_times++; return ic; }
int fasthash_builder_new(FastHashBuilder **out_builder) { FastHashBuilder *fhb; int r; assert(out_builder); fhb = NEW0(FastHashBuilder); if (!fhb) return -ENOMEM; r = binary_tree_new(pointer_compare, &fhb->tree); if (r < 0) { free((void *)fhb); return r; } *out_builder = fhb; return 0; }
int fasthash_build(FastHashBuilder *builder, FastHash **out_hash) { FastHash *fh; int r; assert(builder); assert(out_hash); fh = NEW0(FastHash); if (!fh) return -ENOMEM; r = binary_tree_to_array(builder->tree, &fh->items, &fh->num_items); if (r < 0) { free((void *)fh); return r; } *out_hash = fh; return 0; }
int Thread_init(int preempt, ...) { assert(preempt == 0 || preempt == 1); assert(root == NULL); TRY NEW0(root); EXCEPT(Mem_Failed) return -1; END_TRY; join0 = CreateSemaphore(NULL, 0, 1, NULL); if (join0 == NULL) return -1; root->join = CreateSemaphore(NULL, 0, INT_MAX, NULL); if (root->join == NULL) { BOOL result = CloseHandle(join0); assert(result == TRUE); return -1; } InitializeCriticalSection(&csection); root->IDThread = GetCurrentThreadId(); addThread(root); /* handle preempt == 0 */ return 1; }
static void on_deep_market_data(struct DFITCDepthMarketDataField *deepmd) { Quote *quote; if (deepmd == NULL) return; if (NEW0(quote)) { /* FIXME */ quote->thyquote.m_nLen = sizeof (tHYQuote); RMCHR(deepmd->UpdateTime, ':'); quote->thyquote.m_nTime = atoi(deepmd->UpdateTime) * 1000 + deepmd->UpdateMillisec; strcpy(quote->thyquote.m_cJYS, deepmd->exchangeID); strcpy(quote->thyquote.m_cHYDM, deepmd->instrumentID); quote->thyquote.m_dZJSJ = deepmd->preSettlementPrice; quote->thyquote.m_dJJSJ = deepmd->settlementPrice; quote->thyquote.m_dCJJJ = deepmd->AveragePrice; quote->thyquote.m_dZSP = deepmd->preClosePrice; quote->thyquote.m_dJSP = deepmd->closePrice; quote->thyquote.m_dJKP = deepmd->openPrice; quote->thyquote.m_nZCCL = deepmd->preOpenInterest; quote->thyquote.m_nCCL = deepmd->openInterest; quote->thyquote.m_dZXJ = deepmd->lastPrice; quote->thyquote.m_nCJSL = deepmd->Volume; quote->thyquote.m_dCJJE = deepmd->turnover; quote->thyquote.m_dZGBJ = deepmd->upperLimitPrice; quote->thyquote.m_dZDBJ = deepmd->lowerLimitPrice; quote->thyquote.m_dZGJ = deepmd->highestPrice; quote->thyquote.m_dZDJ = deepmd->lowestPrice; quote->thyquote.m_dZXSD = deepmd->preDelta; quote->thyquote.m_dJXSD = deepmd->currDelta; quote->thyquote.m_dMRJG1 = deepmd->BidPrice1; quote->thyquote.m_dMCJG1 = deepmd->AskPrice1; quote->thyquote.m_nMRSL1 = deepmd->BidVolume1; quote->thyquote.m_nMCSL1 = deepmd->AskVolume1; process_quote(quote); } else xcb_log(XCB_LOG_WARNING, "Error allocating memory for quote"); }
T* Shash_new(int len, int size) { T *hash; assert(len > 0); assert(size > 0); if (IS_POW_OF_TWO(len)) { if ((unsigned)len > 0x80000000) return NULL; len = roundup_pow_of_two(len); } if (!NEW0(hash)) return NULL; if (!ALLOC(hash->buckets, len * sizeof(BUCKET_T))) { FREE(hash); return NULL; } memset(hash->buckets, 0, len * sizeof(BUCKET_T)); hash->len = len; hash->size = size; hash->cur_index = 0; hash->cur_node = NULL; return hash; }
void LoweringVisitor::perform_partial_reduction_slicer(OutlineInfo& outline_info, Nodecl::NodeclBase ref_tree, Nodecl::Utils::SimpleSymbolMap*& symbol_map) { ERROR_CONDITION(ref_tree.is_null(), "Invalid tree", 0); TL::ObjectList<OutlineDataItem*> reduction_items = outline_info.get_data_items().filter( lift_pointer<bool, OutlineDataItem>(&OutlineDataItem::is_reduction)); if (!reduction_items.empty()) { TL::ObjectList<Nodecl::NodeclBase> reduction_stmts; Nodecl::Utils::SimpleSymbolMap* simple_symbol_map = new Nodecl::Utils::SimpleSymbolMap(symbol_map); symbol_map = simple_symbol_map; for (TL::ObjectList<OutlineDataItem*>::iterator it = reduction_items.begin(); it != reduction_items.end(); it++) { scope_entry_t* shared_symbol = (*it)->get_symbol().get_internal_symbol(); // We need this to avoid the original symbol be replaced // incorrectly scope_entry_t* shared_symbol_proxy = NEW0(scope_entry_t); shared_symbol_proxy->symbol_name = UNIQUESTR_LITERAL("<<reduction-variable>>"); // Crude way to ensure it is replaced shared_symbol_proxy->kind = shared_symbol->kind; symbol_entity_specs_copy_from(shared_symbol_proxy, shared_symbol); shared_symbol_proxy->decl_context = shared_symbol->decl_context; shared_symbol_proxy->type_information = shared_symbol->type_information; shared_symbol_proxy->locus = shared_symbol->locus; simple_symbol_map->add_map( shared_symbol_proxy, (*it)->reduction_get_shared_symbol_in_outline() ); Source reduction_code; Nodecl::NodeclBase partial_reduction_code; reduction_code << "{" << "nanos_lock_t* red_lock;" << "nanos_err_t nanos_err;" << "nanos_err = nanos_get_lock_address(" << ((*it)->get_private_type().is_array() ? "" : "&") << as_symbol( shared_symbol_proxy ) << ", &red_lock);" << "if (nanos_err != NANOS_OK) nanos_handle_error(nanos_err);" << "nanos_err = nanos_set_lock(red_lock);" << "if (nanos_err != NANOS_OK) nanos_handle_error(nanos_err);" << statement_placeholder(partial_reduction_code) << "nanos_err = nanos_unset_lock(red_lock);" << "if (nanos_err != NANOS_OK) nanos_handle_error(nanos_err);" << "}" ; FORTRAN_LANGUAGE() { Source::source_language = SourceLanguage::C; } Nodecl::NodeclBase statement = reduction_code.parse_statement(ref_tree); FORTRAN_LANGUAGE() { Source::source_language = SourceLanguage::Current; } ERROR_CONDITION(!statement.is<Nodecl::List>(), "Expecting a list", 0); reduction_stmts.append(statement.as<Nodecl::List>()[0]); TL::Type elemental_type = (*it)->get_private_type(); while (elemental_type.is_array()) elemental_type = elemental_type.array_element(); Source partial_reduction_code_src; if (IS_C_LANGUAGE || IS_CXX_LANGUAGE) { partial_reduction_code_src << as_symbol( (*it)->reduction_get_basic_function() ) << "(" // This will be the reduction shared << ((*it)->get_private_type().is_array() ? "" : "&") << as_symbol( shared_symbol_proxy ) << ", " // This will be the reduction private var << ((*it)->get_private_type().is_array() ? "" : "&") << as_symbol( (*it)->get_symbol() ) << ", " << ((*it)->get_private_type().is_array() ? ( "sizeof(" + as_type( (*it)->get_private_type()) + ")" "/ sizeof(" + as_type(elemental_type) + ")" ) : "1") << ");" ; } else if (IS_FORTRAN_LANGUAGE) { // We use an ELEMENTAL call here partial_reduction_code_src << "CALL " << as_symbol ( (*it)->reduction_get_basic_function() ) << "(" // This will be the reduction shared << as_symbol( shared_symbol_proxy ) << ", " // This will be the reduction private var << as_symbol( (*it)->get_symbol() ) << ")" ; } else { internal_error("Code unreachable", 0); } partial_reduction_code.replace( partial_reduction_code_src.parse_statement(partial_reduction_code)); } ref_tree.replace( Nodecl::CompoundStatement::make( Nodecl::List::make(reduction_stmts), Nodecl::NodeclBase::null() ) ); }
void i_fg_build (void) { unsigned i; i_puint32 cp = i_buf; /* Start of code to analyze */ i_puint32 lp = i_lim; /* End of code to analyze */ i_uint32 op; /* Current opcode */ i_bb_t b; /* Current basic block */ num_bb = 0; b = bb_alloc(); b->h = cp; if (i_ralloctype == RA_EZ) { i_fg_root = i_fg_tail = b; b->t = lp - i_isize; return; } i_calls_cur = i_calls_lim = 0; NEW0(lbl2bb, i_lab_cur); NEW(fwdrefs, i_nbb); fwdref_cur = 0; i_fg_root = b; do { assert(b && !b->init); op = get_op(cp); switch(i_op2class[op]) { case I_BOP: case I_BOPF: case I_MOPR: case I_MOPRF: assert(!isimmed(op)); markuse(b, get_rs(cp)); markuse(b, get_rs2(cp)); markdef(b, get_rd(cp)); break; case I_BOPI: case I_MOPRI: case I_MOPRIF: assert(isimmed(op)); markuse(b, get_rs(cp)); markdef(b, get_rd(cp)); break; case I_MOPW: case I_MOPWF: assert(!isimmed(op)); markuse(b, get_rd(cp)); markuse(b, get_rs(cp)); markuse(b, get_rs2(cp)); break; case I_MOPWI: case I_MOPWIF: assert(isimmed(op)); markuse(b, get_rd(cp)); markuse(b, get_rs(cp)); break; case I_UOP: case I_UOPF: assert(!isimmed(op)); markuse(b, get_rs(cp)); markdef(b, get_rd(cp)); break; case I_UOPI: assert(isimmed(op)); markdef(b, get_rd(cp)); break; case I_SET: case I_SETF: markdef(b, get_rd(cp)); break; case I_LEA: case I_LEAF: SCLASS(get_rs(cp)) = STACK; markuse(b, get_rs(cp)); markdef(b, get_rd(cp)); break; case I_RET: case I_RETF: if (op != i_op_retv) markuse(b, get_rd(cp)); case I_RETI: b = bb_finalize(b, cp, lp, i_isize, false); break; case I_BR: case I_BRF: markuse(b, get_rs2(cp)); case I_BRI: markuse(b, get_rs(cp)); bb_linklbl(b, get_rd(cp)); b = bb_finalize(b, cp, lp, i_isize, true); break; case I_CALL: case I_CALLF: markuse(b, get_rs(cp)); case I_CALLI: case I_CALLIF: if (op != i_op_callv && op != i_op_callvi) markdef(b, get_rd(cp)); markcall(cp); b = bb_finalize(b, cp, lp, 2*i_isize, true); cp += i_isize; /* Calls are 2x as long as other insns */ break; case I_ARG: case I_ARGF: markuse(b, get_rd(cp)); break; case I_JMP: assert(get_rd(cp) < num_i); markuse(b, get_rd(cp)); b = bb_finalize(b, cp, lp, i_isize, false); break; case I_JMPI: bb_linklbl(b, get_imm(cp)); b = bb_finalize(b, cp, lp, i_isize, false); break; case I_MISC: switch (op) { case i_op_lbl: if (cp > b->h) /* If not at head of current block ... */ /* ... make this the head of a new block */ b = bb_finalize(b, cp-i_isize, lp, i_isize, true); lbl2bb[get_rd(cp)] = b; break; default: /* refmul, refdiv, self, nop */ break; } break; default: assert(0); } } while ((cp += i_isize) < lp); i_fg_tail = b; for (i = 0; i < fwdref_cur; i++) bb_linkbb(fwdrefs[i].src, lbl2bb[fwdrefs[i].dst]); #ifndef NDEBUG for (i = 0, b = i_fg_root; b; b = b->lnext) i++; assert(i == num_bb); #endif }
/* Opens an HDF file and reads all its SDS metadata, returning an SDSInfo * structure containing this metadata. Returns NULL on error. */ SDSInfo *open_h4_sds(const char *path) { int i, status; int sd_id = SDstart(path, DFACC_READ); CHECK_HDF_ERROR(path, sd_id); // get dataset and global att counts int32 n_datasets, n_global_atts; status = SDfileinfo(sd_id, &n_datasets, &n_global_atts); CHECK_HDF_ERROR(path, status); SDSInfo *sds = NEW0(SDSInfo); sds->path = xstrdup(path); sds->type = SDS_HDF4_FILE; sds->id = sd_id; // read global attributes sds->gatts = read_attributes(path, sd_id, n_global_atts); // read variables ('datasets') for (i = 0; i < n_datasets; i++) { int sds_id = SDselect(sd_id, i); CHECK_HDF_ERROR(path, sds_id); char buf[_H4_MAX_SDS_NAME + 1]; memset(buf, 0, sizeof(buf)); int32 rank, dim_sizes[H4_MAX_VAR_DIMS], type, natts; status = SDgetinfo(sds_id, buf, &rank, dim_sizes, &type, &natts); CHECK_HDF_ERROR(path, status); SDSVarInfo *var = NEW0(SDSVarInfo); var->name = xstrdup(buf); var->type = h4_to_sdstype(type); var->iscoord = SDiscoordvar(sds_id); var->ndims = rank; var->dims = read_dimensions(sds, sds_id, rank, dim_sizes); var->atts = read_attributes(path, sds_id, natts); var->id = i; // actually the sds_index comp_coder_t comp_type; comp_info c_info; status = SDgetcompinfo(sds_id, &comp_type, &c_info); CHECK_HDF_ERROR(path, status); switch (comp_type) { case COMP_CODE_NONE: var->compress = 0; break; case COMP_CODE_DEFLATE: var->compress = c_info.deflate.level; break; default: // any other compression method is 'worth' 1 imo *trollface* // better than claiming 0 to the user var->compress = 1; break; } var->sds = sds; var->next = sds->vars; sds->vars = var; status = SDendaccess(sds_id); CHECK_HDF_ERROR(path, status); } sds->vars = (SDSVarInfo *)list_reverse((List *)sds->vars); sds->dims = (SDSDimInfo *)list_reverse((List *)sds->dims); sds->funcs = &h4_funcs; return sds; }
void i_li_full (void) { bvt iskip=0, fskip=0; /* Variables live at both start & end of bb */ bvt ilv=0, flv=0; /* Live variables at each step */ i_bb_t b; /* Temp bblock */ i_puint32 cp; /* Code pointer */ i_cnt_t pos = max_cnt; /* Absolute layout-order position */ unsigned int op; /* Current opcode */ /* Allocate live ranges */ if (num_i) NEW0(i_ilrs, num_i); if (num_f) NEW0(i_flrs, num_f); i_ilr_cur = num_i-1; i_flr_cur = num_f-1; /* Now calculate the live ranges */ for (b = i_fg_tail; b; pos--, b = b->lprev) { tpos = pos; hpos = pos - (b->t - b->h)/i_isize; /* Compute skip set */ if (num_i) { iskip = bv_rinter(b->ilv_out, b->ilv_in); ilv = bv_rdiff(b->ilv_out, iskip); bv_eachbit(iskip, lriskip, b); } if (num_f) { fskip = bv_rinter(b->flv_out, b->flv_in); flv = bv_rdiff(b->flv_out, fskip); bv_eachbit(fskip, lrfskip, b); } assert(b && b->t >= b->h); for (cp = b->t; cp >= b->h; pos--, cp -= i_isize) { op = get_op(cp); switch(i_op2class[op]) { case I_MOPW: case I_MOPWF: USE(get_rs2(cp)); /* Fall through */ case I_MOPWI: case I_MOPWIF: USE(get_rd(cp)); USE(get_rs(cp)); break; case I_MOPR: case I_BOP: case I_MOPRF: case I_BOPF: case I_MOPRI: case I_BOPI: case I_MOPRIF: DEF(get_rd(cp)); /* Fall through */ case I_BR: case I_BRI: case I_BRF: USE(get_rs(cp)); if (!isimmed(op)) USE(get_rs2(cp)); break; case I_UOP: case I_UOPI: case I_UOPF: DEF(get_rd(cp)); if (!isimmed(op)) USE(get_rs(cp)); break; case I_SET: case I_SETF: DEF(get_rd(cp)); break; case I_LEA: case I_LEAF: DEF(get_rd(cp)); USE(get_rs(cp)); break; case I_ARG: case I_ARGF: case I_RETF: case I_JMP: USE(get_rd(cp)); break; case I_RET: if (op != i_op_retv) USE(get_rd(cp)); break; case I_CALL: case I_CALLF: case I_CALLI: case I_CALLIF: if (op != i_op_callv && op != i_op_callvi) DEFKP(get_rd(cp)); /* Add use of callee if not immediate; it is in an int register, so treat it like an int */ if (!isimmed(op)) USE(get_rs(cp)); /* Set info for caller-saved registers */ if (num_i) icallsav(cp, bv_runion(ilv, iskip)); if (num_f) fcallsav(cp, bv_runion(flv, fskip)); break; case I_MISC: case I_JMPI: case I_RETI: continue; default: assert(0); } } assert(pos+1 == hpos); if (num_i) bv_eachbit(ilv, lriuseiter, (void *)hpos); if (num_f) bv_eachbit(flv, lrfuseiter, (void *)hpos); } DEBUG(i_li_unparse()); }
/* i_ig_color: color the interference graph g for storage class (INT/FP) sc */ void i_ig_color (int sc) { ig_t g, g2; /* Backup of interference graph */ i_local_t *nstk; /* Node stack: when removing a node from IG, push it onto this stack */ unsigned int ncnt = 0; /* Counter for node stack */ unsigned int nnodes; /* No. of nodes left in IG when coloring */ unsigned int nremoved; /* No. of nodes removed in 1 coloring pass */ i_local_t i, j; /* Dummy variable indices / counters */ unsigned int k; unsigned int reg; /* Temporary color variable */ unsigned int ncolors; /* Number of available registers */ /* Data for prioritized spilling */ i_ref_t threshref = 0.; /* Threshold refcnt (see below) */ i_local_t *deferspill = 0; /* Maintains info of which spills have been deferred */ i_local_t Vnum, Vbase; /* Number of vars of sclass sc, and their base offset in i_locals */ #ifndef NDEBUG int dcnt = 0; #endif if (sc == FP) { g = fig; Vnum = num_f; Vbase = i_loc_ilim; } else { g = iig; Vnum = num_i; Vbase = 0; } ncolors = i_reg_navail(sc);/* Find number of available registers */ NEW(nstk, Vnum); /* Allocate register stack */ g2 = i_igcopy(g); /* Make backup copy of IG */ NEW0(removed, Vnum); /* Mark whether a node has been removed */ DEBUG(i_igunparse(g)); if (i_dorefcnt) { /* Find maxref */ i_ref_t t = 0.; unsigned n = 0; NEW0(deferspill, Vnum); for (i = 0; i < Vnum; i++) { j = i + Vbase; /* Get real index of this variable */ if (! (PARAMP(j) || SCLASS(j) == STACK)) { t += REFCNT(j); n++; } } threshref = t/(n*2); /* For any clique (V,E) where |V| > # regs, spill first all v with refcnt < threshref; this is a little bogus (the right way would be to sort the v \in V and spill in order of increasing refcnt), but fast, and it works pretty well. */ } /* * Dismantle interference graph */ do { nremoved = 0; /* Reset number of nodes removed */ nnodes = 0; /* And number of nodes remaining */ /* Loop over all variables (ie. nodes in IG) */ for (i = 0; i < Vnum; i++) { if (removed[i]) continue; j = i + Vbase; /* Skip params: already allocated */ if (PARAMP(j)) { i_igremove(i, g); continue; } /* Remove non-register candidates */ if (SCLASS(j) == STACK) { i_igspill(j, i, g); continue; } /* Find valence of node i */ k = bv_num(row(i, g)); if (k == 0) { removed[i] = 1; continue; } if (k <= ncolors) { /* Valence <= number of colors: can color. Store index of node i for later use */ push(i, nstk, ncnt); /* Remove node i from graph */ i_igremove(i, g); ++nremoved; /* Increase the counter of removed nodes */ } else ++nnodes; /* Can't color: increase number of nodes left in graph */ } } while (nnodes > 0 && nremoved > 0); while (nnodes > 0) { /* Try nodes with high valence/low refcount */ i_local_t target = i_zero; unsigned int mc = 0; #ifndef NDEBUG if (i_debug) { printf("Initial spill loop, #%d (nnodes=%d,dorefcnt=%d)\n", dcnt++, nnodes, i_dorefcnt); } #endif for (i = 0; i < Vnum; i++) { if (removed[i]) continue; j = i + Vbase; /* Find valence of node i */ k = bv_num(row(i, g)); assert(k); if (k <= ncolors) { /* Can color: evidently we removed some of this node's neighbors on a previous iteration of this inner loop */ /* Store index of node i for later use */ push(i, nstk, ncnt); /* Remove node i from graph */ i_igremove(i, g); --nnodes; /* We have removed a node */ if (!nnodes) break; } else if (REFCNT(j) < 2*threshref && k > mc) { mc = k; target = i; } } if (nnodes) if (target != i_zero) { DEBUG(printf("Spilling(1) %d[n=%d,d=%d,k=%d,c=%f,t=%f]\n",\ target, nnodes, deferspill[target], mc, \ REFCNT(target+Vbase), threshref)); i_igspill(target+Vbase, target, g); DEBUG(i_igunparse(g)); nnodes--; } else { /* Found nothing to spill here */ assert(target == i_zero); break; } } DEBUG(dcnt = 0); while (nnodes > 0) { /* Final, aggressive spill loop */ #ifndef NDEBUG if (i_debug) { printf("Final spill loop, #%d (nnodes=%d)\n", dcnt++, nnodes); } #endif for (i = 0; i < Vnum; i++) { if (removed[i]) continue; j = i + Vbase; /* Find valence of node i */ k = bv_num(row(i, g)); assert(k); if (k <= ncolors) { /* Can color: evidently we removed some of this node's neighbors on a previous iteration of this inner loop */ /* Store index of node i for later use */ push(i, nstk, ncnt); /* Remove node i from graph */ i_igremove(i, g); } else if (!i_dorefcnt || deferspill[i] > 1 || REFCNT(j) < 3*threshref) { /* Small refcnt or already deferred: spill. */ DEBUG(printf("Spilling(2) %d[n=%d,d=%d,k=%d,c=%f,t=%f]\n",\ i, nnodes, deferspill[i], k, \ REFCNT(j), threshref)); i_igspill(j, i, g); DEBUG(i_igunparse(g)); } else { /* This node is referenced a lot; try deferring the spill. */ ++deferspill[i]; continue; /* Do not remove this node, yet */ } --nnodes; /* We have removed a node */ } } /* * Rebuild interference graph, coloring nodes */ while (ncnt) { /* Find a new node to add back to the IG */ pop(i, nstk, ncnt); /* Make unavailable the registers of all nodes adjacent to node i in the IG */ bv_eachbit(row(i, g2), i_rmreg, (void *)Vbase); reg = i_reg_get(sc); /* Get an int register */ j = i + Vbase; ADDR(j) = reg; SCLASS(j) = REGISTER; /* Set storage location info */ i_reg_mask(sc); /* Reset the set of available registers */ } i_reg_resetmask(sc); }
static void read_quote(event_loop el, int fd, int mask, void *data) { char *buf; struct sockaddr_in si; socklen_t slen = sizeof si; int nread; NOT_USED(el); NOT_USED(mask); NOT_USED(data); if ((buf = CALLOC(1, sizeof (Quote))) == NULL) return; /* FIXME */ if ((nread = recvfrom(fd, buf, sizeof (Quote), 0, (struct sockaddr *)&si, &slen)) > 0) { Quote *quote; struct msg *msg; quote = (Quote *)buf; if (quote->thyquote.m_nLen == sizeof (THYQuote)) { int tlen; quote->thyquote.m_cJYS[sizeof quote->thyquote.m_cJYS - 1] = '\0'; quote->thyquote.m_cHYDM[sizeof quote->thyquote.m_cHYDM - 1] = '\0'; quote->m_nMSec = 0; /* for testing */ dlist_rwlock_rdlock(monitors); if (dlist_length(monitors) > 0) { char res[512]; dlist_iter_t iter = dlist_iter_new(monitors, DLIST_START_HEAD); dlist_node_t node; snprintf(res, sizeof res, "RX '%d,%s,%s,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f," "%.2f,%.2f,%d,%.2f,%d,%d,%.2f,%d,%.2f,%d'\r\n", quote->thyquote.m_nTime, quote->thyquote.m_cHYDM, quote->thyquote.m_cJYS, quote->thyquote.m_dZXJ, quote->thyquote.m_dJKP, quote->thyquote.m_dZGJ, quote->thyquote.m_dZDJ, quote->thyquote.m_dZSP, quote->thyquote.m_dJSP, quote->thyquote.m_dZJSJ, quote->thyquote.m_dJJSJ, quote->thyquote.m_nCJSL, quote->thyquote.m_dCJJE, quote->thyquote.m_nZCCL, quote->thyquote.m_nCCL, quote->thyquote.m_dMRJG1, quote->thyquote.m_nMRSL1, quote->thyquote.m_dMCJG1, quote->thyquote.m_nMCSL1); while ((node = dlist_next(iter))) { client c = (client)dlist_node_value(node); pthread_spin_lock(&c->lock); if (c->flags & CLIENT_CLOSE_ASAP) { pthread_spin_unlock(&c->lock); continue; } if (net_try_write(c->fd, res, strlen(res), 10, NET_NONBLOCK) == -1) { xcb_log(XCB_LOG_WARNING, "Writing to client '%p': %s", c, strerror(errno)); if (++c->eagcount >= 10) client_free_async(c); } else if (c->eagcount) c->eagcount = 0; pthread_spin_unlock(&c->lock); } dlist_iter_free(&iter); } dlist_rwlock_unlock(monitors); /* FIXME */ if (quote->thyquote.m_nTime == 999999999) { FREE(buf); return; } else if ((tlen = intlen(quote->thyquote.m_nTime)) < 10) { struct timeval tv; struct tm lt; gettimeofday(&tv, NULL); localtime_r(&tv.tv_sec, <); if (quote->thyquote.m_cHYDM[0] == 'S' && quote->thyquote.m_cHYDM[1] == 'P') quote->thyquote.m_nTime *= 1000; else if (tlen == 6 || tlen == 7) quote->thyquote.m_nTime *= 100; lt.tm_hour = quote->thyquote.m_nTime / 10000000; lt.tm_min = quote->thyquote.m_nTime % 10000000 / 100000; lt.tm_sec = quote->thyquote.m_nTime % 100000 / 1000; quote->m_nMSec = quote->thyquote.m_nTime % 1000; quote->thyquote.m_nTime = mktime(<); } /* FIXME */ if (addms) { struct timeval tv; dstr contract = dstr_new(quote->thyquote.m_cHYDM); struct sms *sms; gettimeofday(&tv, NULL); if ((sms = table_get_value(times, contract)) == NULL) { if (NEW(sms)) { sms->qsec = quote->thyquote.m_nTime; sms->sec = tv.tv_sec; sms->msec = tv.tv_usec / 1000; table_insert(times, contract, sms); } } else if (sms->qsec != quote->thyquote.m_nTime) { sms->qsec = quote->thyquote.m_nTime; sms->sec = tv.tv_sec; sms->msec = tv.tv_usec / 1000; dstr_free(contract); } else { int32_t offset; if ((offset = (tv.tv_sec - sms->sec) * 1000 + tv.tv_usec / 1000 - sms->msec) > 999) offset = 999; quote->m_nMSec = offset; dstr_free(contract); } } } if (NEW0(msg) == NULL) { FREE(buf); return; } msg->data = buf; msg->refcount = 1; thrpool_queue(tp, send_quote, msg, NULL, msgfree, NULL); } else FREE(buf); }
T Ring_new(void) { T ring; NEW0(ring); ring->head = NULL; return ring; }
void test_array(void) { int i; double* d; void* A = array_create(0); fprintf(stdout, "call function : %s\n", __func__); array_object_show(A); fprintf(stdout, "\ntest function - array_push_back ===>\n"); { srand((unsigned int)time(0)); for (i = 0; i < 5; ++i) { NEW0(d); *d = (i + 1) * (i + 1) * rand() % 5555 * 0.123; fprintf(stdout, "\tappend into array {object=>0x%p, value=>%.3f}\n", d, *d); array_push_back(A, d); } array_object_show(A); array_for_each(A, array_element_display, NULL); array_for_each(A, array_element_destroy, NULL); array_object_show(A); array_clear(A); } array_object_show(A); fprintf(stdout, "\ntest function - array_pop_back ===>\n"); { srand((unsigned int)time(0)); for (i = 0; i < 5; ++i) { NEW0(d); *d = (i + 1) * (i + 1) * rand() % 5555 * 0.123; fprintf(stdout, "\tappend into array {object=>0x%p, value=>%.3f}\n", d, *d); array_push_back(A, d); } array_object_show(A); array_for_each(A, array_element_display, NULL); d = (double*)array_pop_back(A); fprintf(stdout, " the pop element {object=>0x%p,value=>%.3f}\n", d, *d); FREE(d); array_object_show(A); array_for_each(A, array_element_display, NULL); array_for_each(A, array_element_destroy, NULL); array_object_show(A); array_clear(A); } array_object_show(A); fprintf(stdout, "\ntest function - array_erase ===>\n"); { srand((unsigned int)time(0)); for (i = 0; i < 5; ++i) { NEW0(d); *d = (i + 1) * (i + 1) * rand() % 5555 * 0.123; fprintf(stdout, "\tappend into array {object=>0x%p, value=>%.3f}\n", d, *d); array_push_back(A, d); } array_object_show(A); array_for_each(A, array_element_display, NULL); d = (double*)array_erase(A, array_begin(A)); fprintf(stdout, " the erased begin element {object=>0x%p,value=>%.3f}\n", d, *d); FREE(d); array_object_show(A); array_for_each(A, array_element_display, NULL); d = (double*)array_erase(A, array_end(A)); fprintf(stdout, " the erased end element {object=>0x%p,value=>%.3f}\n", d, *d); FREE(d); array_object_show(A); array_for_each(A, array_element_display, NULL); array_for_each(A, array_element_destroy, NULL); array_object_show(A); array_clear(A); } array_object_show(A); fprintf(stdout, "\ntest function - array_remove ===>\n"); { srand((unsigned int)time(0)); for (i = 0; i < 5; ++i) { NEW0(d); *d = (i + 1) * (i + 1) * rand() % 5555 * 0.123; fprintf(stdout, "\tappend into array {object=>0x%p, value=>%.3f}\n", d, *d); array_push_back(A, d); } array_object_show(A); array_for_each(A, array_element_display, NULL); d = (double*)array_remove(A, 3); fprintf(stdout, " the removed [3] -> {object=>0x%p,value=>%.3f}\n", d, *d); FREE(d); array_object_show(A); array_for_each(A, array_element_display, NULL); array_for_each(A, array_element_destroy, NULL); array_object_show(A); array_clear(A); } array_object_show(A); fprintf(stdout, "\ntest function - array_copy ===>\n"); { void* copy_A; srand((unsigned int)time(0)); for (i = 0; i < 5; ++i) { NEW0(d); *d = (i + 1) * (i + 1) * rand() % 5555 * 0.123; fprintf(stdout, "\tappend into array {object=>0x%p, value=>%.3f}\n", d, *d); array_push_back(A, d); } array_object_show(A); array_for_each(A, array_element_display, NULL); copy_A = array_copy(A, 10); array_object_show(copy_A); array_for_each(copy_A, array_element_display, NULL); array_release(©_A); array_for_each(A, array_element_destroy, NULL); array_clear(A); } array_object_show(A); fprintf(stdout, "\ntest function - array_resize ===>\n"); { srand((unsigned int)time(0)); for (i = 0; i < 5; ++i) { NEW0(d); *d = (i + 1) * (i + 1) * rand() % 5555 * 0.123; fprintf(stdout, "\tappend into array {object=>0x%p, value=>%.3f}\n", d, *d); array_push_back(A, d); } array_object_show(A); array_for_each(A, array_element_display, NULL); array_resize(A, 20); array_object_show(A); array_for_each(A, array_element_display, NULL); array_for_each(A, array_element_destroy, NULL); array_clear(A); } array_object_show(A); fprintf(stdout, "\ntest function - array_release ===>\n"); array_release(&A); array_object_show(A); }
static void *uid2type(int uid) { assert(uid >= 0 && uid < nuids); if (itemmap[uid] == NULL) { Type ty; rcc_type_ty type = (void *)items[uid]; assert(items[uid]); assert(items[uid]->uid == uid); assert(items[uid]->kind == rcc_Type_enum); type = items[uid]->v.rcc_Type.type; assert(type); switch (type->kind) { case rcc_INT_enum: ty = btot(INT, type->size); assert(ty->align == type->align); break; case rcc_UNSIGNED_enum: ty = btot(UNSIGNED, type->size); assert(ty->align == type->align); break; case rcc_FLOAT_enum: ty = btot(FLOAT, type->size); assert(ty->align == type->align); break; case rcc_VOID_enum: ty = voidtype; break; case rcc_POINTER_enum: ty = ptr(uid2type(type->v.rcc_POINTER.type)); break; case rcc_ARRAY_enum: ty = uid2type(type->v.rcc_ARRAY.type); assert(ty->size > 0); ty = array(ty, type->size/ty->size, 0); break; case rcc_CONST_enum: ty = qual(CONST, uid2type(type->v.rcc_CONST.type)); break; case rcc_VOLATILE_enum: ty = qual(VOLATILE, uid2type(type->v.rcc_VOLATILE.type)); break; case rcc_ENUM_enum: { int i, n = Seq_length(type->v.rcc_ENUM.ids); ty = newstruct(ENUM, string(type->v.rcc_ENUM.tag)); ty->type = inttype; ty->size = ty->type->size; ty->align = ty->type->align; ty->u.sym->u.idlist = newarray(n + 1, sizeof *ty->u.sym->u.idlist, PERM); for (i = 0; i < n; i++) { rcc_enum__ty e = Seq_remlo(type->v.rcc_ENUM.ids); Symbol p = install(e->id, &identifiers, GLOBAL, PERM); p->type = ty; p->sclass = ENUM; p->u.value = e->value; ty->u.sym->u.idlist[i] = p; free(e); } ty->u.sym->u.idlist[i] = NULL; Seq_free(&type->v.rcc_ENUM.ids); break; } case rcc_STRUCT_enum: case rcc_UNION_enum: { int i, n; Field *tail; list_ty fields; if (type->kind == rcc_STRUCT_enum) { ty = newstruct(STRUCT, string(type->v.rcc_STRUCT.tag)); fields = type->v.rcc_STRUCT.fields; } else { ty = newstruct(UNION, string(type->v.rcc_UNION.tag)); fields = type->v.rcc_UNION.fields; } itemmap[uid] = ty; /* recursive types */ ty->size = type->size; ty->align = type->align; tail = &ty->u.sym->u.s.flist; n = Seq_length(fields); for (i = 0; i < n; i++) { rcc_field_ty field = Seq_remlo(fields); NEW0(*tail, PERM); (*tail)->name = (char *)field->id; (*tail)->type = uid2type(field->type); (*tail)->offset = field->offset; (*tail)->bitsize = field->bitsize; (*tail)->lsb = field->lsb; if (isconst((*tail)->type)) ty->u.sym->u.s.cfields = 1; if (isvolatile((*tail)->type)) ty->u.sym->u.s.vfields = 1; tail = &(*tail)->link; free(field); } Seq_free(&fields); break; } case rcc_FUNCTION_enum: { int n = Seq_length(type->v.rcc_FUNCTION.formals); if (n > 0) { int i; Type *proto = newarray(n + 1, sizeof *proto, PERM); for (i = 0; i < n; i++) { int *formal = Seq_remlo(type->v.rcc_FUNCTION.formals); proto[i] = uid2type(*formal); free(formal); } proto[i] = NULL; ty = func(uid2type(type->v.rcc_FUNCTION.type), proto, 0); } else ty = func(uid2type(type->v.rcc_FUNCTION.type), NULL, 1); Seq_free(&type->v.rcc_FUNCTION.formals); break; } default: assert(0); } if (itemmap[uid] == NULL) { itemmap[uid] = ty; free(type); free(items[uid]); items[uid] = NULL; } else assert(itemmap[uid] == ty); } return itemmap[uid]; }
void process_quote(void *data) { Quote *quote; struct msg *msg; quote = (Quote *)data; if (quote->thyquote.m_nLen == sizeof (tHYQuote)) { dlist_iter_t iter; dlist_node_t node; int tlen; quote->thyquote.m_cJYS[sizeof quote->thyquote.m_cJYS - 1] = '\0'; quote->thyquote.m_cHYDM[sizeof quote->thyquote.m_cHYDM - 1] = '\0'; quote->m_nMSec = 0; /* in case of multiple monitors */ dlist_rwlock_rdlock(monitors); if (dlist_length(monitors) > 0) { char res[512]; snprintf(res, sizeof res, "RX '%d,%s,%s,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f," "%.2f,%.2f,%d,%.2f,%d,%d,%.2f,%d,%.2f,%d'\r\n", quote->thyquote.m_nTime, quote->thyquote.m_cHYDM, quote->thyquote.m_cJYS, quote->thyquote.m_dZXJ, quote->thyquote.m_dJKP, quote->thyquote.m_dZGJ, quote->thyquote.m_dZDJ, quote->thyquote.m_dZSP, quote->thyquote.m_dJSP, quote->thyquote.m_dZJSJ, quote->thyquote.m_dJJSJ, quote->thyquote.m_nCJSL, quote->thyquote.m_dCJJE, quote->thyquote.m_nZCCL, quote->thyquote.m_nCCL, quote->thyquote.m_dMRJG1, quote->thyquote.m_nMRSL1, quote->thyquote.m_dMCJG1, quote->thyquote.m_nMCSL1); iter = dlist_iter_new(monitors, DLIST_START_HEAD); while ((node = dlist_next(iter))) { client c = (client)dlist_node_value(node); pthread_spin_lock(&c->lock); if (!(c->flags & CLIENT_CLOSE_ASAP)) { if (net_try_write(c->fd, res, strlen(res), 10, NET_NONBLOCK) == -1) { xcb_log(XCB_LOG_WARNING, "Writing to client '%p': %s", c, strerror(errno)); if (++c->eagcount >= 3) client_free_async(c); } else if (c->eagcount) c->eagcount = 0; } pthread_spin_unlock(&c->lock); } dlist_iter_free(&iter); } dlist_rwlock_unlock(monitors); /* FIXME */ if (quote->thyquote.m_nTime == 999999999) { FREE(data); return; /* idiosyncrasy of different timestamps */ } else if ((tlen = intlen(quote->thyquote.m_nTime)) < 10) { int hour; struct tm lt; hour = quote->thyquote.m_nTime / 10000000; if (tv.tv_sec == 0 || hour == 9 || hour == 21) gettimeofday(&tv, NULL); if (prev_hour == 23 && hour == 0) tv.tv_sec += 24 * 60 * 60; prev_hour = hour; localtime_r(&tv.tv_sec, <); if (quote->thyquote.m_cHYDM[0] == 'S' && quote->thyquote.m_cHYDM[1] == 'P') quote->thyquote.m_nTime *= 1000; else if (tlen == 6 || tlen == 7) quote->thyquote.m_nTime *= 100; lt.tm_sec = quote->thyquote.m_nTime % 100000 / 1000; lt.tm_min = quote->thyquote.m_nTime % 10000000 / 100000; lt.tm_hour = hour; quote->m_nMSec = quote->thyquote.m_nTime % 1000; quote->thyquote.m_nTime = mktime(<); } /* FIXME: no millisecond field in some exchanges' quotes */ if (addms) { struct timeval tv; dstr contract = dstr_new(quote->thyquote.m_cHYDM); struct sms *sms; gettimeofday(&tv, NULL); if ((sms = table_get_value(times, contract)) == NULL) { if (NEW(sms)) { sms->qsec = quote->thyquote.m_nTime; sms->sec = tv.tv_sec; sms->msec = tv.tv_usec / 1000; table_insert(times, contract, sms); } } else if (sms->qsec != quote->thyquote.m_nTime) { sms->qsec = quote->thyquote.m_nTime; sms->sec = tv.tv_sec; sms->msec = tv.tv_usec / 1000; dstr_free(contract); } else { int32_t offset; if ((offset = (tv.tv_sec - sms->sec) * 1000 + tv.tv_usec / 1000 - sms->msec) > 999) offset = 999; quote->m_nMSec = offset; dstr_free(contract); } } if (get_logger_level() == __LOG_DEBUG) { time_t t = (time_t)quote->thyquote.m_nTime; char datestr[64]; strftime(datestr, sizeof datestr, "%F %T", localtime(&t)); xcb_log(XCB_LOG_DEBUG, "%s.%03d,%s,%s,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f," "%d,%.2f,%d,%d,%.2f,%d,%.2f,%d", datestr, quote->m_nMSec, quote->thyquote.m_cHYDM, quote->thyquote.m_cJYS, quote->thyquote.m_dZXJ, quote->thyquote.m_dJKP, quote->thyquote.m_dZGJ, quote->thyquote.m_dZDJ, quote->thyquote.m_dZSP, quote->thyquote.m_dJSP, quote->thyquote.m_dZJSJ, quote->thyquote.m_dJJSJ, quote->thyquote.m_nCJSL, quote->thyquote.m_dCJJE, quote->thyquote.m_nZCCL, quote->thyquote.m_nCCL, quote->thyquote.m_dMRJG1, quote->thyquote.m_nMRSL1, quote->thyquote.m_dMCJG1, quote->thyquote.m_nMCSL1); } } else xcb_log(XCB_LOG_DEBUG, "Data '%s' received", data); if (NEW0(msg) == NULL) { FREE(data); return; } msg->data = data; msg->refcount = 1; thrpool_queue(tp, send_quote, msg, NULL, msgfree, NULL); }