/* * Function: processImage * ---------------------- * Called to perform the actual image conversion and disk output. Controls iterations. */ int processImage(rgbyuv_args_t* args) { uint8_t* in = args->in_img; uint8_t* pY = args->pY; uint8_t* pU = args->pU; uint8_t* pV = args->pV; int i,j; #ifdef VERBOSE fprintf(stderr, "Beginning conversion ... \n"); #endif /***************************************PARALLELIZING OPTION NUMBER 1**********************************/ /*******************************THIS OPTION IS FASTER THAN THE OTHER ONE*******************************/ //#pragma omp parallel for schedule(dynamic) private(i) for(i = 0; i < iterations; i++) { int remainder = args->pixels % BPELS; int evenpels = args->pixels - remainder; int tasks = evenpels / BPELS; /***************************************PARALLELIZING OPTION NUMBER 2**********************************/ #pragma omp parallel for schedule(dynamic) private(j) for(j = 0; j < tasks; j++) { convertBlock(in+j*IN_DEPTH*BPELS, pY+j*BPELS, pU+j*BPELS, pV+j*BPELS, BPELS); } if(remainder) convertBlock(in+evenpels*IN_DEPTH, pY+evenpels, pU+evenpels, pV+evenpels, remainder); #ifdef VERBOSE fprintf(stderr, "Finished conversion, writing to disk ... \n"); #endif } return 0; }
/// Process data from bitcoind daemon (esp. RPC getrawmempool for live transactions) void daemonThreadFunc(BlockChain* blockChain) { leveldb::WriteBatch batch; while (true) { std::this_thread::sleep_for(std::chrono::seconds(1)); if (requestedQuit) break; if (!txCheck) continue; try { auto transactions = rpcClient->CallMethod("getrawmempool", Json::Value()); BlockInfo blockInfo; Hash256 latestBlock; { boost::lock_guard<boost::mutex> guard(chainMutex); latestBlock = currentChain.back(); auto blockInfoIt = blocks.find(latestBlock); if (blockInfoIt == blocks.end()) { continue; } blockInfo = blockInfoIt->second; } if (pendingPreviousBlock != latestBlock) { pendingPreviousBlock = latestBlock; // Broadcast new block for live update Json::Value blockResult; blockResult["item"] = "block"; convertBlock(blockResult, pendingPreviousBlock, blockInfo); websocket_server.broadcast_livetx(blockResult.toStyledString().c_str()); { boost::lock_guard<boost::mutex> guard(pendingTransactionsMutex); pendingTransactionIndices.clear(); pendingTransactions.clear(); pendingTransactionsByAddress.clear(); } } for (auto tx = transactions.begin(); tx != transactions.end(); ++tx) { Hash256 txHash; encodeHexString((uint8_t*) &txHash, 32, (*tx).asString(), true); batch.Clear(); { // Already exists? boost::unique_lock<boost::mutex> guard(pendingTransactionsMutex); if (pendingTransactionIndices.find(txHash) != pendingTransactionIndices.end()) continue; } { DbTransaction dbTx; Json::Value parameters(Json::arrayValue); parameters.append(*tx); auto rawTx = rpcClient->CallMethod("getrawtransaction", parameters); auto data = rawTx.asCString(); auto bufferLength = strlen(data) / 2; llvm::SmallVector<uint8_t, 65536> buffer; buffer.resize(bufferLength); encodeHexString(buffer.begin(), bufferLength, data); BlockChain::BlockTransaction tx2; if (!blockChain->processSingleTransaction(buffer.begin(), bufferLength, tx2)) assert("could not read tx" && false); assert(memcmp(tx2.transactionHash, &txHash, 32) == 0); uint64_t totalOutput = 0; bool needBroadcast = false; auto txIndex = dbHelper.txLoad(txHash, dbTx, NULL, NULL); if (txIndex == 0) { { boost::unique_lock<boost::mutex> guard(pendingTransactionsMutex); try { txIndex = processTransaction(batch, dbTx, tx2, time(NULL), false, &pendingTransactionIndices, &pendingTransactions); } catch (std::exception e) { batch.Clear(); continue; } } needBroadcast = true; dbHelper.txSave(batch, txHash, dbTx); db->Write(leveldb::WriteOptions(), &batch); } { boost::unique_lock<boost::mutex> guard(pendingTransactionsMutex); pendingTransactionIndices[txHash] = pendingTransactions.size(); pendingTransactions.emplace_back(txHash, dbTx); // lastPendingTransactions only holds last N items if (lastPendingTransactions.size() >= lastPendingTransactionsSize) lastPendingTransactions.pop_front(); lastPendingTransactions.emplace_back(txHash, dbTx); for (auto output = dbTx.outputs.begin(); output != dbTx.outputs.end(); ++output) { if (output->address.IsNull()) continue; totalOutput += output->value; pendingTransactionsByAddress.emplace(output->address, pendingTransactions.size() - 1); } for (auto input = dbTx.inputs.begin(); input != dbTx.inputs.end(); ++input) { if (input->address.IsNull()) continue; pendingTransactionsByAddress.emplace(input->address, pendingTransactions.size() - 1); } } if (needBroadcast) { Json::Value txResult; // Broadcast tx for live update txResult["item"] = "tx"; txResult["output"] = (double)totalOutput; char timeBuffer[65]; convertTime(dbTx.getBestTimeStamp(), timeBuffer, sizeof(timeBuffer)); txResult["time"] = timeBuffer; txResult["coinage_destroyed"] = dbTx.coinAgeDestroyed / 86400.0; txResult["hash"] = *tx; websocket_server.broadcast_livetx(txResult.toStyledString().c_str()); } } } } catch (std::exception e) { boost::lock_guard<boost::mutex> guard(pendingTransactionsMutex); pendingTransactionIndices.clear(); pendingTransactions.clear(); pendingTransactionsByAddress.clear(); printf("Error processing live transactions: %s!\n", e.what()); } } }