Line 1... |
Line 1... |
/**
|
/*
|
* @file
|
* Copyright 2018 Sergey Khabarov, sergeykhbr@gmail.com
|
* @copyright Copyright 2016 GNSS Sensor Ltd. All right reserved.
|
*
|
* @author Sergey Khabarov - sergeykhbr@gmail.com
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
* @brief Asynchronous queue with time markers.
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
*/
|
*/
|
|
|
#include "api_utils.h"
|
#include <api_utils.h>
|
#include "async_tqueue.h"
|
#include <async_tqueue.h>
|
|
|
namespace debugger {
|
namespace debugger {
|
|
|
AsyncTQueueType::AsyncTQueueType() {
|
AsyncTQueueType::AsyncTQueueType() {
|
preLen_ = 0;
|
|
curLen_ = 0;
|
|
stepPreQueued_.make_list(0);
|
stepPreQueued_.make_list(0);
|
stepQueue_.make_list(16); /** it will be auto reallocated if needed */
|
stepQueue_.make_list(16); /** it will be auto reallocated if needed */
|
item_.make_list(Queue_Total);
|
|
RISCV_mutex_init(&mutex_);
|
RISCV_mutex_init(&mutex_);
|
|
hardReset();
|
}
|
}
|
|
|
AsyncTQueueType::~AsyncTQueueType() {
|
AsyncTQueueType::~AsyncTQueueType() {
|
RISCV_mutex_destroy(&mutex_);
|
RISCV_mutex_destroy(&mutex_);
|
}
|
}
|
|
|
void AsyncTQueueType::put(uint64_t time, IFace *cb) {
|
void AsyncTQueueType::hardReset() {
|
RISCV_mutex_lock(&mutex_);
|
preLen_ = 0;
|
item_[Queue_Time].make_uint64(time);
|
curLen_ = 0;
|
item_[Queue_IFace].make_iface(cb);
|
curIdx_ = 0;
|
|
}
|
|
|
|
void AsyncTQueueType::put(AttributeType *item) {
|
if (preLen_ == stepPreQueued_.size()) {
|
if (preLen_ == stepPreQueued_.size()) {
|
unsigned new_sz = 2 * stepPreQueued_.size();
|
unsigned new_sz = 2 * stepPreQueued_.size();
|
if (new_sz == 0) {
|
if (new_sz == 0) {
|
new_sz = 1;
|
new_sz = 1;
|
}
|
}
|
stepPreQueued_.realloc_list(new_sz);
|
stepPreQueued_.realloc_list(new_sz);
|
}
|
}
|
stepPreQueued_[preLen_].attr_free();
|
stepPreQueued_[preLen_].attr_free();
|
stepPreQueued_[preLen_] = item_;
|
stepPreQueued_[preLen_] = *item;
|
preLen_++;
|
preLen_++;
|
RISCV_mutex_unlock(&mutex_);
|
|
}
|
}
|
|
|
void AsyncTQueueType::pushPreQueued() {
|
void AsyncTQueueType::pushPreQueued() {
|
if (preLen_ == 0) {
|
if (preLen_ == 0) {
|
return;
|
return;
|
}
|
}
|
RISCV_mutex_lock(&mutex_);
|
RISCV_mutex_lock(&mutex_);
|
Line 59... |
Line 69... |
|
|
void AsyncTQueueType::initProc() {
|
void AsyncTQueueType::initProc() {
|
curIdx_ = 0;
|
curIdx_ = 0;
|
}
|
}
|
|
|
IFace *AsyncTQueueType::getNext(uint64_t step_cnt) {
|
/** Clock queue */
|
|
ClockAsyncTQueueType::ClockAsyncTQueueType() : AsyncTQueueType() {
|
|
item_.make_list(Queue_Total);
|
|
}
|
|
|
|
void ClockAsyncTQueueType::put(uint64_t time, IFace *cb) {
|
|
RISCV_mutex_lock(&mutex_);
|
|
item_[Queue_Time].make_uint64(time);
|
|
item_[Queue_IFace].make_iface(cb);
|
|
|
|
AsyncTQueueType::put(&item_);
|
|
RISCV_mutex_unlock(&mutex_);
|
|
}
|
|
|
|
IFace *ClockAsyncTQueueType::getNext(uint64_t step_cnt) {
|
IFace *ret = 0;
|
IFace *ret = 0;
|
if (curIdx_ >= curLen_) {
|
if (curIdx_ >= curLen_) {
|
return ret;
|
return ret;
|
}
|
}
|
for (unsigned i = curIdx_; i < curLen_; i++) {
|
for (unsigned i = curIdx_; i < curLen_; i++) {
|
uint64_t ev_time = stepQueue_[i][Queue_Time].to_uint64();
|
uint64_t ev_time = stepQueue_[i][Queue_Time].to_uint64();
|
|
|
|
curIdx_ = i;
|
if (step_cnt < ev_time) {
|
if (step_cnt < ev_time) {
|
continue;
|
continue;
|
}
|
}
|
ret = stepQueue_[i][Queue_IFace].to_iface();
|
ret = stepQueue_[i][Queue_IFace].to_iface();
|
|
|
// remove item from list using swap function to avoid usage
|
// remove item from list using swap function to avoid usage
|
// of allocation/deallocation calls.
|
// of allocation/deallocation calls.
|
|
if (i < (curLen_ - 1)) {
|
stepQueue_.swap_list_item(i, curLen_ - 1);
|
stepQueue_.swap_list_item(i, curLen_ - 1);
|
|
}
|
curLen_--;
|
curLen_--;
|
curIdx_--;
|
|
break;
|
break;
|
}
|
}
|
return ret;
|
return ret;
|
}
|
}
|
|
|
|
|
|
/** GUI queue */
|
|
GuiAsyncTQueueType::GuiAsyncTQueueType() : AsyncTQueueType() {
|
|
item_.make_list(Queue_Total);
|
|
dbg_cnt_ = 0;
|
|
}
|
|
|
|
void GuiAsyncTQueueType::put(IFace *src, AttributeType *cmd, bool silent) {
|
|
RISCV_mutex_lock(&mutex_);
|
|
item_[Queue_Source].make_iface(src);
|
|
item_[Queue_Command] = *cmd;
|
|
item_[Queue_Silent].make_boolean(silent);
|
|
|
|
AsyncTQueueType::put(&item_);
|
|
dbg_cnt_++;
|
|
RISCV_mutex_unlock(&mutex_);
|
|
}
|
|
|
|
bool GuiAsyncTQueueType::getNext(IFace **src, AttributeType &cmd,
|
|
bool &silent) {
|
|
*src = 0;
|
|
if (curIdx_ >= curLen_) {
|
|
curIdx_ = 0;
|
|
curLen_ = 0;
|
|
return false;
|
|
}
|
|
AttributeType &item = stepQueue_[curIdx_++];
|
|
dbg_cnt_--;
|
|
|
|
*src = item[Queue_Source].to_iface();
|
|
cmd = item[Queue_Command];
|
|
silent = item[Queue_Silent].to_bool();
|
|
return true;
|
|
}
|
|
|
|
void GuiAsyncTQueueType::remove(IFace *src) {
|
|
RISCV_mutex_lock(&mutex_);
|
|
for (unsigned i = 0; i < preLen_; i++) {
|
|
AttributeType &item = stepPreQueued_[i];
|
|
if (item[Queue_Source].to_iface() == src) {
|
|
item[Queue_Source].make_iface(0);
|
|
}
|
|
}
|
|
for (unsigned i = 0; i < curLen_; i++) {
|
|
AttributeType &item = stepQueue_[i];
|
|
if (item[Queue_Source].to_iface() == src) {
|
|
item[Queue_Source].make_iface(0);
|
|
}
|
|
}
|
|
RISCV_mutex_unlock(&mutex_);
|
|
}
|
|
|
} // namespace debugger
|
} // namespace debugger
|
|
|
|
|
No newline at end of file
|
No newline at end of file
|