void CacheMap::insert(string cacheKey, string value, int position, int repeat) { string type = checkExistanceAndGetType(cacheKey); bool error = false; if(type!="") { if(type==VECTOR) { instance->mutex.lock(); vector<string>* valueVector = (vector<string>*)instance->cacheMap[cacheKey]; instance->mutex.unlock(); instance->valueLocks[cacheKey]->lock(); if(position<(int)valueVector->size()) { valueVector->insert(valueVector->begin()+position, repeat, value); } else { error = true; } instance->valueLocks[cacheKey]->unlock(); } else if(type==LIST) { instance->mutex.lock(); list<string>* valueList = (list<string>*)instance->cacheMap[cacheKey]; instance->mutex.unlock(); instance->valueLocks[cacheKey]->lock(); if(position<(int)valueList->size()) { list<string>::iterator it = valueList->begin(); advance(it, position); valueList->insert(it, repeat, value); } else { error = true; } instance->valueLocks[cacheKey]->unlock(); } else if(type==DEQUE) { instance->mutex.lock(); deque<string>* valueDeque = (deque<string>*)instance->cacheMap[cacheKey]; instance->mutex.unlock(); instance->valueLocks[cacheKey]->lock(); if(position<(int)valueDeque->size()) { valueDeque->insert(valueDeque->begin()+position, repeat, value); } else { error = true; } instance->valueLocks[cacheKey]->unlock(); } else if(type==QUEUE) { throw ERR_OPNOTSUPP; } else { throw ERR_INVCONTAINER; } } else { throw ERR_NOKEYCACHEMAP; } if(error) { throw ERR_INDGRTCONTSIZ; } }
QVector<QPointF> ArtisticTextShape::calculateAbstractCharacterPositions() { const int totalTextLength = plainText().length(); QVector<QPointF> charPositions; // one more than the number of characters for position after the last character charPositions.resize(totalTextLength+1); // the character index within the text shape int globalCharIndex = 0; QPointF charPos(0, 0); QPointF advance(0, 0); const bool attachedToPath = isOnPath(); foreach(const ArtisticTextRange &range, m_ranges) { QFontMetricsF metrics(QFont(range.font(), &m_paintDevice)); const QString textRange = range.text(); const qreal letterSpacing = range.letterSpacing(); const int localTextLength = textRange.length(); const bool absoluteXOffset = range.xOffsetType() == ArtisticTextRange::AbsoluteOffset; const bool absoluteYOffset = range.yOffsetType() == ArtisticTextRange::AbsoluteOffset; // set baseline shift const qreal baselineShift = baselineShiftForFontSize(range, defaultFont().pointSizeF()); for(int localCharIndex = 0; localCharIndex < localTextLength; ++localCharIndex, ++globalCharIndex) { // apply offset to character if (range.hasXOffset(localCharIndex)) { if (absoluteXOffset) charPos.rx() = range.xOffset(localCharIndex); else charPos.rx() += range.xOffset(localCharIndex); } else { charPos.rx() += advance.x(); } if (range.hasYOffset(localCharIndex)) { if (absoluteYOffset) { // when attached to a path, absolute y-offsets are ignored if (!attachedToPath) charPos.ry() = range.yOffset(localCharIndex); } else { charPos.ry() += range.yOffset(localCharIndex); } } else { charPos.ry() += advance.y(); } // apply baseline shift charPos.ry() += baselineShift; // save character position of current character charPositions[globalCharIndex] = charPos; // advance character position advance = QPointF(metrics.width(textRange[localCharIndex])+letterSpacing, 0.0); charPos.ry() -= baselineShift; } }
glm::vec2 Font::computeTokenExtent(const QString& token) const { glm::vec2 advance(0, _fontSize); foreach(QChar c, token) { Q_ASSERT(c != '\n'); advance.x += (c == ' ') ? _spaceWidth : getGlyph(c).d; }
CSmartPtr<CMsgCommon> CMsgQueues::popMsg() { LOG_INFO_FMT("%s[%p] pop msg ...", m_operator->toString(), m_operator); LOG_INFO_FMT("%s[%p] before pop msg, path[%s] has queue count[%lu] ...", m_operator->toString(), m_operator, m_path.c_str(), m_queues.size()); CSmartPtr<CMsgCommon> msg(NULL); #if defined(USING_STL_MAP) //m_rwlock.rlock(); UINT4 size = m_queues.size(); if (size <= 0) { //m_rwlock.unlock(); return msg; } m_mutex.lock(); m_pos %= size; CMsgQueueMap::iterator it = m_queues.begin(); if (m_pos > 0) advance(it, m_pos); for (UINT4 i = 0; i < size; ++i) { if (it->second.isNull() || it->second->empty()) { ++ m_pos; if (++it == m_queues.end()) { it = m_queues.begin(); m_pos = 0; } } else { it->second->pop(msg); #if 0 if (it->second->empty()) { deleteQueue(it->first); if ((--m_count % 5000 == 0) && (m_count > 0)) LOG_WARN_FMT("-------- path[%s] has %llu queues --------", m_path.c_str(), m_count); break; } #else ++ m_pos; #endif break; } } m_mutex.unlock(); //m_rwlock.unlock(); #elif defined(USING_HASH_MAP) //m_rwlock.rlock(); UINT4 bucketNum = m_queues.bucketNum(); if (bucketNum <= 0) { //m_rwlock.unlock(); return msg; } m_mutex.lock(); m_bucket %= bucketNum; CMsgQueueHMap::CBucket* map = m_queues.bucket(m_bucket); for (UINT4 i = 0; i < bucketNum+1; ++i) { if (!map->empty() && (m_pos < map->size())) { CMsgQueueHMap::CBucket::iterator it = map->begin(); if (m_pos > 0) advance(it, m_pos); while (it != map->end()) { if (it->second.isNull() || it->second->empty()) { ++ it; ++ m_pos; } else { it->second->pop(msg); ++ m_pos; break; } } } if (msg.isNotNull()) { break; } else { m_pos = 0; ++ m_bucket; m_bucket %= bucketNum; map = m_queues.bucket(m_bucket); } } m_mutex.unlock(); //m_rwlock.unlock(); #elif defined(USING_LF_HASH_MAP) UINT4 size = m_queues.size(); if (size <= 0) return msg; m_mutex.lock(); m_pos %= size; CMsgQueueLFHMap::CIterator it = m_queues.begin(); if (m_pos > 0) advance(it, m_pos); for (UINT4 i = 0; i < size; ++i) { if (it->second.isNull() || it->second->empty()) { ++ m_pos; if (++it == m_queues.end()) { it = m_queues.begin(); m_pos = 0; } } else { it->second->pop(msg); #if 0 if (it->second->empty()) { deleteQueue(it->first); if ((m_queues.size() > 0) && (m_queues.size() % 5000 == 0)) LOG_WARN_FMT("-------- path[%s] has %llu queues --------", m_path.c_str(), m_queues.size()); break; } #endif ++ m_pos; break; } } m_mutex.unlock(); #elif defined(USING_LK_HASH_MAP) UINT4 size = m_queues.size(); if (size <= 0) return msg; m_mutex.lock(); m_pos %= size; CMsgQueueLKHMap::CReferenceIterator it = m_queues.begin(); if (m_pos > 0) advance(it, m_pos); for (UINT4 i = 0; i <= size; i++) { CMsgKey key = it->first; CSmartPtr<CMsgQueue> queue = it->second; #if defined(POP_LOCK_GRANULARITY_LARGE) UINT4 index = m_queues.bucketIndex(key); //m_queues.bucketLock(index); if (m_queues.bucketTrylock(index) != 0) { ++ it; ++ m_pos; if (it == m_queues.end()) { it = m_queues.begin(); m_pos = 0; } continue; } #endif if (queue.isNull() || queue->empty()) { ++ it; #if defined(POP_LOCK_GRANULARITY_LARGE) m_queues.bucketUnlock(index); #endif ++ m_pos; if (it == m_queues.end()) { it = m_queues.begin(); m_pos = 0; } } else { queue->pop(msg); #if defined(POP_LOCK_GRANULARITY_LARGE) if (queue->empty()) { deleteQueue(key); m_queues.bucketUnlock(index); break; } m_queues.bucketUnlock(index); #elif defined(POP_LOCK_GRANULARITY_LITTLE) if (queue->empty()) { UINT4 index = m_queues.bucketIndex(key); //m_queues.bucketLock(index); if (m_queues.bucketTrylock(index) == 0) { if (queue->empty()) { deleteQueue(key); m_queues.bucketUnlock(index); break; } m_queues.bucketUnlock(index); } } #endif ++ m_pos; break; } } m_mutex.unlock(); #endif LOG_INFO_FMT("%s[%p] after poped msg, path[%s] has queue count[%lu] ...", m_operator->toString(), m_operator, m_path.c_str(), m_queues.size()); #if 0 if (!m_queues.empty()&& (!strcmp(m_operator->toString(),"CSwitchEventTester")|| !strcmp(m_operator->toString(),"CLinkEventTester")|| !strcmp(m_operator->toString(),"CPortEventTester"))) if (m_queues.size() == 1) { CMsgKey key; CMsgQueue* queue = NULL; m_queues.front(key, queue); LOG_WARN_FMT("######%s[%p] after poped msg, path[%s] has only key[%s] queue size[%lu] ...", m_operator->toString(), m_operator, m_path.c_str(), key.c_str(), queue->size()); } else { LOG_WARN_FMT("######%s[%p] after poped msg, path[%s] has queue count[%lu] ...", m_operator->toString(), m_operator, m_path.c_str(), m_queues.size()); } #endif return msg; }
filter_iterator& operator++() { advance(); return *this; }
bool InliningDecider::shouldInline(const Func* callee, const RegionDesc& region, uint32_t maxTotalCost) { auto sk = region.empty() ? SrcKey() : region.start(); assertx(callee); assertx(sk.func() == callee); // Tracing return lambdas. auto refuse = [&] (const char* why) { FTRACE(1, "shouldInline: rejecting callee region: {}", show(region)); return traceRefusal(m_topFunc, callee, why); }; auto accept = [&, this] (const char* kind) { FTRACE(1, "InliningDecider: inlining {}() <- {}()\t<reason: {}>\n", m_topFunc->fullName()->data(), callee->fullName()->data(), kind); return true; }; // Check inlining depths. if (m_callDepth + 1 >= RuntimeOption::EvalHHIRInliningMaxDepth) { return refuse("inlining call depth limit exceeded"); } if (m_stackDepth + callee->maxStackCells() >= kStackCheckLeafPadding) { return refuse("inlining stack depth limit exceeded"); } // Even if the func contains NativeImpl we may have broken the trace before // we hit it. auto containsNativeImpl = [&] { for (auto block : region.blocks()) { if (!block->empty() && block->last().op() == OpNativeImpl) return true; } return false; }; // Try to inline CPP builtin functions. // The NativeImpl opcode may appear later in the function because of Asserts // generated in hhbbc if (callee->isCPPBuiltin() && containsNativeImpl()) { if (isInlinableCPPBuiltin(callee)) { return accept("inlinable CPP builtin"); } return refuse("non-inlinable CPP builtin"); } // If the function may use a VarEnv (which is stored in the ActRec) or may be // variadic, we restrict inlined callees to certain whitelisted instructions // which we know won't actually require these features. const bool needsCheckVVSafe = callee->attrs() & AttrMayUseVV; int numRets = 0; int numExits = 0; // Iterate through the region, checking its suitability for inlining. for (auto const& block : region.blocks()) { sk = block->start(); for (auto i = 0, n = block->length(); i < n; ++i, sk.advance()) { auto op = sk.op(); // We don't allow inlined functions in the region. The client is // expected to disable inlining for the region it gives us to peek. if (sk.func() != callee) { return refuse("got region with inlined calls"); } // Restrict to VV-safe opcodes if necessary. if (needsCheckVVSafe && !isInliningVVSafe(op)) { return refuse(folly::format("{} may use dynamic environment", opcodeToName(op)).str().c_str()); } // Count the returns. if (isReturnish(op)) { if (++numRets > RuntimeOption::EvalHHIRInliningMaxReturns) { return refuse("region has too many returns"); } continue; } // We can't inline FCallArray. XXX: Why? if (op == Op::FCallArray) { return refuse("can't inline FCallArray"); } } if (region.isExit(block->id())) { if (++numExits > RuntimeOption::EvalHHIRInliningMaxBindJmps + numRets) { return refuse("region has too many non return exits"); } } } // Refuse if the cost exceeds our thresholds. // We measure the cost of inlining each callstack and stop when it exceeds a // certain threshold. (Note that we do not measure the total cost of all the // inlined calls for a given caller---just the cost of each nested stack.) const int maxCost = maxTotalCost - m_cost; const int cost = computeCost(region); if (cost > maxCost) { return refuse("too expensive"); } if (numRets == 0) { return refuse("region has no returns"); } return accept("small region with single return"); }
// Parse an inline, advancing subject, and add it as a child of parent. // Return 0 if no inline can be parsed, 1 otherwise. static int parse_inline(subject* subj, cmark_node * parent) { cmark_node* new_inl = NULL; cmark_chunk contents; unsigned char c; int endpos; c = peek_char(subj); if (c == 0) { return 0; } switch(c) { case '\n': new_inl = handle_newline(subj); break; case '`': new_inl = handle_backticks(subj); break; case '\\': new_inl = handle_backslash(subj); break; case '&': new_inl = handle_entity(subj); break; case '<': new_inl = handle_pointy_brace(subj); break; case '*': case '_': new_inl = handle_strong_emph(subj, c); break; case '[': advance(subj); new_inl = make_str(cmark_chunk_literal("[")); push_delimiter(subj, '[', true, false, new_inl); break; case ']': new_inl = handle_close_bracket(subj, parent); break; case '!': advance(subj); if (peek_char(subj) == '[') { advance(subj); new_inl = make_str(cmark_chunk_literal("![")); push_delimiter(subj, '!', false, true, new_inl); } else { new_inl = make_str(cmark_chunk_literal("!")); } break; default: endpos = subject_find_special_char(subj); contents = cmark_chunk_dup(&subj->input, subj->pos, endpos - subj->pos); subj->pos = endpos; // if we're at a newline, strip trailing spaces. if (peek_char(subj) == '\n') { cmark_chunk_rtrim(&contents); } new_inl = make_str(contents); } if (new_inl != NULL) { cmark_node_append_child(parent, new_inl); } return 1; }
int CLINScheduleDataStore::nEnableScheduleCommand(int nChannel, int nTableIndex, int nItemIndex, bool bEnable ) { if ( ( nChannel < 0 ) && ( nChannel >= CHANNEL_ALLOWED ) ) { return S_FALSE; } if ( bEnable == true ) { std::list<CSheduleTable>::iterator itrTable = m_ouTableData[nChannel].m_ouScheduleTables.begin(); int nCurrentIndex = 0; while (itrTable != m_ouTableData[nChannel].m_ouScheduleTables.end()) { if ( nCurrentIndex == nTableIndex ) { std::list<CScheduleCommands>::iterator itrCommand = itrTable->m_listCommands.begin(); advance(itrCommand, nItemIndex); if ( itrCommand != itrTable->m_listCommands.end() ) { itrCommand->m_bEnabled = bEnable; if ( m_ouTableData[nChannel].m_strCurrentTable != itrTable->m_strTableName) { m_ouTableData[nChannel].m_strCurrentTable = itrTable->m_strTableName; nTransmitScheduleTable(nChannel, nTableIndex); } else { nTransmitScheduleCommand(nChannel, nTableIndex, nItemIndex, bEnable); } } } else { nEnableCommands(*itrTable, false ); } itrTable++; nCurrentIndex++; } } else { std::list<CSheduleTable>::iterator itrTable = m_ouTableData[nChannel].m_ouScheduleTables.begin(); advance(itrTable, nTableIndex); if (itrTable != m_ouTableData[nChannel].m_ouScheduleTables.end()) { std::list<CScheduleCommands>::iterator itrCommand = itrTable->m_listCommands.begin(); int i = 0; int bENabled = 0; while ( itrCommand != itrTable->m_listCommands.end() ) { if ( i == nItemIndex ) { itrCommand->m_bEnabled = false; } if ( itrCommand->m_bEnabled ) { bENabled++; } itrCommand++; i++; } if ( bENabled == 0 ) { m_ouTableData[nChannel].m_strCurrentTable.clear(); } nTransmitScheduleCommand(nChannel, nTableIndex, nItemIndex, bEnable); } } return S_OK; }
int get_mixed_part_delimiter(str* body, str *mp_delimiter) { static unsigned int boun[16] = { 0x6e756f62,0x4e756f62,0x6e556f62,0x4e556f62, 0x6e754f62,0x4e754f62,0x6e554f62,0x4e554f62, 0x6e756f42,0x4e756f42,0x6e556f42,0x4e556f42, 0x6e754f42,0x4e754f42,0x6e554f42,0x4e554f42}; static unsigned int dary[16] = { 0x79726164,0x59726164,0x79526164,0x59526164, 0x79724164,0x59724164,0x79524164,0x59524164, 0x79726144,0x59726144,0x79526144,0x59526144, 0x79724144,0x59724144,0x79524144,0x59524144}; str str_type; unsigned int x; char *p; /* LM_DBG("<%.*s>\n",body->len,body->s); */ p = str_type.s = body->s; str_type.len = body->len; while (*p!=';' && p<(body->s+body->len)) advance(p,1,str_type,error); p++; str_type.s = p; str_type.len = body->len - (p - body->s); /* LM_DBG("string to parse: <%.*s>\n",str_type.len,str_type.s); */ /* skip spaces and tabs if any */ while (*p==' ' || *p=='\t') advance(p,1,str_type,error); advance(p,4,str_type,error); x = READ(p-4); if (!one_of_16(x,boun)) goto other; advance(p,4,str_type,error); x = READ(p-4); if (!one_of_16(x,dary)) goto other; /* skip spaces and tabs if any */ while (*p==' ' || *p=='\t') advance(p,1,str_type,error); if (*p!='=') { LM_ERR("parse error: no = found after boundary field\n"); goto error; } advance(p,1,str_type,error); while ((*p==' ' || *p=='\t') && p+1<str_type.s+str_type.len) advance(p,1,str_type,error); mp_delimiter->len = str_type.len - (int)(p-str_type.s); mp_delimiter->s = p; /* check if the boundary value is enclosed in quotes */ if(*p=='"' || *p=='\'') { if(mp_delimiter->s[mp_delimiter->len-1]==*p) { mp_delimiter->s = p+1; mp_delimiter->len -= 2; if(mp_delimiter->len<=0) { LM_ERR("invalid boundary field value\n"); goto error; } } else { LM_ERR("missing closing quote in boundary field value\n"); goto error; } } return 1; error: return -1; other: LM_DBG("'boundary' parsing error\n"); return -1; }
void Preprocessor::findLineDelimiters (const std::deque<bool>& visited) { delimiters_.clear(); // Traverse each row searching non-visited pixels unsigned int topRowOfTextLine = 0; bool rowHasInk = false, previousRowHasInk; for ( unsigned int i = 0; i < clipHeight_; ++i ) { previousRowHasInk = rowHasInk; rowHasInk = false; for ( unsigned int j = 0; j < clipWidth_; ++j ) { if ( visited.at(i * clipWidth_ + j) ) { rowHasInk = true; break; } } if (not rowHasInk ) { if ( previousRowHasInk ) delimiters_.push_back( LineDelimiter(topRowOfTextLine, i-1) ); else topRowOfTextLine = i; } else { if ( not previousRowHasInk ) topRowOfTextLine = i; } } // Make sure the last text line joins with the clip border if ( rowHasInk ) delimiters_.push_back( LineDelimiter(topRowOfTextLine, clipHeight_-1) ); LineDelimiterIterator previousLineDelimiterIterator = delimiters_.begin(); LineDelimiterIterator currentLineDelimiterIterator = delimiters_.begin(); advance( currentLineDelimiterIterator, 1 ); // Search lines that are too close to each other, probably because there are accents belonging to characters on a single line while ( currentLineDelimiterIterator != delimiters_.end() ) { unsigned int currentLineHeight = currentLineDelimiterIterator->second - currentLineDelimiterIterator->first + 1; unsigned int previousLineHeight = previousLineDelimiterIterator->second - previousLineDelimiterIterator->first + 1; if ( previousLineHeight > (currentLineHeight / 2) ) { advance( currentLineDelimiterIterator, 1 ); advance( previousLineDelimiterIterator, 1 ); } else { // A new line delimiter is inserted by joining the two line delimiters explored. delimiters_.insert( previousLineDelimiterIterator, LineDelimiter(previousLineDelimiterIterator->first, currentLineDelimiterIterator->second) ); LineDelimiterIterator newLineDelimiterIterator = previousLineDelimiterIterator; advance ( newLineDelimiterIterator, -1 ); // The two old line delimiters are removed from the list delimiters_.erase( previousLineDelimiterIterator ); previousLineDelimiterIterator = currentLineDelimiterIterator; advance( currentLineDelimiterIterator, 1 ); delimiters_.erase( previousLineDelimiterIterator ); previousLineDelimiterIterator = newLineDelimiterIterator; } } }
void CLINScheduleDataStore::vSetScheduleConfig(xmlNodePtr pNode) { xmlChar* pchPath = (xmlChar*)DEF_INDEX; xmlXPathObjectPtr pObjectPath = xmlUtils::pGetChildNodes(pNode, pchPath); INT nChannel = 0; if (pObjectPath != NULL ) { xmlNodeSetPtr pNodeSet = pObjectPath->nodesetval; if( NULL != pNodeSet ) { xmlNodePtr pNode = pNodeSet->nodeTab[0]; //Take First One only xmlChar* key = xmlNodeListGetString(pNode->doc, pNode->xmlChildrenNode , 1); nChannel = atoi( (char*)key) - 1; } } // Validating channel number aginst available channels after conversion int nNumChannels = 0; m_ouClusterConfig->GetChannelCount(LIN, nNumChannels); if (nChannel > nNumChannels || nChannel < 0) { nChannel = 0; } pchPath = (xmlChar*)DEF_NAME; pObjectPath = xmlUtils::pGetChildNodes(pNode, pchPath); std::string strScheduleName; if (pObjectPath != NULL ) { xmlNodeSetPtr pNodeSet = pObjectPath->nodesetval; if( NULL != pNodeSet ) { xmlNodePtr pNode = pNodeSet->nodeTab[0]; //Take First One only xmlChar* key = xmlNodeListGetString(pNode->doc, pNode->xmlChildrenNode , 1); strScheduleName = (char*)key; } } std::list<FrameState> lstFrames; xmlChar* pchPathMsg = (xmlChar*)DEF_FRAMES; pObjectPath = xmlUtils::pGetChildNodes(pNode, pchPathMsg); if (pObjectPath != NULL ) { xmlNodeSetPtr pNodeSet = pObjectPath->nodesetval; if( NULL != pNodeSet ) { for ( int nChldIndex =0 ; nChldIndex < pNodeSet->nodeNr; nChldIndex++ ) { xmlNodePtr pNode = pNodeSet->nodeTab[nChldIndex]; //Take First One only xmlChar* pchPathMsg = (xmlChar*)DEF_FRAME; xmlXPathObjectPtr pObjectPath = xmlUtils::pGetChildNodes(pNode, pchPathMsg); if (pObjectPath != NULL ) { xmlNodeSetPtr pFrameNodeSet = pObjectPath->nodesetval; FrameState omFrameState; // Get the frame attributes for ( int nFrameIndex =0 ; nFrameIndex < pFrameNodeSet->nodeNr; nFrameIndex++ ) { xmlNodePtr pFrameNode = pFrameNodeSet->nodeTab[nFrameIndex]; //Take First One only xmlChar* pchPathMsg = (xmlChar*)DEF_NAME; xmlXPathObjectPtr pObjectPath = xmlUtils::pGetChildNodes(pFrameNode, pchPathMsg); if (pObjectPath != NULL ) { pNodeSet = pObjectPath->nodesetval; pNode = pNodeSet->nodeTab[0]; xmlChar* key = xmlNodeListGetString(pNode->doc, pNode->xmlChildrenNode , 1); omFrameState.omName = (char*)key; } pchPathMsg = (xmlChar*)DEF_IsEnabled; pObjectPath = xmlUtils::pGetChildNodes(pFrameNode, pchPathMsg); if (pObjectPath != NULL ) { pNodeSet = pObjectPath->nodesetval; pNode = pNodeSet->nodeTab[0]; xmlChar* key = xmlNodeListGetString(pNode->doc, pNode->xmlChildrenNode , 1); std::string omIsEnabled = (char*)key; if(omIsEnabled == DEF_TRUE) { omFrameState.bIsEnabled = TRUE; } else { omFrameState.bIsEnabled = FALSE; } } lstFrames.push_back(omFrameState); } } } } } std::list<CSheduleTable>::iterator itrTable = m_ouTableData[nChannel].m_ouScheduleTables.begin(); while( itrTable != m_ouTableData[nChannel].m_ouScheduleTables.end() ) { if ( itrTable->m_strTableName == strScheduleName ) { m_ouTableData[nChannel].m_strCurrentTable = strScheduleName; std::list<CScheduleCommands>::iterator itrCommand; INT nIndex = 0; for (itrCommand = itrTable->m_listCommands.begin(); itrCommand != itrTable->m_listCommands.end(); itrCommand++ ) { std::list<FrameState>::iterator itrFrame = lstFrames.begin(); advance(itrFrame, nIndex); if ( itrFrame != lstFrames.end() ) { if(itrFrame->omName.compare(itrCommand->m_strCommandName.c_str()) == 0) { itrCommand->m_bEnabled = itrFrame->bIsEnabled; } } nIndex++; } break; m_ouTableData[nChannel].m_strCurrentTable = strScheduleName; } itrTable++; } }
int main(int argc, char *argv[]) { // Инициализируем генератор псевдослучайных чисел qsrand(QTime::currentTime().msec()); QApplication app(argc, argv); BubbleItem::setBubblePixmap(QPixmap(":/images/bubble.png")); // Получаем скриншот QScreen *screen = QApplication::primaryScreen(); if (!screen) return -1; QPixmap screenshot = screen->grabWindow(0); // QGraphicsScene - контейнер для создаваемых нами // объектов класса Bubble QGraphicsScene scene; scene.setSceneRect( screenshot.rect() ); // Наполняем сцену непересекающимися элементами { const int left = scene.sceneRect().left() + BubbleItem::RADIUS; const int top = scene.sceneRect().top() + BubbleItem::RADIUS; const int right = scene.sceneRect().right() - BubbleItem::RADIUS; const int bottom = scene.sceneRect().bottom() - BubbleItem::RADIUS; for (int i = 0; i < BUBBLES_AMOUNT; ++i) { BubbleItem *bubble = new BubbleItem(); scene.addItem(bubble); // Будем давать пузырю случайные координаты до тез пор // пока он не прекратит пересекаться с другими пузырями do { bubble->setPos( left + qrand() % (right - left), top + qrand() % (bottom - top) ); } while ( !scene.collidingItems(bubble).isEmpty() ); } } // MainWidget - главный и единственный виджет этой программы, // он непосредственно рисует на экране элементы сцены, а также // обрабатывает нажатие клавиш и завершает выполнение программы при // нажатии клавиши ESC MainWidget view(&scene); view.setBackgroundPixmap(screenshot); view.setRenderHint(QPainter::Antialiasing); view.showFullScreen(); // Используем QTimer для анимации движения пузырей. Сцена будет принудительно // обновляться EXPECTED_FPS раз в секунду QTimer timer; QObject::connect(&timer, SIGNAL(timeout()), &scene, SLOT(advance())); timer.start(1000 / EXPECTED_FPS); return app.exec(); }
/*===========================================================================* * new_node * *===========================================================================*/ PRIVATE struct inode *new_node(struct inode **ldirp, char *path, mode_t bits, zone_t z0, int opaque, char *parsed) { /* New_node() is called by common_open(), do_mknod(), and do_mkdir(). * In all cases it allocates a new inode, makes a directory entry for it on * the path 'path', and initializes it. It returns a pointer to the inode if * it can do this; otherwise it returns NIL_INODE. It always sets 'err_code' * to an appropriate value (OK or an error code). * * The parsed path rest is returned in 'parsed' if parsed is nonzero. It * has to hold at least NAME_MAX bytes. */ register struct inode *rip; register int r; char string[NAME_MAX]; *ldirp = parse_path(path, string, opaque ? LAST_DIR : LAST_DIR_EATSYM); if (*ldirp == NIL_INODE) return(NIL_INODE); /* The final directory is accessible. Get final component of the path. */ rip = advance(ldirp, string); if (S_ISDIR(bits) && (*ldirp)->i_nlinks >= ((*ldirp)->i_sp->s_version == V1 ? CHAR_MAX : SHRT_MAX)) { /* New entry is a directory, alas we can't give it a ".." */ put_inode(rip); err_code = EMLINK; return(NIL_INODE); } if ( rip == NIL_INODE && err_code == ENOENT) { /* Last path component does not exist. Make new directory entry. */ if ( (rip = alloc_inode((*ldirp)->i_dev, bits)) == NIL_INODE) { /* Can't creat new inode: out of inodes. */ return(NIL_INODE); } /* Force inode to the disk before making directory entry to make * the system more robust in the face of a crash: an inode with * no directory entry is much better than the opposite. */ rip->i_nlinks++; rip->i_zone[0] = z0; /* major/minor device numbers */ rw_inode(rip, WRITING); /* force inode to disk now */ /* New inode acquired. Try to make directory entry. */ if ((r = search_dir(*ldirp, string, &rip->i_num,ENTER)) != OK) { rip->i_nlinks--; /* pity, have to free disk inode */ rip->i_dirt = DIRTY; /* dirty inodes are written out */ put_inode(rip); /* this call frees the inode */ err_code = r; return(NIL_INODE); } } else { /* Either last component exists, or there is some problem. */ if (rip != NIL_INODE) r = EEXIST; else r = err_code; } if(parsed) { /* Give the caller the parsed string if requested. */ strncpy(parsed, string, NAME_MAX-1); parsed[NAME_MAX-1] = '\0'; } /* The caller has to return the directory inode (*ldirp). */ err_code = r; return(rip); }
// Scan ***, **, or * and return number scanned, or 0. // Advances position. static int scan_delims(subject* subj, unsigned char c, bool * can_open, bool * can_close) { int numdelims = 0; int before_char_pos; int32_t after_char = 0; int32_t before_char = 0; int len; bool left_flanking, right_flanking; if (subj->pos == 0) { before_char = 10; } else { before_char_pos = subj->pos - 1; // walk back to the beginning of the UTF_8 sequence: while (peek_at(subj, before_char_pos) >> 6 == 2 && before_char_pos > 0) { before_char_pos -= 1; } len = utf8proc_iterate(subj->input.data + before_char_pos, subj->pos - before_char_pos, &before_char); if (len == -1) { before_char = 10; } } if (c == '\'' || c == '"') { numdelims++; advance(subj); // limit to 1 delim for quotes } else { while (peek_char(subj) == c) { numdelims++; advance(subj); } } len = utf8proc_iterate(subj->input.data + subj->pos, subj->input.len - subj->pos, &after_char); if (len == -1) { after_char = 10; } left_flanking = numdelims > 0 && !utf8proc_is_space(after_char) && !(utf8proc_is_punctuation(after_char) && !utf8proc_is_space(before_char) && !utf8proc_is_punctuation(before_char)); right_flanking = numdelims > 0 && !utf8proc_is_space(before_char) && !(utf8proc_is_punctuation(before_char) && !utf8proc_is_space(after_char) && !utf8proc_is_punctuation(after_char)); if (c == '_') { *can_open = left_flanking && (!right_flanking || utf8proc_is_punctuation(before_char)); *can_close = right_flanking && (!left_flanking || utf8proc_is_punctuation(after_char)); } else if (c == '\'' || c == '"') { *can_open = left_flanking && !right_flanking; *can_close = right_flanking; } else { *can_open = left_flanking; *can_close = right_flanking; } return numdelims; }
Res::ResourceSet::nziterator Res::ResourceSet::nziterator::operator++() { advance(); return *this; }
bool on_encoder(const EncoderEvent event) override { advance(event); return true; }
Res::ResourceSet::nziterator Res::ResourceSet::nziterator::operator++(int) { nziterator ret = *this; advance(); return ret; }
Tuple Relation::getRowAtIndex(int index){ set<Tuple>::iterator it = rows.begin(); advance(it, index); // now it is advanced by index return *it; }
// Return a link, an image, or a literal close bracket. static cmark_node* handle_close_bracket(subject* subj, cmark_node *parent) { int initial_pos; int starturl, endurl, starttitle, endtitle, endall; int n; int sps; cmark_reference *ref; bool is_image = false; cmark_chunk url_chunk, title_chunk; unsigned char *url, *title; delimiter *opener; cmark_node *link_text; cmark_node *inl; cmark_chunk raw_label; int found_label; advance(subj); // advance past ] initial_pos = subj->pos; // look through list of delimiters for a [ or ! opener = subj->last_delim; while (opener) { if (opener->delim_char == '[' || opener->delim_char == '!') { break; } opener = opener->previous; } if (opener == NULL) { return make_str(cmark_chunk_literal("]")); } if (!opener->active) { // take delimiter off stack remove_delimiter(subj, opener); return make_str(cmark_chunk_literal("]")); } // If we got here, we matched a potential link/image text. is_image = opener->delim_char == '!'; link_text = opener->inl_text->next; // Now we check to see if it's a link/image. // First, look for an inline link. if (peek_char(subj) == '(' && ((sps = scan_spacechars(&subj->input, subj->pos + 1)) > -1) && ((n = scan_link_url(&subj->input, subj->pos + 1 + sps)) > -1)) { // try to parse an explicit link: starturl = subj->pos + 1 + sps; // after ( endurl = starturl + n; starttitle = endurl + scan_spacechars(&subj->input, endurl); // ensure there are spaces btw url and title endtitle = (starttitle == endurl) ? starttitle : starttitle + scan_link_title(&subj->input, starttitle); endall = endtitle + scan_spacechars(&subj->input, endtitle); if (peek_at(subj, endall) == ')') { subj->pos = endall + 1; url_chunk = cmark_chunk_dup(&subj->input, starturl, endurl - starturl); title_chunk = cmark_chunk_dup(&subj->input, starttitle, endtitle - starttitle); url = cmark_clean_url(&url_chunk); title = cmark_clean_title(&title_chunk); cmark_chunk_free(&url_chunk); cmark_chunk_free(&title_chunk); goto match; } else { goto noMatch; } } // Next, look for a following [link label] that matches in refmap. // skip spaces subj->pos = subj->pos + scan_spacechars(&subj->input, subj->pos); raw_label = cmark_chunk_literal(""); found_label = link_label(subj, &raw_label); if (!found_label || raw_label.len == 0) { cmark_chunk_free(&raw_label); raw_label = cmark_chunk_dup(&subj->input, opener->position, initial_pos - opener->position - 1); } if (!found_label) { // If we have a shortcut reference link, back up // to before the spacse we skipped. subj->pos = initial_pos; } ref = cmark_reference_lookup(subj->refmap, &raw_label); cmark_chunk_free(&raw_label); if (ref != NULL) { // found url = bufdup(ref->url); title = bufdup(ref->title); goto match; } else { goto noMatch; } noMatch: // If we fall through to here, it means we didn't match a link: remove_delimiter(subj, opener); // remove this opener from delimiter list subj->pos = initial_pos; return make_str(cmark_chunk_literal("]")); match: inl = opener->inl_text; inl->type = is_image ? NODE_IMAGE : NODE_LINK; cmark_chunk_free(&inl->as.literal); inl->first_child = link_text; process_emphasis(subj, opener->previous); inl->as.link.url = url; inl->as.link.title = title; inl->next = NULL; if (link_text) { cmark_node *tmp; link_text->prev = NULL; for (tmp = link_text; tmp->next != NULL; tmp = tmp->next) { tmp->parent = inl; } tmp->parent = inl; inl->last_child = tmp; } parent->last_child = inl; // process_emphasis will remove this delimiter and all later ones. // Now, if we have a link, we also want to deactivate earlier link // delimiters. (This code can be removed if we decide to allow links // inside links.) if (!is_image) { opener = subj->last_delim; while (opener != NULL) { if (opener->delim_char == '[') { if (!opener->active) { break; } else { opener->active = false; } } opener = opener->previous; } } return NULL; }
void Relation::deleteTuple(int index){ set<Tuple>::iterator it = rows.begin(); advance(it, index); // now it is advanced by index this->rows.erase(it); }
int check_content_type(struct sip_msg *msg) { static unsigned int appl[16] = { 0x6c707061/*appl*/,0x6c707041/*Appl*/,0x6c705061/*aPpl*/, 0x6c705041/*APpl*/,0x6c507061/*apPl*/,0x6c507041/*ApPl*/, 0x6c505061/*aPPl*/,0x6c505041/*APPl*/,0x4c707061/*appL*/, 0x4c707041/*AppL*/,0x4c705061/*aPpL*/,0x4c705041/*APpL*/, 0x4c507061/*apPL*/,0x4c507041/*ApPL*/,0x4c505061/*aPPL*/, 0x4c505041/*APPL*/}; static unsigned int icat[16] = { 0x74616369/*icat*/,0x74616349/*Icat*/,0x74614369/*iCat*/, 0x74614349/*ICat*/,0x74416369/*icAt*/,0x74416349/*IcAt*/, 0x74414369/*iCAt*/,0x74414349/*ICAt*/,0x54616369/*icaT*/, 0x54616349/*IcaT*/,0x54614369/*iCaT*/,0x54614349/*ICaT*/, 0x54416369/*icAT*/,0x54416349/*IcAT*/,0x54414369/*iCAT*/, 0x54414349/*ICAT*/}; static unsigned int ion_[8] = { 0x006e6f69/*ion_*/,0x006e6f49/*Ion_*/,0x006e4f69/*iOn_*/, 0x006e4f49/*IOn_*/,0x004e6f69/*ioN_*/,0x004e6f49/*IoN_*/, 0x004e4f69/*iON_*/,0x004e4f49/*ION_*/}; static unsigned int sdp_[8] = { 0x00706473/*sdp_*/,0x00706453/*Sdp_*/,0x00704473/*sDp_*/, 0x00704453/*SDp_*/,0x00506473/*sdP_*/,0x00506453/*SdP_*/, 0x00504473/*sDP_*/,0x00504453/*SDP_*/}; str str_type; unsigned int x; char *p; if (!msg->content_type) { LOG(L_WARN,"WARNING: check_content_type: Content-TYPE header absent!" "let's assume the content is text/plain ;-)\n"); return 1; } trim_len(str_type.len,str_type.s,msg->content_type->body); p = str_type.s; advance(p,4,str_type,error_1); x = READ(p-4); if (!one_of_16(x,appl)) goto other; advance(p,4,str_type,error_1); x = READ(p-4); if (!one_of_16(x,icat)) goto other; advance(p,3,str_type,error_1); x = READ(p-3) & 0x00ffffff; if (!one_of_8(x,ion_)) goto other; /* skip spaces and tabs if any */ while (*p==' ' || *p=='\t') advance(p,1,str_type,error_1); if (*p!='/') { LOG(L_ERR, "ERROR:check_content_type: parse error:" "no / found after primary type\n"); goto error; } advance(p,1,str_type,error_1); while ((*p==' ' || *p=='\t') && p+1<str_type.s+str_type.len) advance(p,1,str_type,error_1); advance(p,3,str_type,error_1); x = READ(p-3) & 0x00ffffff; if (!one_of_8(x,sdp_)) goto other; if (*p==';'||*p==' '||*p=='\t'||*p=='\n'||*p=='\r'||*p==0) { DBG("DEBUG:check_content_type: type <%.*s> found valid\n", (int)(p-str_type.s), str_type.s); return 1; } else { LOG(L_ERR,"ERROR:check_content_type: bad end for type!\n"); return -1; } error_1: LOG(L_ERR,"ERROR:check_content_type: parse error: body ended :-(!\n"); error: return -1; other: LOG(L_ERR,"ERROR:check_content_type: invlaid type for a message\n"); return -1; }
static unsigned char next_octet(unsigned char **cursor, qd_buffer_t **buffer) { unsigned char result = **cursor; advance(cursor, buffer, 1, 0, 0); return result; }
CSmartPtr<CMsgQueue> CMsgQueues::popMsgQueue() { LOG_INFO_FMT("%s[%p] pop msg queue ...", m_operator->toString(), m_operator); LOG_INFO_FMT("%s[%p] before pop msg queue, path[%s] has queue count[%lu] ...", m_operator->toString(), m_operator, m_path.c_str(), m_queues.size()); CSmartPtr<CMsgQueue> queue(NULL); #if defined(USING_STL_MAP) //m_rwlock.rlock(); UINT4 size = m_queues.size(); if (size <= 0) { //m_rwlock.unlock(); return queue; } m_mutex.lock(); m_pos %= size; CMsgQueueMap::iterator it = m_queues.begin(); if (m_pos > 0) advance(it, m_pos); for (UINT4 i = 0; i < size; i++) { if (it->second.isNull() || it->second->empty() || it->second->isBusy()) { ++ m_pos; if (++it == m_queues.end()) { it = m_queues.begin(); m_pos = 0; } } else { it->second->setBusy(TRUE); queue = it->second; ++ m_pos; break; } } m_mutex.unlock(); //m_rwlock.unlock(); #elif defined(USING_HASH_MAP) //m_rwlock.rlock(); UINT4 bucketNum = m_queues.bucketNum(); if (bucketNum <= 0) { //m_rwlock.unlock(); return queue; } m_mutex.lock(); m_bucket %= bucketNum; CMsgQueueHMap::CBucket* map = m_queues.bucket(m_bucket); for (UINT4 i = 0; i < bucketNum+1; ++i) { if (!map->empty() && (m_pos < map->size())) { CMsgQueueHMap::CBucket::iterator it = map->begin(); if (m_pos > 0) advance(it, m_pos); while (it != map->end()) { if (it->second.isNull() || it->second->empty() || it->second->isBusy()) { ++ it; ++ m_pos; } else { it->second->setBusy(TRUE); queue = it->second; ++ m_pos; break; } } } if (queue.isNotNull()) { break; } else { m_pos = 0; ++ m_bucket; m_bucket %= bucketNum; map = m_queues.bucket(m_bucket); } } m_mutex.unlock(); //m_rwlock.unlock(); #elif defined(USING_LF_HASH_MAP) UINT4 size = m_queues.size(); if (size <= 0) return queue; m_mutex.lock(); m_pos %= size; CMsgQueueLFHMap::CIterator it = m_queues.begin(); if (m_pos > 0) advance(it, m_pos); for (UINT4 i = 0; i < size; i++) { if (it->second.isNull() || it->second->empty() || it->second->isBusy()) { ++ m_pos; if (++it == m_queues.end()) { it = m_queues.begin(); m_pos = 0; } } else { it->second->setBusy(TRUE); queue = it->second; ++ m_pos; break; } } m_mutex.unlock(); #elif defined(USING_LK_HASH_MAP) UINT4 size = m_queues.size(); if (size <= 0) return queue; m_mutex.lock(); m_pos %= size; CMsgQueueLKHMap::CReferenceIterator it = m_queues.begin(); if (m_pos > 0) advance(it, m_pos); for (UINT4 i = 0; i <= size; i++) { CMsgKey key = it->first; CSmartPtr<CMsgQueue> que = it->second; #if defined(POP_LOCK_GRANULARITY_LARGE) || defined(POP_LOCK_GRANULARITY_LITTLE) UINT4 index = m_queues.bucketIndex(key); //m_queues.bucketLock(index); if (m_queues.bucketTrylock(index) != 0) { ++ it; ++ m_pos; continue; } #endif if (que.isNull() || que->empty()) { it++; #if defined(POP_LOCK_GRANULARITY_LARGE) || defined(POP_LOCK_GRANULARITY_LITTLE) deleteQueue(key); m_queues.bucketUnlock(index); #else ++ m_pos; #endif } else if (que->isBusy()) { ++ it; #if defined(POP_LOCK_GRANULARITY_LARGE) || defined(POP_LOCK_GRANULARITY_LITTLE) m_queues.bucketUnlock(index); #endif ++ m_pos; } else { que->setBusy(TRUE); #if defined(POP_LOCK_GRANULARITY_LARGE) || defined(POP_LOCK_GRANULARITY_LITTLE) m_queues.bucketUnlock(index); #endif queue = que; ++ m_pos; break; } if (it == m_queues.end()) { it = m_queues.begin(); m_pos = 0; } } m_mutex.unlock(); #endif LOG_INFO_FMT("%s[%p] after pop msg queue, path[%s] has queue count[%lu] ...", m_operator->toString(), m_operator, m_path.c_str(), m_queues.size()); return queue; }
// // Check the buffer chain, starting at cursor to see if it matches the pattern. // If the pattern matches, check the next tag to see if it's in the set of expected // tags. If not, return zero. If so, set the location descriptor to the good // tag and advance the cursor (and buffer, if needed) to the end of the matched section. // // If there is no match, don't advance the cursor. // // Return 0 if the pattern matches but the following tag is unexpected // Return 0 if the pattern matches and the location already has a pointer (duplicate section) // Return 1 if the pattern matches and we've advanced the cursor/buffer // Return 1 if the pattern does not match // static int qd_check_and_advance(qd_buffer_t **buffer, unsigned char **cursor, const unsigned char *pattern, int pattern_length, const unsigned char *expected_tags, qd_field_location_t *location) { qd_buffer_t *test_buffer = *buffer; unsigned char *test_cursor = *cursor; if (!test_cursor) return 1; // no match unsigned char *end_of_buffer = qd_buffer_base(test_buffer) + qd_buffer_size(test_buffer); int idx = 0; while (idx < pattern_length && *test_cursor == pattern[idx]) { idx++; test_cursor++; if (test_cursor == end_of_buffer) { test_buffer = test_buffer->next; if (test_buffer == 0) return 1; // Pattern didn't match test_cursor = qd_buffer_base(test_buffer); end_of_buffer = test_cursor + qd_buffer_size(test_buffer); } } if (idx < pattern_length) return 1; // Pattern didn't match // // Pattern matched, check the tag // while (*expected_tags && *test_cursor != *expected_tags) expected_tags++; if (*expected_tags == 0) return 0; // Unexpected tag if (location->parsed) return 0; // Duplicate section // // Pattern matched and tag is expected. Mark the beginning of the section. // location->parsed = 1; location->buffer = *buffer; location->offset = *cursor - qd_buffer_base(*buffer); location->length = 0; location->hdr_length = pattern_length; // // Advance the pointers to consume the whole section. // int pre_consume = 1; // Count the already extracted tag int consume = 0; unsigned char tag = next_octet(&test_cursor, &test_buffer); if (!test_cursor) return 0; switch (tag) { case 0x45 : // list0 break; case 0xd0 : // list32 case 0xd1 : // map32 case 0xb0 : // vbin32 pre_consume += 3; consume |= ((int) next_octet(&test_cursor, &test_buffer)) << 24; if (!test_cursor) return 0; consume |= ((int) next_octet(&test_cursor, &test_buffer)) << 16; if (!test_cursor) return 0; consume |= ((int) next_octet(&test_cursor, &test_buffer)) << 8; if (!test_cursor) return 0; // Fall through to the next case... case 0xc0 : // list8 case 0xc1 : // map8 case 0xa0 : // vbin8 pre_consume += 1; consume |= (int) next_octet(&test_cursor, &test_buffer); if (!test_cursor) return 0; break; } location->length = pre_consume + consume; if (consume) advance(&test_cursor, &test_buffer, consume, 0, 0); *cursor = test_cursor; *buffer = test_buffer; return 1; }
_clState *initCl(unsigned int gpu, char *name, size_t nameSize) { _clState *clState = (_clState *)calloc(1, sizeof(_clState)); bool patchbfi = false, prog_built = false; struct cgpu_info *cgpu = &gpus[gpu]; cl_platform_id platform = NULL; char pbuff[256], vbuff[255]; cl_platform_id* platforms; cl_uint preferred_vwidth; cl_device_id *devices; cl_uint numPlatforms; cl_uint numDevices; cl_int status; status = clGetPlatformIDs(0, NULL, &numPlatforms); if (status != CL_SUCCESS) { applog(LOG_ERR, "Error %d: Getting Platforms. (clGetPlatformsIDs)", status); return NULL; } platforms = (cl_platform_id *)alloca(numPlatforms*sizeof(cl_platform_id)); status = clGetPlatformIDs(numPlatforms, platforms, NULL); if (status != CL_SUCCESS) { applog(LOG_ERR, "Error %d: Getting Platform Ids. (clGetPlatformsIDs)", status); return NULL; } if (opt_platform_id >= (int)numPlatforms) { applog(LOG_ERR, "Specified platform that does not exist"); return NULL; } status = clGetPlatformInfo(platforms[opt_platform_id], CL_PLATFORM_VENDOR, sizeof(pbuff), pbuff, NULL); if (status != CL_SUCCESS) { applog(LOG_ERR, "Error %d: Getting Platform Info. (clGetPlatformInfo)", status); return NULL; } platform = platforms[opt_platform_id]; if (platform == NULL) { perror("NULL platform found!\n"); return NULL; } applog(LOG_INFO, "CL Platform vendor: %s", pbuff); status = clGetPlatformInfo(platform, CL_PLATFORM_NAME, sizeof(pbuff), pbuff, NULL); if (status == CL_SUCCESS) applog(LOG_INFO, "CL Platform name: %s", pbuff); status = clGetPlatformInfo(platform, CL_PLATFORM_VERSION, sizeof(vbuff), vbuff, NULL); if (status == CL_SUCCESS) applog(LOG_INFO, "CL Platform version: %s", vbuff); status = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 0, NULL, &numDevices); if (status != CL_SUCCESS) { applog(LOG_ERR, "Error %d: Getting Device IDs (num)", status); return NULL; } if (numDevices > 0 ) { devices = (cl_device_id *)malloc(numDevices*sizeof(cl_device_id)); /* Now, get the device list data */ status = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, numDevices, devices, NULL); if (status != CL_SUCCESS) { applog(LOG_ERR, "Error %d: Getting Device IDs (list)", status); return NULL; } applog(LOG_INFO, "List of devices:"); unsigned int i; for (i = 0; i < numDevices; i++) { status = clGetDeviceInfo(devices[i], CL_DEVICE_NAME, sizeof(pbuff), pbuff, NULL); if (status != CL_SUCCESS) { applog(LOG_ERR, "Error %d: Getting Device Info", status); return NULL; } applog(LOG_INFO, "\t%i\t%s", i, pbuff); } if (gpu < numDevices) { status = clGetDeviceInfo(devices[gpu], CL_DEVICE_NAME, sizeof(pbuff), pbuff, NULL); if (status != CL_SUCCESS) { applog(LOG_ERR, "Error %d: Getting Device Info", status); return NULL; } applog(LOG_INFO, "Selected %i: %s", gpu, pbuff); strncpy(name, pbuff, nameSize); } else { applog(LOG_ERR, "Invalid GPU %i", gpu); return NULL; } } else return NULL; cl_context_properties cps[3] = { CL_CONTEXT_PLATFORM, (cl_context_properties)platform, 0 }; clState->context = clCreateContextFromType(cps, CL_DEVICE_TYPE_GPU, NULL, NULL, &status); if (status != CL_SUCCESS) { applog(LOG_ERR, "Error %d: Creating Context. (clCreateContextFromType)", status); return NULL; } ///////////////////////////////////////////////////////////////// // Create an OpenCL command queue ///////////////////////////////////////////////////////////////// clState->commandQueue = clCreateCommandQueue(clState->context, devices[gpu], CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE, &status); if (status != CL_SUCCESS) /* Try again without OOE enable */ clState->commandQueue = clCreateCommandQueue(clState->context, devices[gpu], 0 , &status); if (status != CL_SUCCESS) { applog(LOG_ERR, "Error %d: Creating Command Queue. (clCreateCommandQueue)", status); return NULL; } /* Check for BFI INT support. Hopefully people don't mix devices with * and without it! */ char * extensions = (char *)malloc(1024); const char * camo = "cl_amd_media_ops"; char *find; status = clGetDeviceInfo(devices[gpu], CL_DEVICE_EXTENSIONS, 1024, (void *)extensions, NULL); if (status != CL_SUCCESS) { applog(LOG_ERR, "Error %d: Failed to clGetDeviceInfo when trying to get CL_DEVICE_EXTENSIONS", status); return NULL; } find = strstr(extensions, camo); if (find) clState->hasBitAlign = true; /* Check for OpenCL >= 1.0 support, needed for global offset parameter usage. */ char * devoclver = (char *)malloc(1024); const char * ocl10 = "OpenCL 1.0"; const char * ocl11 = "OpenCL 1.1"; status = clGetDeviceInfo(devices[gpu], CL_DEVICE_VERSION, 1024, (void *)devoclver, NULL); if (status != CL_SUCCESS) { applog(LOG_ERR, "Error %d: Failed to clGetDeviceInfo when trying to get CL_DEVICE_VERSION", status); return NULL; } find = strstr(devoclver, ocl10); if (!find) { clState->hasOpenCL11plus = true; find = strstr(devoclver, ocl11); if (!find) clState->hasOpenCL12plus = true; } status = clGetDeviceInfo(devices[gpu], CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT, sizeof(cl_uint), (void *)&preferred_vwidth, NULL); if (status != CL_SUCCESS) { applog(LOG_ERR, "Error %d: Failed to clGetDeviceInfo when trying to get CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT", status); return NULL; } applog(LOG_DEBUG, "Preferred vector width reported %d", preferred_vwidth); status = clGetDeviceInfo(devices[gpu], CL_DEVICE_MAX_WORK_GROUP_SIZE, sizeof(size_t), (void *)&clState->max_work_size, NULL); if (status != CL_SUCCESS) { applog(LOG_ERR, "Error %d: Failed to clGetDeviceInfo when trying to get CL_DEVICE_MAX_WORK_GROUP_SIZE", status); return NULL; } applog(LOG_DEBUG, "Max work group size reported %d", (int)(clState->max_work_size)); size_t compute_units = 0; status = clGetDeviceInfo(devices[gpu], CL_DEVICE_MAX_COMPUTE_UNITS, sizeof(size_t), (void *)&compute_units, NULL); if (status != CL_SUCCESS) { applog(LOG_ERR, "Error %d: Failed to clGetDeviceInfo when trying to get CL_DEVICE_MAX_COMPUTE_UNITS", status); return NULL; } // AMD architechture got 64 compute shaders per compute unit. // Source: http://www.amd.com/us/Documents/GCN_Architecture_whitepaper.pdf clState->compute_shaders = compute_units * 64; applog(LOG_DEBUG, "Max shaders calculated %d", (int)(clState->compute_shaders)); status = clGetDeviceInfo(devices[gpu], CL_DEVICE_MAX_MEM_ALLOC_SIZE , sizeof(cl_ulong), (void *)&cgpu->max_alloc, NULL); if (status != CL_SUCCESS) { applog(LOG_ERR, "Error %d: Failed to clGetDeviceInfo when trying to get CL_DEVICE_MAX_MEM_ALLOC_SIZE", status); return NULL; } applog(LOG_DEBUG, "Max mem alloc size is %lu", (long unsigned int)(cgpu->max_alloc)); /* Create binary filename based on parameters passed to opencl * compiler to ensure we only load a binary that matches what * would have otherwise created. The filename is: * name + kernelname + g + lg + lookup_gap + tc + thread_concurrency + nf + nfactor + w + work_size + l + sizeof(long) + .bin */ char binaryfilename[255]; char filename[255]; char strbuf[32]; if (cgpu->kernelname == NULL) { applog(LOG_INFO, "No kernel specified, defaulting to ckolivas"); cgpu->kernelname = strdup("ckolivas"); } if (strcmp(cgpu->kernelname, ALEXKARNEW_KERNNAME) == 0){ applog(LOG_WARNING, "Kernel alexkarnew is experimental."); strcpy(filename, ALEXKARNEW_KERNNAME".cl"); strcpy(binaryfilename, ALEXKARNEW_KERNNAME); } else if (strcmp(cgpu->kernelname, ALEXKAROLD_KERNNAME) == 0){ applog(LOG_WARNING, "Kernel alexkarold is experimental."); strcpy(filename, ALEXKAROLD_KERNNAME".cl"); strcpy(binaryfilename, ALEXKAROLD_KERNNAME); } else if (strcmp(cgpu->kernelname, CKOLIVAS_KERNNAME) == 0){ strcpy(filename, CKOLIVAS_KERNNAME".cl"); strcpy(binaryfilename, CKOLIVAS_KERNNAME); } else if (strcmp(cgpu->kernelname, PSW_KERNNAME) == 0){ applog(LOG_WARNING, "Kernel psw is experimental."); strcpy(filename, PSW_KERNNAME".cl"); strcpy(binaryfilename, PSW_KERNNAME); } else if (strcmp(cgpu->kernelname, ZUIKKIS_KERNNAME) == 0){ applog(LOG_WARNING, "Kernel zuikkis is experimental."); strcpy(filename, ZUIKKIS_KERNNAME".cl"); strcpy(binaryfilename, ZUIKKIS_KERNNAME); /* Kernel only supports worksize 256 */ cgpu->work_size = 256; } else if (strcmp(cgpu->kernelname, DARKCOIN_KERNNAME) == 0){ applog(LOG_WARNING, "Kernel darkcoin is experimental."); strcpy(filename, DARKCOIN_KERNNAME".cl"); strcpy(binaryfilename, DARKCOIN_KERNNAME); } else if (strcmp(cgpu->kernelname, QUBITCOIN_KERNNAME) == 0){ applog(LOG_WARNING, "Kernel qubitcoin is experimental."); strcpy(filename, QUBITCOIN_KERNNAME".cl"); strcpy(binaryfilename, QUBITCOIN_KERNNAME); } else if (strcmp(cgpu->kernelname, QUARKCOIN_KERNNAME) == 0){ applog(LOG_WARNING, "Kernel quarkcoin is experimental."); strcpy(filename, QUARKCOIN_KERNNAME".cl"); strcpy(binaryfilename, QUARKCOIN_KERNNAME); } else if (strcmp(cgpu->kernelname, FUGUECOIN_KERNNAME) == 0){ applog(LOG_WARNING, "Kernel fuguecoin is experimental."); strcpy(filename, FUGUECOIN_KERNNAME".cl"); strcpy(binaryfilename, FUGUECOIN_KERNNAME); } else if (strcmp(cgpu->kernelname, INKCOIN_KERNNAME) == 0){ applog(LOG_WARNING, "Kernel inkcoin is experimental."); strcpy(filename, INKCOIN_KERNNAME".cl"); strcpy(binaryfilename, INKCOIN_KERNNAME); } else if (strcmp(cgpu->kernelname, ANIMECOIN_KERNNAME) == 0){ applog(LOG_WARNING, "Kernel animecoin is experimental."); strcpy(filename, ANIMECOIN_KERNNAME".cl"); strcpy(binaryfilename, ANIMECOIN_KERNNAME); } else if (strcmp(cgpu->kernelname, GROESTLCOIN_KERNNAME) == 0){ applog(LOG_WARNING, "Kernel groestlcoin is experimental."); strcpy(filename, GROESTLCOIN_KERNNAME".cl"); strcpy(binaryfilename, GROESTLCOIN_KERNNAME); } else if (strcmp(cgpu->kernelname, SIFCOIN_KERNNAME) == 0){ applog(LOG_WARNING, "Kernel groestlcoin is experimental."); strcpy(filename, SIFCOIN_KERNNAME".cl"); strcpy(binaryfilename, SIFCOIN_KERNNAME); } else if (strcmp(cgpu->kernelname, MYRIADCOIN_GROESTL_KERNNAME) == 0){ applog(LOG_WARNING, "Kernel myriadcoin-groestl is experimental."); strcpy(filename, MYRIADCOIN_GROESTL_KERNNAME".cl"); strcpy(binaryfilename, MYRIADCOIN_GROESTL_KERNNAME); } else if (strcmp(cgpu->kernelname, MYRIADCOIN_SKEIN_KERNNAME) == 0){ applog(LOG_WARNING, "Kernel myriadcoin-skein is experimental."); strcpy(filename, MYRIADCOIN_SKEIN_KERNNAME".cl"); strcpy(binaryfilename, MYRIADCOIN_SKEIN_KERNNAME); } else if (strcmp(cgpu->kernelname, MYRIADCOIN_QUBIT_KERNNAME) == 0){ applog(LOG_WARNING, "Kernel myriadcoin-qubit is experimental."); strcpy(filename, MYRIADCOIN_QUBIT_KERNNAME".cl"); strcpy(binaryfilename, MYRIADCOIN_QUBIT_KERNNAME); } else { applog(LOG_WARNING, "Kernel was not chosen."); } /* For some reason 2 vectors is still better even if the card says * otherwise, and many cards lie about their max so use 256 as max * unless explicitly set on the command line. Tahiti prefers 1 */ if (strstr(name, "Tahiti")) preferred_vwidth = 1; else if (preferred_vwidth > 2) preferred_vwidth = 2; /* All available kernels only support vector 1 */ cgpu->vwidth = 1; /* Vectors are hard-set to 1 above. */ if (likely(cgpu->vwidth)) clState->vwidth = cgpu->vwidth; else { clState->vwidth = preferred_vwidth; cgpu->vwidth = preferred_vwidth; } clState->goffset = true; if (cgpu->work_size && cgpu->work_size <= clState->max_work_size) clState->wsize = cgpu->work_size; else clState->wsize = 256; if (!cgpu->opt_lg) { applog(LOG_DEBUG, "GPU %d: selecting lookup gap of 2", gpu); cgpu->lookup_gap = 2; } else cgpu->lookup_gap = cgpu->opt_lg; if ((strcmp(cgpu->kernelname, "zuikkis") == 0) && (cgpu->lookup_gap != 2)) { applog(LOG_WARNING, "Kernel zuikkis only supports lookup-gap = 2 (currently %d), forcing.", cgpu->lookup_gap); cgpu->lookup_gap = 2; } if (!cgpu->opt_tc) { unsigned int sixtyfours; sixtyfours = cgpu->max_alloc / 131072 / 64 / (algorithm->n/1024) - 1; cgpu->thread_concurrency = sixtyfours * 64; if (cgpu->shaders && cgpu->thread_concurrency > cgpu->shaders) { cgpu->thread_concurrency -= cgpu->thread_concurrency % cgpu->shaders; if (cgpu->thread_concurrency > cgpu->shaders * 5) cgpu->thread_concurrency = cgpu->shaders * 5; } applog(LOG_DEBUG, "GPU %d: selecting thread concurrency of %d", gpu, (int)(cgpu->thread_concurrency)); } else cgpu->thread_concurrency = cgpu->opt_tc; FILE *binaryfile; size_t *binary_sizes; char **binaries; int pl; char *source = file_contents(filename, &pl); size_t sourceSize[] = {(size_t)pl}; cl_uint slot, cpnd; slot = cpnd = 0; if (!source) return NULL; binary_sizes = (size_t *)calloc(sizeof(size_t) * MAX_GPUDEVICES * 4, 1); if (unlikely(!binary_sizes)) { applog(LOG_ERR, "Unable to calloc binary_sizes"); return NULL; } binaries = (char **)calloc(sizeof(char *) * MAX_GPUDEVICES * 4, 1); if (unlikely(!binaries)) { applog(LOG_ERR, "Unable to calloc binaries"); return NULL; } strcat(binaryfilename, name); if (clState->goffset) strcat(binaryfilename, "g"); sprintf(strbuf, "lg%utc%unf%u", cgpu->lookup_gap, (unsigned int)cgpu->thread_concurrency, algorithm->nfactor); strcat(binaryfilename, strbuf); sprintf(strbuf, "w%d", (int)clState->wsize); strcat(binaryfilename, strbuf); sprintf(strbuf, "l%d", (int)sizeof(long)); strcat(binaryfilename, strbuf); strcat(binaryfilename, ".bin"); binaryfile = fopen(binaryfilename, "rb"); if (!binaryfile) { applog(LOG_DEBUG, "No binary found, generating from source"); } else { struct stat binary_stat; if (unlikely(stat(binaryfilename, &binary_stat))) { applog(LOG_DEBUG, "Unable to stat binary, generating from source"); fclose(binaryfile); goto build; } if (!binary_stat.st_size) goto build; binary_sizes[slot] = binary_stat.st_size; binaries[slot] = (char *)calloc(binary_sizes[slot], 1); if (unlikely(!binaries[slot])) { applog(LOG_ERR, "Unable to calloc binaries"); fclose(binaryfile); return NULL; } if (fread(binaries[slot], 1, binary_sizes[slot], binaryfile) != binary_sizes[slot]) { applog(LOG_ERR, "Unable to fread binaries"); fclose(binaryfile); free(binaries[slot]); goto build; } clState->program = clCreateProgramWithBinary(clState->context, 1, &devices[gpu], &binary_sizes[slot], (const unsigned char **)binaries, &status, NULL); if (status != CL_SUCCESS) { applog(LOG_ERR, "Error %d: Loading Binary into cl_program (clCreateProgramWithBinary)", status); fclose(binaryfile); free(binaries[slot]); goto build; } fclose(binaryfile); applog(LOG_DEBUG, "Loaded binary image %s", binaryfilename); goto built; } ///////////////////////////////////////////////////////////////// // Load CL file, build CL program object, create CL kernel object ///////////////////////////////////////////////////////////////// build: applog(LOG_NOTICE, "Building binary %s", binaryfilename); clState->program = clCreateProgramWithSource(clState->context, 1, (const char **)&source, sourceSize, &status); if (status != CL_SUCCESS) { applog(LOG_ERR, "Error %d: Loading Binary into cl_program (clCreateProgramWithSource)", status); return NULL; } /* create a cl program executable for all the devices specified */ char *CompilerOptions = (char *)calloc(1, 256); sprintf(CompilerOptions, "-I \"%s\" -I \"%s\" -I \"%skernel\" -I \".\" -D LOOKUP_GAP=%d -D CONCURRENT_THREADS=%d -D WORKSIZE=%d -D NFACTOR=%d", opt_kernel_path, sgminer_path, sgminer_path, cgpu->lookup_gap, (unsigned int)cgpu->thread_concurrency, (int)clState->wsize, (unsigned int)algorithm->nfactor); applog(LOG_DEBUG, "Setting worksize to %d", (int)(clState->wsize)); if (clState->vwidth > 1) applog(LOG_DEBUG, "Patched source to suit %d vectors", clState->vwidth); if (clState->hasBitAlign) { strcat(CompilerOptions, " -D BITALIGN"); applog(LOG_DEBUG, "cl_amd_media_ops found, setting BITALIGN"); if (!clState->hasOpenCL12plus && (strstr(name, "Cedar") || strstr(name, "Redwood") || strstr(name, "Juniper") || strstr(name, "Cypress" ) || strstr(name, "Hemlock" ) || strstr(name, "Caicos" ) || strstr(name, "Turks" ) || strstr(name, "Barts" ) || strstr(name, "Cayman" ) || strstr(name, "Antilles" ) || strstr(name, "Wrestler" ) || strstr(name, "Zacate" ) || strstr(name, "WinterPark" ))) patchbfi = true; } else applog(LOG_DEBUG, "cl_amd_media_ops not found, will not set BITALIGN"); if (patchbfi) { strcat(CompilerOptions, " -D BFI_INT"); applog(LOG_DEBUG, "BFI_INT patch requiring device found, patched source with BFI_INT"); } else applog(LOG_DEBUG, "BFI_INT patch requiring device not found, will not BFI_INT patch"); if (clState->goffset) strcat(CompilerOptions, " -D GOFFSET"); if (!clState->hasOpenCL11plus) strcat(CompilerOptions, " -D OCL1"); applog(LOG_DEBUG, "CompilerOptions: %s", CompilerOptions); status = clBuildProgram(clState->program, 1, &devices[gpu], CompilerOptions , NULL, NULL); free(CompilerOptions); if (status != CL_SUCCESS) { applog(LOG_ERR, "Error %d: Building Program (clBuildProgram)", status); size_t logSize; status = clGetProgramBuildInfo(clState->program, devices[gpu], CL_PROGRAM_BUILD_LOG, 0, NULL, &logSize); char *log = (char *)malloc(logSize); status = clGetProgramBuildInfo(clState->program, devices[gpu], CL_PROGRAM_BUILD_LOG, logSize, log, NULL); applog(LOG_ERR, "%s", log); return NULL; } prog_built = true; #ifdef __APPLE__ /* OSX OpenCL breaks reading off binaries with >1 GPU so always build * from source. */ goto built; #endif status = clGetProgramInfo(clState->program, CL_PROGRAM_NUM_DEVICES, sizeof(cl_uint), &cpnd, NULL); if (unlikely(status != CL_SUCCESS)) { applog(LOG_ERR, "Error %d: Getting program info CL_PROGRAM_NUM_DEVICES. (clGetProgramInfo)", status); return NULL; } status = clGetProgramInfo(clState->program, CL_PROGRAM_BINARY_SIZES, sizeof(size_t)*cpnd, binary_sizes, NULL); if (unlikely(status != CL_SUCCESS)) { applog(LOG_ERR, "Error %d: Getting program info CL_PROGRAM_BINARY_SIZES. (clGetProgramInfo)", status); return NULL; } /* The actual compiled binary ends up in a RANDOM slot! Grr, so we have * to iterate over all the binary slots and find where the real program * is. What the heck is this!? */ for (slot = 0; slot < cpnd; slot++) if (binary_sizes[slot]) break; /* copy over all of the generated binaries. */ applog(LOG_DEBUG, "Binary size for gpu %d found in binary slot %d: %d", gpu, slot, (int)(binary_sizes[slot])); if (!binary_sizes[slot]) { applog(LOG_ERR, "OpenCL compiler generated a zero sized binary, FAIL!"); return NULL; } binaries[slot] = (char *)calloc(sizeof(char)* binary_sizes[slot], 1); status = clGetProgramInfo(clState->program, CL_PROGRAM_BINARIES, sizeof(char *) * cpnd, binaries, NULL ); if (unlikely(status != CL_SUCCESS)) { applog(LOG_ERR, "Error %d: Getting program info. CL_PROGRAM_BINARIES (clGetProgramInfo)", status); return NULL; } /* Patch the kernel if the hardware supports BFI_INT but it needs to * be hacked in */ if (patchbfi) { unsigned remaining = binary_sizes[slot]; char *w = binaries[slot]; unsigned int start, length; /* Find 2nd incidence of .text, and copy the program's * position and length at a fixed offset from that. Then go * back and find the 2nd incidence of \x7ELF (rewind by one * from ELF) and then patch the opcocdes */ if (!advance(&w, &remaining, ".text")) goto build; w++; remaining--; if (!advance(&w, &remaining, ".text")) { /* 32 bit builds only one ELF */ w--; remaining++; } memcpy(&start, w + 285, 4); memcpy(&length, w + 289, 4); w = binaries[slot]; remaining = binary_sizes[slot]; if (!advance(&w, &remaining, "ELF")) goto build; w++; remaining--; if (!advance(&w, &remaining, "ELF")) { /* 32 bit builds only one ELF */ w--; remaining++; } w--; remaining++; w += start; remaining -= start; applog(LOG_DEBUG, "At %p (%u rem. bytes), to begin patching", w, remaining); patch_opcodes(w, length); status = clReleaseProgram(clState->program); if (status != CL_SUCCESS) { applog(LOG_ERR, "Error %d: Releasing program. (clReleaseProgram)", status); return NULL; } clState->program = clCreateProgramWithBinary(clState->context, 1, &devices[gpu], &binary_sizes[slot], (const unsigned char **)&binaries[slot], &status, NULL); if (status != CL_SUCCESS) { applog(LOG_ERR, "Error %d: Loading Binary into cl_program (clCreateProgramWithBinary)", status); return NULL; } /* Program needs to be rebuilt */ prog_built = false; } free(source); /* Save the binary to be loaded next time */ binaryfile = fopen(binaryfilename, "wb"); if (!binaryfile) { /* Not fatal, just means we build it again next time */ applog(LOG_DEBUG, "Unable to create file %s", binaryfilename); } else { if (unlikely(fwrite(binaries[slot], 1, binary_sizes[slot], binaryfile) != binary_sizes[slot])) { applog(LOG_ERR, "Unable to fwrite to binaryfile"); return NULL; } fclose(binaryfile); } built: if (binaries[slot]) free(binaries[slot]); free(binaries); free(binary_sizes); applog(LOG_NOTICE, "Initialising kernel %s with%s bitalign, %spatched BFI", filename, clState->hasBitAlign ? "" : "out", patchbfi ? "" : "un"); if (!prog_built) { /* create a cl program executable for all the devices specified */ status = clBuildProgram(clState->program, 1, &devices[gpu], NULL, NULL, NULL); if (status != CL_SUCCESS) { applog(LOG_ERR, "Error %d: Building Program (clBuildProgram)", status); size_t logSize; status = clGetProgramBuildInfo(clState->program, devices[gpu], CL_PROGRAM_BUILD_LOG, 0, NULL, &logSize); char *log = (char *)malloc(logSize); status = clGetProgramBuildInfo(clState->program, devices[gpu], CL_PROGRAM_BUILD_LOG, logSize, log, NULL); applog(LOG_ERR, "%s", log); return NULL; } } /* get a kernel object handle for a kernel with the given name */ clState->kernel = clCreateKernel(clState->program, "search", &status); if (status != CL_SUCCESS) { applog(LOG_ERR, "Error %d: Creating Kernel from program. (clCreateKernel)", status); return NULL; } size_t ipt = (algorithm->n / cgpu->lookup_gap + (algorithm->n % cgpu->lookup_gap > 0)); size_t bufsize = 128 * ipt * cgpu->thread_concurrency; /* Use the max alloc value which has been rounded to a power of * 2 greater >= required amount earlier */ if (bufsize > cgpu->max_alloc) { applog(LOG_WARNING, "Maximum buffer memory device %d supports says %lu", gpu, (unsigned long)(cgpu->max_alloc)); applog(LOG_WARNING, "Your scrypt settings come to %lu", (unsigned long)bufsize); } applog(LOG_DEBUG, "Creating scrypt buffer sized %lu", (unsigned long)bufsize); clState->padbufsize = bufsize; /* This buffer is weird and might work to some degree even if * the create buffer call has apparently failed, so check if we * get anything back before we call it a failure. */ clState->padbuffer8 = NULL; clState->padbuffer8 = clCreateBuffer(clState->context, CL_MEM_READ_WRITE, bufsize, NULL, &status); if (status != CL_SUCCESS && !clState->padbuffer8) { applog(LOG_ERR, "Error %d: clCreateBuffer (padbuffer8), decrease TC or increase LG", status); return NULL; } clState->CLbuffer0 = clCreateBuffer(clState->context, CL_MEM_READ_ONLY, 128, NULL, &status); if (status != CL_SUCCESS) { applog(LOG_ERR, "Error %d: clCreateBuffer (CLbuffer0)", status); return NULL; } clState->outputBuffer = clCreateBuffer(clState->context, CL_MEM_WRITE_ONLY, BUFFERSIZE, NULL, &status); if (status != CL_SUCCESS) { applog(LOG_ERR, "Error %d: clCreateBuffer (outputBuffer)", status); return NULL; } return clState; }
void qd_message_send(qd_message_t *in_msg, qd_link_t *link, bool strip_annotations) { qd_message_pvt_t *msg = (qd_message_pvt_t*) in_msg; qd_message_content_t *content = msg->content; qd_buffer_t *buf = DEQ_HEAD(content->buffers); unsigned char *cursor; pn_link_t *pnl = qd_link_pn(link); char repr[qd_message_repr_len()]; qd_log(log_source, QD_LOG_TRACE, "Sending %s on link %s", qd_message_repr(in_msg, repr, sizeof(repr)), pn_link_name(pnl)); qd_buffer_list_t new_ma; DEQ_INIT(new_ma); if (strip_annotations || compose_message_annotations(msg, &new_ma)) { // // This is the case where the message annotations have been modified. // The message send must be divided into sections: The existing header; // the new message annotations; the rest of the existing message. // Note that the original message annotations that are still in the // buffer chain must not be sent. // // Start by making sure that we've parsed the message sections through // the message annotations // // ??? NO LONGER NECESSARY??? if (!qd_message_check(in_msg, QD_DEPTH_MESSAGE_ANNOTATIONS)) { qd_log(log_source, QD_LOG_ERROR, "Cannot send: %s", qd_error_message); return; } // // Send header if present // cursor = qd_buffer_base(buf); if (content->section_message_header.length > 0) { buf = content->section_message_header.buffer; cursor = content->section_message_header.offset + qd_buffer_base(buf); advance(&cursor, &buf, content->section_message_header.length + content->section_message_header.hdr_length, send_handler, (void*) pnl); } // // Send new message annotations // qd_buffer_t *da_buf = DEQ_HEAD(new_ma); while (da_buf) { pn_link_send(pnl, (char*) qd_buffer_base(da_buf), qd_buffer_size(da_buf)); da_buf = DEQ_NEXT(da_buf); } qd_buffer_list_free_buffers(&new_ma); // // Skip over replaced message annotations // if (content->section_message_annotation.length > 0) advance(&cursor, &buf, content->section_message_annotation.hdr_length + content->section_message_annotation.length, 0, 0); // // Send remaining partial buffer // if (buf) { size_t len = qd_buffer_size(buf) - (cursor - qd_buffer_base(buf)); advance(&cursor, &buf, len, send_handler, (void*) pnl); } // Fall through to process the remaining buffers normally // Note that 'advance' will have moved us to the next buffer in the chain. } while (buf) { pn_link_send(pnl, (char*) qd_buffer_base(buf), qd_buffer_size(buf)); buf = DEQ_NEXT(buf); } }
_clState *initCl(unsigned int gpu, char *name, size_t nameSize) { _clState *clState = calloc(1, sizeof(_clState)); bool patchbfi = false, prog_built = false; struct cgpu_info *cgpu = &gpus[gpu]; cl_platform_id platform = NULL; char pbuff[256], vbuff[255]; cl_platform_id* platforms; cl_uint preferred_vwidth; cl_device_id *devices; cl_uint numPlatforms; cl_uint numDevices; cl_int status; status = clGetPlatformIDs(0, NULL, &numPlatforms); if (status != CL_SUCCESS) { applog(LOG_ERR, "Error %d: Getting Platforms. (clGetPlatformsIDs)", status); return NULL; } platforms = (cl_platform_id *)alloca(numPlatforms*sizeof(cl_platform_id)); status = clGetPlatformIDs(numPlatforms, platforms, NULL); if (status != CL_SUCCESS) { applog(LOG_ERR, "Error %d: Getting Platform Ids. (clGetPlatformsIDs)", status); return NULL; } if (opt_platform_id >= (int)numPlatforms) { applog(LOG_ERR, "Specified platform that does not exist"); return NULL; } status = clGetPlatformInfo(platforms[opt_platform_id], CL_PLATFORM_VENDOR, sizeof(pbuff), pbuff, NULL); if (status != CL_SUCCESS) { applog(LOG_ERR, "Error %d: Getting Platform Info. (clGetPlatformInfo)", status); return NULL; } platform = platforms[opt_platform_id]; if (platform == NULL) { perror("NULL platform found!\n"); return NULL; } applog(LOG_INFO, "CL Platform vendor: %s", pbuff); status = clGetPlatformInfo(platform, CL_PLATFORM_NAME, sizeof(pbuff), pbuff, NULL); if (status == CL_SUCCESS) applog(LOG_INFO, "CL Platform name: %s", pbuff); status = clGetPlatformInfo(platform, CL_PLATFORM_VERSION, sizeof(vbuff), vbuff, NULL); if (status == CL_SUCCESS) applog(LOG_INFO, "CL Platform version: %s", vbuff); status = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 0, NULL, &numDevices); if (status != CL_SUCCESS) { applog(LOG_ERR, "Error %d: Getting Device IDs (num)", status); return NULL; } if (numDevices > 0 ) { devices = (cl_device_id *)malloc(numDevices*sizeof(cl_device_id)); /* Now, get the device list data */ status = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, numDevices, devices, NULL); if (status != CL_SUCCESS) { applog(LOG_ERR, "Error %d: Getting Device IDs (list)", status); return NULL; } applog(LOG_INFO, "List of devices:"); unsigned int i; for (i = 0; i < numDevices; i++) { status = clGetDeviceInfo(devices[i], CL_DEVICE_NAME, sizeof(pbuff), pbuff, NULL); if (status != CL_SUCCESS) { applog(LOG_ERR, "Error %d: Getting Device Info", status); return NULL; } applog(LOG_INFO, "\t%i\t%s", i, pbuff); } if (gpu < numDevices) { status = clGetDeviceInfo(devices[gpu], CL_DEVICE_NAME, sizeof(pbuff), pbuff, NULL); if (status != CL_SUCCESS) { applog(LOG_ERR, "Error %d: Getting Device Info", status); return NULL; } applog(LOG_INFO, "Selected %i: %s", gpu, pbuff); strncpy(name, pbuff, nameSize); } else { applog(LOG_ERR, "Invalid GPU %i", gpu); return NULL; } } else return NULL; cl_context_properties cps[3] = { CL_CONTEXT_PLATFORM, (cl_context_properties)platform, 0 }; clState->context = clCreateContextFromType(cps, CL_DEVICE_TYPE_GPU, NULL, NULL, &status); if (status != CL_SUCCESS) { applog(LOG_ERR, "Error %d: Creating Context. (clCreateContextFromType)", status); return NULL; } ///////////////////////////////////////////////////////////////// // Create an OpenCL command queue ///////////////////////////////////////////////////////////////// clState->commandQueue = clCreateCommandQueue(clState->context, devices[gpu], CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE, &status); if (status != CL_SUCCESS) /* Try again without OOE enable */ clState->commandQueue = clCreateCommandQueue(clState->context, devices[gpu], 0 , &status); if (status != CL_SUCCESS) { applog(LOG_ERR, "Error %d: Creating Command Queue. (clCreateCommandQueue)", status); return NULL; } /* Check for BFI INT support. Hopefully people don't mix devices with * and without it! */ char * extensions = malloc(1024); const char * camo = "cl_amd_media_ops"; char *find; status = clGetDeviceInfo(devices[gpu], CL_DEVICE_EXTENSIONS, 1024, (void *)extensions, NULL); if (status != CL_SUCCESS) { applog(LOG_ERR, "Error %d: Failed to clGetDeviceInfo when trying to get CL_DEVICE_EXTENSIONS", status); return NULL; } find = strstr(extensions, camo); if (find) clState->hasBitAlign = true; /* Check for OpenCL >= 1.0 support, needed for global offset parameter usage. */ char * devoclver = malloc(1024); const char * ocl10 = "OpenCL 1.0"; status = clGetDeviceInfo(devices[gpu], CL_DEVICE_VERSION, 1024, (void *)devoclver, NULL); if (status != CL_SUCCESS) { applog(LOG_ERR, "Error %d: Failed to clGetDeviceInfo when trying to get CL_DEVICE_VERSION", status); return NULL; } find = strstr(devoclver, ocl10); if (!find) clState->hasOpenCL11plus = true; status = clGetDeviceInfo(devices[gpu], CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT, sizeof(cl_uint), (void *)&preferred_vwidth, NULL); if (status != CL_SUCCESS) { applog(LOG_ERR, "Error %d: Failed to clGetDeviceInfo when trying to get CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT", status); return NULL; } applog(LOG_DEBUG, "Preferred vector width reported %d", preferred_vwidth); status = clGetDeviceInfo(devices[gpu], CL_DEVICE_MAX_WORK_GROUP_SIZE, sizeof(size_t), (void *)&clState->max_work_size, NULL); if (status != CL_SUCCESS) { applog(LOG_ERR, "Error %d: Failed to clGetDeviceInfo when trying to get CL_DEVICE_MAX_WORK_GROUP_SIZE", status); return NULL; } applog(LOG_DEBUG, "Max work group size reported %d", clState->max_work_size); status = clGetDeviceInfo(devices[gpu], CL_DEVICE_MAX_MEM_ALLOC_SIZE , sizeof(cl_ulong), (void *)&cgpu->max_alloc, NULL); if (status != CL_SUCCESS) { applog(LOG_ERR, "Error %d: Failed to clGetDeviceInfo when trying to get CL_DEVICE_MAX_MEM_ALLOC_SIZE", status); return NULL; } applog(LOG_DEBUG, "Max mem alloc size is %u", cgpu->max_alloc); /* Create binary filename based on parameters passed to opencl * compiler to ensure we only load a binary that matches what would * have otherwise created. The filename is: * name + kernelname +/- g(offset) + v + vectors + w + work_size + l + sizeof(long) + .bin * For scrypt the filename is: * name + kernelname + g + lg + lookup_gap + tc + thread_concurrency + w + work_size + l + sizeof(long) + .bin */ char binaryfilename[255]; char filename[255]; char numbuf[16]; if (cgpu->kernel == KL_NONE) { if (opt_scrypt) { applog(LOG_INFO, "Selecting scrypt kernel"); clState->chosen_kernel = KL_SCRYPT; } else if (!strstr(name, "Tahiti") && /* Detect all 2.6 SDKs not with Tahiti and use diablo kernel */ (strstr(vbuff, "844.4") || // Linux 64 bit ATI 2.6 SDK strstr(vbuff, "851.4") || // Windows 64 bit "" strstr(vbuff, "831.4") || strstr(vbuff, "898.1") || // 12.2 driver SDK strstr(vbuff, "923.1") || // 12.4 strstr(vbuff, "938.2") || // SDK 2.7 strstr(vbuff, "1113.2"))) {// SDK 2.8 applog(LOG_INFO, "Selecting diablo kernel"); clState->chosen_kernel = KL_DIABLO; /* Detect all 7970s, older ATI and NVIDIA and use poclbm */ } else if (strstr(name, "Tahiti") || !clState->hasBitAlign) { applog(LOG_INFO, "Selecting poclbm kernel"); clState->chosen_kernel = KL_POCLBM; /* Use phatk for the rest R5xxx R6xxx */ } else { applog(LOG_INFO, "Selecting phatk kernel"); clState->chosen_kernel = KL_PHATK; } cgpu->kernel = clState->chosen_kernel; } else { clState->chosen_kernel = cgpu->kernel; if (clState->chosen_kernel == KL_PHATK && (strstr(vbuff, "844.4") || strstr(vbuff, "851.4") || strstr(vbuff, "831.4") || strstr(vbuff, "898.1") || strstr(vbuff, "923.1") || strstr(vbuff, "938.2") || strstr(vbuff, "1113.2"))) { applog(LOG_WARNING, "WARNING: You have selected the phatk kernel."); applog(LOG_WARNING, "You are running SDK 2.6+ which performs poorly with this kernel."); applog(LOG_WARNING, "Downgrade your SDK and delete any .bin files before starting again."); applog(LOG_WARNING, "Or allow cgminer to automatically choose a more suitable kernel."); } } /* For some reason 2 vectors is still better even if the card says * otherwise, and many cards lie about their max so use 256 as max * unless explicitly set on the command line. Tahiti prefers 1 */ if (strstr(name, "Tahiti")) preferred_vwidth = 1; else if (preferred_vwidth > 2) preferred_vwidth = 2; switch (clState->chosen_kernel) { case KL_POCLBM: strcpy(filename, POCLBM_KERNNAME".cl"); strcpy(binaryfilename, POCLBM_KERNNAME); break; case KL_PHATK: strcpy(filename, PHATK_KERNNAME".cl"); strcpy(binaryfilename, PHATK_KERNNAME); break; case KL_DIAKGCN: strcpy(filename, DIAKGCN_KERNNAME".cl"); strcpy(binaryfilename, DIAKGCN_KERNNAME); break; case KL_SCRYPT: strcpy(filename, SCRYPT_KERNNAME".cl"); strcpy(binaryfilename, SCRYPT_KERNNAME); /* Scrypt only supports vector 1 */ cgpu->vwidth = 1; break; case KL_NONE: /* Shouldn't happen */ case KL_DIABLO: strcpy(filename, DIABLO_KERNNAME".cl"); strcpy(binaryfilename, DIABLO_KERNNAME); break; } if (cgpu->vwidth) clState->vwidth = cgpu->vwidth; else { clState->vwidth = preferred_vwidth; cgpu->vwidth = preferred_vwidth; } if (((clState->chosen_kernel == KL_POCLBM || clState->chosen_kernel == KL_DIABLO || clState->chosen_kernel == KL_DIAKGCN) && clState->vwidth == 1 && clState->hasOpenCL11plus) || opt_scrypt) clState->goffset = true; if (cgpu->work_size && cgpu->work_size <= clState->max_work_size) clState->wsize = cgpu->work_size; else if (opt_scrypt) clState->wsize = 256; else if (strstr(name, "Tahiti")) clState->wsize = 64; else clState->wsize = (clState->max_work_size <= 256 ? clState->max_work_size : 256) / clState->vwidth; cgpu->work_size = clState->wsize; #ifdef USE_SCRYPT if (opt_scrypt) { if (!cgpu->opt_lg) { applog(LOG_DEBUG, "GPU %d: selecting lookup gap of 2", gpu); cgpu->lookup_gap = 2; } else cgpu->lookup_gap = cgpu->opt_lg; if (!cgpu->opt_tc) { unsigned int sixtyfours; sixtyfours = cgpu->max_alloc / 131072 / 64 - 1; cgpu->thread_concurrency = sixtyfours * 64; if (cgpu->shaders && cgpu->thread_concurrency > cgpu->shaders) { cgpu->thread_concurrency -= cgpu->thread_concurrency % cgpu->shaders; if (cgpu->thread_concurrency > cgpu->shaders * 5) cgpu->thread_concurrency = cgpu->shaders * 5; } applog(LOG_DEBUG, "GPU %d: selecting thread concurrency of %u",gpu, cgpu->thread_concurrency); } else cgpu->thread_concurrency = cgpu->opt_tc; } #endif FILE *binaryfile; size_t *binary_sizes; char **binaries; int pl; char *source = file_contents(filename, &pl); size_t sourceSize[] = {(size_t)pl}; cl_uint slot, cpnd; slot = cpnd = 0; if (!source) return NULL; binary_sizes = calloc(sizeof(size_t) * MAX_GPUDEVICES * 4, 1); if (unlikely(!binary_sizes)) { applog(LOG_ERR, "Unable to calloc binary_sizes"); return NULL; } binaries = calloc(sizeof(char *) * MAX_GPUDEVICES * 4, 1); if (unlikely(!binaries)) { applog(LOG_ERR, "Unable to calloc binaries"); return NULL; } strcat(binaryfilename, name); if (clState->goffset) strcat(binaryfilename, "g"); if (opt_scrypt) { #ifdef USE_SCRYPT sprintf(numbuf, "lg%utc%u", cgpu->lookup_gap, (unsigned int)cgpu->thread_concurrency); strcat(binaryfilename, numbuf); #endif } else { sprintf(numbuf, "v%d", clState->vwidth); strcat(binaryfilename, numbuf); } sprintf(numbuf, "w%d", (int)clState->wsize); strcat(binaryfilename, numbuf); sprintf(numbuf, "l%d", (int)sizeof(long)); strcat(binaryfilename, numbuf); strcat(binaryfilename, ".bin"); binaryfile = fopen(binaryfilename, "rb"); if (!binaryfile) { applog(LOG_DEBUG, "No binary found, generating from source"); } else { struct stat binary_stat; if (unlikely(stat(binaryfilename, &binary_stat))) { applog(LOG_DEBUG, "Unable to stat binary, generating from source"); fclose(binaryfile); goto build; } if (!binary_stat.st_size) goto build; binary_sizes[slot] = binary_stat.st_size; binaries[slot] = (char *)calloc(binary_sizes[slot], 1); if (unlikely(!binaries[slot])) { applog(LOG_ERR, "Unable to calloc binaries"); fclose(binaryfile); return NULL; } if (fread(binaries[slot], 1, binary_sizes[slot], binaryfile) != binary_sizes[slot]) { applog(LOG_ERR, "Unable to fread binaries"); fclose(binaryfile); free(binaries[slot]); goto build; } clState->program = clCreateProgramWithBinary(clState->context, 1, &devices[gpu], &binary_sizes[slot], (const unsigned char **)binaries, &status, NULL); if (status != CL_SUCCESS) { applog(LOG_ERR, "Error %d: Loading Binary into cl_program (clCreateProgramWithBinary)", status); fclose(binaryfile); free(binaries[slot]); goto build; } fclose(binaryfile); applog(LOG_DEBUG, "Loaded binary image %s", binaryfilename); goto built; } ///////////////////////////////////////////////////////////////// // Load CL file, build CL program object, create CL kernel object ///////////////////////////////////////////////////////////////// build: clState->program = clCreateProgramWithSource(clState->context, 1, (const char **)&source, sourceSize, &status); if (status != CL_SUCCESS) { applog(LOG_ERR, "Error %d: Loading Binary into cl_program (clCreateProgramWithSource)", status); return NULL; } /* create a cl program executable for all the devices specified */ char *CompilerOptions = calloc(1, 256); #ifdef USE_SCRYPT if (opt_scrypt) sprintf(CompilerOptions, "-D LOOKUP_GAP=%d -D CONCURRENT_THREADS=%d -D WORKSIZE=%d", cgpu->lookup_gap, (unsigned int)cgpu->thread_concurrency, (int)clState->wsize); else #endif { sprintf(CompilerOptions, "-D WORKSIZE=%d -D VECTORS%d -D WORKVEC=%d", (int)clState->wsize, clState->vwidth, (int)clState->wsize * clState->vwidth); } applog(LOG_DEBUG, "Setting worksize to %d", clState->wsize); if (clState->vwidth > 1) applog(LOG_DEBUG, "Patched source to suit %d vectors", clState->vwidth); if (clState->hasBitAlign) { strcat(CompilerOptions, " -D BITALIGN"); applog(LOG_DEBUG, "cl_amd_media_ops found, setting BITALIGN"); if (strstr(name, "Cedar") || strstr(name, "Redwood") || strstr(name, "Juniper") || strstr(name, "Cypress" ) || strstr(name, "Hemlock" ) || strstr(name, "Caicos" ) || strstr(name, "Turks" ) || strstr(name, "Barts" ) || strstr(name, "Cayman" ) || strstr(name, "Antilles" ) || strstr(name, "Wrestler" ) || strstr(name, "Zacate" ) || strstr(name, "WinterPark" )) patchbfi = true; } else applog(LOG_DEBUG, "cl_amd_media_ops not found, will not set BITALIGN"); if (patchbfi) { strcat(CompilerOptions, " -D BFI_INT"); applog(LOG_DEBUG, "BFI_INT patch requiring device found, patched source with BFI_INT"); } else applog(LOG_DEBUG, "BFI_INT patch requiring device not found, will not BFI_INT patch"); if (clState->goffset) strcat(CompilerOptions, " -D GOFFSET"); if (!clState->hasOpenCL11plus) strcat(CompilerOptions, " -D OCL1"); applog(LOG_DEBUG, "CompilerOptions: %s", CompilerOptions); status = clBuildProgram(clState->program, 1, &devices[gpu], CompilerOptions , NULL, NULL); free(CompilerOptions); if (status != CL_SUCCESS) { applog(LOG_ERR, "Error %d: Building Program (clBuildProgram)", status); size_t logSize; status = clGetProgramBuildInfo(clState->program, devices[gpu], CL_PROGRAM_BUILD_LOG, 0, NULL, &logSize); char *log = malloc(logSize); status = clGetProgramBuildInfo(clState->program, devices[gpu], CL_PROGRAM_BUILD_LOG, logSize, log, NULL); applog(LOG_ERR, "%s", log); return NULL; } prog_built = true; #ifdef __APPLE__ /* OSX OpenCL breaks reading off binaries with >1 GPU so always build * from source. */ goto built; #endif status = clGetProgramInfo(clState->program, CL_PROGRAM_NUM_DEVICES, sizeof(cl_uint), &cpnd, NULL); if (unlikely(status != CL_SUCCESS)) { applog(LOG_ERR, "Error %d: Getting program info CL_PROGRAM_NUM_DEVICES. (clGetProgramInfo)", status); return NULL; } status = clGetProgramInfo(clState->program, CL_PROGRAM_BINARY_SIZES, sizeof(size_t)*cpnd, binary_sizes, NULL); if (unlikely(status != CL_SUCCESS)) { applog(LOG_ERR, "Error %d: Getting program info CL_PROGRAM_BINARY_SIZES. (clGetProgramInfo)", status); return NULL; } /* The actual compiled binary ends up in a RANDOM slot! Grr, so we have * to iterate over all the binary slots and find where the real program * is. What the heck is this!? */ for (slot = 0; slot < cpnd; slot++) if (binary_sizes[slot]) break; /* copy over all of the generated binaries. */ applog(LOG_DEBUG, "Binary size for gpu %d found in binary slot %d: %d", gpu, slot, binary_sizes[slot]); if (!binary_sizes[slot]) { applog(LOG_ERR, "OpenCL compiler generated a zero sized binary, FAIL!"); return NULL; } binaries[slot] = calloc(sizeof(char) * binary_sizes[slot], 1); status = clGetProgramInfo(clState->program, CL_PROGRAM_BINARIES, sizeof(char *) * cpnd, binaries, NULL ); if (unlikely(status != CL_SUCCESS)) { applog(LOG_ERR, "Error %d: Getting program info. CL_PROGRAM_BINARIES (clGetProgramInfo)", status); return NULL; } /* Patch the kernel if the hardware supports BFI_INT but it needs to * be hacked in */ if (patchbfi) { unsigned remaining = binary_sizes[slot]; char *w = binaries[slot]; unsigned int start, length; /* Find 2nd incidence of .text, and copy the program's * position and length at a fixed offset from that. Then go * back and find the 2nd incidence of \x7ELF (rewind by one * from ELF) and then patch the opcocdes */ if (!advance(&w, &remaining, ".text")) goto build; w++; remaining--; if (!advance(&w, &remaining, ".text")) { /* 32 bit builds only one ELF */ w--; remaining++; } memcpy(&start, w + 285, 4); memcpy(&length, w + 289, 4); w = binaries[slot]; remaining = binary_sizes[slot]; if (!advance(&w, &remaining, "ELF")) goto build; w++; remaining--; if (!advance(&w, &remaining, "ELF")) { /* 32 bit builds only one ELF */ w--; remaining++; } w--; remaining++; w += start; remaining -= start; applog(LOG_DEBUG, "At %p (%u rem. bytes), to begin patching", w, remaining); patch_opcodes(w, length); status = clReleaseProgram(clState->program); if (status != CL_SUCCESS) { applog(LOG_ERR, "Error %d: Releasing program. (clReleaseProgram)", status); return NULL; } clState->program = clCreateProgramWithBinary(clState->context, 1, &devices[gpu], &binary_sizes[slot], (const unsigned char **)&binaries[slot], &status, NULL); if (status != CL_SUCCESS) { applog(LOG_ERR, "Error %d: Loading Binary into cl_program (clCreateProgramWithBinary)", status); return NULL; } /* Program needs to be rebuilt */ prog_built = false; } free(source); /* Save the binary to be loaded next time */ binaryfile = fopen(binaryfilename, "wb"); if (!binaryfile) { /* Not a fatal problem, just means we build it again next time */ applog(LOG_DEBUG, "Unable to create file %s", binaryfilename); } else { if (unlikely(fwrite(binaries[slot], 1, binary_sizes[slot], binaryfile) != binary_sizes[slot])) { applog(LOG_ERR, "Unable to fwrite to binaryfile"); return NULL; } fclose(binaryfile); } built: if (binaries[slot]) free(binaries[slot]); free(binaries); free(binary_sizes); applog(LOG_INFO, "Initialising kernel %s with%s bitalign, %d vectors and worksize %d", filename, clState->hasBitAlign ? "" : "out", clState->vwidth, clState->wsize); if (!prog_built) { /* create a cl program executable for all the devices specified */ status = clBuildProgram(clState->program, 1, &devices[gpu], NULL, NULL, NULL); if (status != CL_SUCCESS) { applog(LOG_ERR, "Error %d: Building Program (clBuildProgram)", status); size_t logSize; status = clGetProgramBuildInfo(clState->program, devices[gpu], CL_PROGRAM_BUILD_LOG, 0, NULL, &logSize); char *log = malloc(logSize); status = clGetProgramBuildInfo(clState->program, devices[gpu], CL_PROGRAM_BUILD_LOG, logSize, log, NULL); applog(LOG_ERR, "%s", log); return NULL; } } /* get a kernel object handle for a kernel with the given name */ clState->kernel = clCreateKernel(clState->program, "search", &status); if (status != CL_SUCCESS) { applog(LOG_ERR, "Error %d: Creating Kernel from program. (clCreateKernel)", status); return NULL; } #ifdef USE_SCRYPT if (opt_scrypt) { size_t ipt = (1024 / cgpu->lookup_gap + (1024 % cgpu->lookup_gap > 0)); size_t bufsize = 128 * ipt * cgpu->thread_concurrency; /* Use the max alloc value which has been rounded to a power of * 2 greater >= required amount earlier */ if (bufsize > cgpu->max_alloc) { applog(LOG_WARNING, "Maximum buffer memory device %d supports says %u", gpu, cgpu->max_alloc); applog(LOG_WARNING, "Your scrypt settings come to %u", bufsize); } applog(LOG_DEBUG, "Creating scrypt buffer sized %u", bufsize); clState->padbufsize = bufsize; /* This buffer is weird and might work to some degree even if * the create buffer call has apparently failed, so check if we * get anything back before we call it a failure. */ clState->padbuffer8 = NULL; clState->padbuffer8 = clCreateBuffer(clState->context, CL_MEM_READ_WRITE, bufsize, NULL, &status); if (status != CL_SUCCESS && !clState->padbuffer8) { applog(LOG_ERR, "Error %d: clCreateBuffer (padbuffer8), decrease TC or increase LG", status); return NULL; } clState->CLbuffer0 = clCreateBuffer(clState->context, CL_MEM_READ_ONLY, 128, NULL, &status); if (status != CL_SUCCESS) { applog(LOG_ERR, "Error %d: clCreateBuffer (CLbuffer0)", status); return NULL; } } #endif clState->outputBuffer = clCreateBuffer(clState->context, CL_MEM_WRITE_ONLY, BUFFERSIZE, NULL, &status); if (status != CL_SUCCESS) { applog(LOG_ERR, "Error %d: clCreateBuffer (outputBuffer)", status); return NULL; } return clState; }
superblock_metainfo_iterator_t(char *metainfo, char *metainfo_end) : end(metainfo_end) { advance(metainfo); }
void UpdateAI(uint32 const diff) { if (!phase) return; events.Update(diff); if ((phase != PHASE_BIRTH && !UpdateVictim()) || !CheckInRoom()) return; _DoAggroPulse(diff); if (CanTheHundredClub) { if (CheckFrostResistTimer <= diff) { CheckPlayersFrostResist(); CheckFrostResistTimer = (rand() % 5 + 5) * 1000; } else CheckFrostResistTimer -= diff; } if (phase == PHASE_GROUND) { while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { case EVENT_BERSERK: DoScriptText(EMOTE_ENRAGE, me); DoCast(me, SPELL_BERSERK); return; case EVENT_CLEAVE: DoCastVictim(SPELL_CLEAVE); events.ScheduleEvent(EVENT_CLEAVE, 5000+rand()%10000, 0, PHASE_GROUND); return; case EVENT_TAIL: DoCastAOE(SPELL_TAIL_SWEEP); events.ScheduleEvent(EVENT_TAIL, 5000+rand()%10000, 0, PHASE_GROUND); return; case EVENT_DRAIN: DoCastAOE(SPELL_LIFE_DRAIN); events.ScheduleEvent(EVENT_DRAIN, 24000, 0, PHASE_GROUND); return; case EVENT_BLIZZARD: { //DoCastAOE(SPELL_SUMMON_BLIZZARD); Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1); if (!target) target = me->getVictim(); if (Creature* Summon = DoSummon(MOB_BLIZZARD, target, 0.0f, 20000, TEMPSUMMON_TIMED_DESPAWN)) Summon->GetMotionMaster()->MoveRandom(40); events.ScheduleEvent(EVENT_BLIZZARD, RAID_MODE(20000, 7000), 0, PHASE_GROUND); break; } case EVENT_FLIGHT: if (HealthAbovePct(10)) { phase = PHASE_FLIGHT; events.SetPhase(PHASE_FLIGHT); me->SetReactState(REACT_PASSIVE); me->AttackStop(); float x, y, z, o; me->GetHomePosition(x, y, z, o); me->GetMotionMaster()->MovePoint(1, x, y, z); return; } break; } } DoMeleeAttackIfReady(); } else { if (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { case EVENT_LIFTOFF: me->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF); me->SetLevitate(true); me->SendMovementFlagUpdate(); events.ScheduleEvent(EVENT_ICEBOLT, 1500); iceboltCount = RAID_MODE(2, 3); return; case EVENT_ICEBOLT: { std::vector<Unit*> targets; std::list<HostileReference*>::const_iterator i = me->getThreatManager().getThreatList().begin(); for (; i != me->getThreatManager().getThreatList().end(); ++i) if ((*i)->getTarget()->GetTypeId() == TYPEID_PLAYER && !(*i)->getTarget()->HasAura(SPELL_ICEBOLT)) targets.push_back((*i)->getTarget()); if (targets.empty()) iceboltCount = 0; else { std::vector<Unit*>::const_iterator itr = targets.begin(); advance(itr, rand()%targets.size()); iceblocks.insert(std::make_pair((*itr)->GetGUID(), 0)); DoCast(*itr, SPELL_ICEBOLT); --iceboltCount; } if (iceboltCount) events.ScheduleEvent(EVENT_ICEBOLT, 1000); else events.ScheduleEvent(EVENT_BREATH, 1000); return; } case EVENT_BREATH: { DoScriptText(EMOTE_BREATH, me); DoCastAOE(SPELL_FROST_MISSILE); events.ScheduleEvent(EVENT_EXPLOSION, 8000); return; } case EVENT_EXPLOSION: CastExplosion(); ClearIceBlock(); events.ScheduleEvent(EVENT_LAND, 3000); return; case EVENT_LAND: me->HandleEmoteCommand(EMOTE_ONESHOT_LAND); me->SetLevitate(false); me->SendMovementFlagUpdate(); events.ScheduleEvent(EVENT_GROUND, 1500); return; case EVENT_GROUND: EnterPhaseGround(); return; case EVENT_BIRTH: me->SetVisible(true); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); me->SetReactState(REACT_AGGRESSIVE); return; } } } }
string CacheMap::getCollectionEntryAt(string cacheKey, int position) { string value; bool error = false; string type = checkExistanceAndGetType(cacheKey); if(type!="") { if(type==VECTOR) { instance->mutex.lock(); vector<string>* valueVector = (vector<string>*)instance->cacheMap[cacheKey]; instance->mutex.unlock(); instance->valueLocks[cacheKey]->lock(); if(position<(int)valueVector->size()) { value = valueVector->at(position); } else { error = true; } instance->valueLocks[cacheKey]->unlock(); } else if(type==LIST) { instance->mutex.lock(); list<string>* valueList = (list<string>*)instance->cacheMap[cacheKey]; instance->mutex.unlock(); instance->valueLocks[cacheKey]->lock(); if(position<(int)valueList->size()) { list<string>::iterator it = valueList->begin(); advance(it, position); value = *it; } else { error = true; } instance->valueLocks[cacheKey]->unlock(); } else if(type==SET) { instance->mutex.lock(); set<string>* valueSet = (set<string>*)instance->cacheMap[cacheKey]; instance->mutex.unlock(); instance->valueLocks[cacheKey]->lock(); if(position<(int)valueSet->size()) { set<string>::iterator it = valueSet->begin(); advance(it, position); value = *it; } else { error = true; } instance->valueLocks[cacheKey]->unlock(); } else if(type==DEQUE) { instance->mutex.lock(); deque<string>* valueDeque = (deque<string>*)instance->cacheMap[cacheKey]; instance->mutex.unlock(); instance->valueLocks[cacheKey]->lock(); if(position<(int)valueDeque->size()) { deque<string>::iterator it = valueDeque->begin(); advance(it, position); value = *it; } else { error = true; } instance->valueLocks[cacheKey]->unlock(); } else if(type==QUEUE) { throw ERR_OPNOTSUPP; } else { throw ERR_INVCONTAINER; } } else { throw ERR_NOKEYCACHEMAP; } if(error) { throw ERR_INDGRTCONTSIZ; } return value; }