From b6884b148e54ed0da2ebb75e88566b584e1b632e Mon Sep 17 00:00:00 2001 From: gb <741021719@qq.com> Date: Tue, 12 Dec 2023 09:36:06 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B0=86=E7=B3=BB=E7=BB=9F=E4=BF=A1=E6=81=AF?= =?UTF-8?q?=EF=BC=88=E5=86=85=E5=AD=98=E9=A1=B5=E5=A4=A7=E5=B0=8F=E2=80=A6?= =?UTF-8?q?=E2=80=A6=EF=BC=89=E6=8F=90=E5=8D=87=E4=B8=BA=E5=85=A8=E5=B1=80?= =?UTF-8?q?=E5=88=9D=E5=A7=8B=E5=8C=96=E5=AF=B9=E8=B1=A1=EF=BC=9B=E8=B0=83?= =?UTF-8?q?=E6=95=B4IO=E7=BC=93=E5=86=B2=E5=A4=A7=E5=B0=8F=E4=B8=BA?= =?UTF-8?q?=E5=86=85=E5=AD=98=E9=A1=B5=E9=9D=A2=E5=A4=A7=E5=B0=8F=EF=BC=9B?= =?UTF-8?q?IO=E7=BC=93=E5=86=B2=E9=87=87=E7=94=A8=E5=86=85=E5=AD=98?= =?UTF-8?q?=E6=B1=A0=EF=BC=9B=E5=A2=9E=E5=8A=A0=E6=96=87=E4=BB=B6=E6=98=A0?= =?UTF-8?q?=E5=B0=84=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sdk/base/data.cpp | 30 +++++++++++++++++++ sdk/base/data.h | 15 +++++++++- sdk/base/packet.h | 1 + sdk/base/utils.cpp | 2 -- usb/usb_io.cpp | 72 ++++++++++++++++++++++++++++++++++++++++------ usb/usb_io.h | 4 +++ 6 files changed, 112 insertions(+), 12 deletions(-) diff --git a/sdk/base/data.cpp b/sdk/base/data.cpp index 7c2a13c..c33f69c 100644 --- a/sdk/base/data.cpp +++ b/sdk/base/data.cpp @@ -10,6 +10,29 @@ #include #endif +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// sys_info +uint32_t sys_info::page_size = 0; +uint32_t sys_info::page_map_size = 0; +uint32_t sys_info::cluster_size = 0; + +sys_info::sys_info() +{ + sys_info::page_size = utils::get_page_size(&sys_info::page_map_size); + + std::string path(utils::get_local_data_path()); + unsigned long long cluster = 0; + + utils::get_disk_space(path.c_str(), nullptr, nullptr, &cluster); + sys_info::cluster_size = cluster; + + printf("Page size: %u\nMap size: %u\nCluster : %u\n", sys_info::page_size, sys_info::page_map_size, sys_info::cluster_size); +} +sys_info::~sys_info() +{} + +static sys_info g_si; + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // packet_data_base::packet_data_base() : pack_cmd_(0), pack_id_(0) @@ -406,6 +429,12 @@ dyn_mem& dyn_mem::operator+=(dyn_mem& r) return *this; } +void dyn_mem::clear_data(void) +{ + len_ = 0; + set_packet_param(0, 0); + set_session_id(0); +} bool dyn_mem::is_memory_block(void) { @@ -450,6 +479,7 @@ file_reader::~file_reader() fclose(src_); if (map_) map_->release(); + notify_progress(len_, len_, 0); // ensure 100% utils::to_log(LOG_LEVEL_DEBUG, "Read file(%s) over(%ld/%ld).\n", path_.c_str(), consume_, len_); } diff --git a/sdk/base/data.h b/sdk/base/data.h index e5a30d5..ffd8dc9 100644 --- a/sdk/base/data.h +++ b/sdk/base/data.h @@ -76,6 +76,18 @@ public: uint8_t* buffer(void); }; +class sys_info +{ +public: + sys_info(); + ~sys_info(); + +public: + static uint32_t page_size; + static uint32_t page_map_size; + static uint32_t cluster_size; +}; + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // /* data_holder, used when data is also required for a certain packet @@ -220,6 +232,7 @@ public: size_t used(size_t len); // used len bytes content, move following data to head and set data length, return rest data length dyn_mem& operator+=(dyn_mem& r); + void clear_data(void); // data_source public: @@ -284,7 +297,7 @@ CLS_PTR(file_reader); // // when invalid packet, suggest use the entire data // -// packet_data_base_ptr* - return data_holder or data_source or nullptr The number of bytes required for this packet, 0 is over for this packet +// packet_data_base_ptr* - return data_holder or data_source or nullptr ��The number of bytes required for this packet, 0 is over for this packet�� // // data_holder: the packet/command need more data than dyn_mem_ptr provides to complete the business. such as 'write a large file' // diff --git a/sdk/base/packet.h b/sdk/base/packet.h index dfc51e2..b62667d 100644 --- a/sdk/base/packet.h +++ b/sdk/base/packet.h @@ -44,6 +44,7 @@ enum ep0_req { USB_REQ_EP0_GET_PROTO_VER = 100, // get protocol version (PROTOCOL_VER), req = me, ind = 0, val = 0, len = 2 + USB_REQ_EP0_GET_IO_SIZE, // get bulk size of IO buffer, req = me, ind = 0, val = 0, len = sizeof(uint32_t) USB_REQ_EP0_GET_STATUS, // 获取各工作线程状态, return EP0REPLYSTATUS. req = me, ind = 0, val = 0, len = sizeof(EP0REPLYSTATUS) USB_REQ_EP0_RESET_BULK, // 关闭并重新打开BULK端点, return error number (uint32_t). req = me, ind = 0, val = 0, len = sizeof(uint32_t) USB_REQ_EP0_CANCEL_CMD, // 取消当前指令的继续执行(一般用于中止大数据的传输). req = me, ind = 0, val = 0, len = sizeof(uint32_t) * 2 [(uint32_t)cmd + (uint32_t)pack-id] diff --git a/sdk/base/utils.cpp b/sdk/base/utils.cpp index 574c626..9a5720e 100644 --- a/sdk/base/utils.cpp +++ b/sdk/base/utils.cpp @@ -1052,8 +1052,6 @@ namespace utils ret = statfs(path, &fs); if (ret == 0) { - utils::to_log(LOG_LEVEL_DEBUG, " Total: %lld, Free: %lld, Avail: %lld, block size: %lld\n", - fs.f_blocks, fs.f_bfree, fs.f_bavail, fs.f_bsize); if (total) *total = fs.f_blocks * fs.f_bsize; if (avail) diff --git a/usb/usb_io.cpp b/usb/usb_io.cpp index 046abc9..6cf4a69 100644 --- a/usb/usb_io.cpp +++ b/usb/usb_io.cpp @@ -18,7 +18,7 @@ async_usb_gadget::async_usb_gadget(std::function , std::function dev_conn) : handle_cmd_(cmd_handler), dev_connect_(dev_conn) , enc_head_(ENCRYPT_CMD_NONE), enc_payload_(ENCRYPT_NONE), enc_data_(0) - , cmd_que_("in-queue"), sent_que_("out-queue") + , io_buf_("IO-buf"), cmd_que_("in-queue"), sent_que_("out-queue") , wait_in_("wait_usb_enable_in"), wait_out_("wait_usb_enable_out") { cmd_que_.enable_wait_log(false); @@ -87,7 +87,17 @@ async_usb_gadget::async_usb_gadget(std::function }; threads_.set_exception_handler(excep); - unit_in_ = unit_out_ = dev_->get_max_packet(); + unit_in_ = unit_out_ = sys_info::page_size; // dev_->get_max_packet(); + + // allocate 10MB for IO + for(int i = 0; i < SIZE_MB(10) / unit_out_; ++i) + { + dyn_mem_ptr buf = dyn_mem::memory(unit_out_); + if(buf) + io_buf_.save(buf); + } + utils::to_log(LOG_LEVEL_DEBUG, "Prepare %u(%u * %u) for IO.\n", io_buf_.size() * unit_out_, io_buf_.size(), unit_in_); + threads_.start(task, "thread_pump_task", (void*)&async_usb_gadget::thread_pump_task); threads_.start(bulkw, "thread_write_bulk", (void*)&async_usb_gadget::thread_write_bulk); threads_.start(bulkr, "thread_read_bulk", (void*)&async_usb_gadget::thread_read_bulk); @@ -97,6 +107,27 @@ async_usb_gadget::async_usb_gadget(std::function async_usb_gadget::~async_usb_gadget() { stop(); + + dyn_mem_ptr buf = nullptr; + while(io_buf_.take(buf, false)) + { + if(buf) + buf->release(); + } +} + +dyn_mem_ptr async_usb_gadget::get_io_buffer(void) +{ + dyn_mem_ptr buf = nullptr; + + io_buf_.take(buf, true); + + return buf; +} +void async_usb_gadget::free_io_buffer(dyn_mem_ptr buf) +{ + buf->clear_data(); + io_buf_.save(buf, true); } const char* async_usb_gadget::ep0_status_desc(int ep0_status, char* unk_buf/*>= 20 bytes*/) @@ -233,6 +264,10 @@ dyn_mem_ptr async_usb_gadget::handle_ctrl_setup(dyn_mem_ptr data) utils::log_mem_info("threads status:", lps, sizeof(*lps), LOG_LEVEL_DEBUG); } break; + case USB_REQ_EP0_GET_IO_SIZE: + reply = dyn_mem::memory(sizeof(unit_out_)); + reply->put(&unit_out_, sizeof(unit_out_)); + break; case USB_REQ_EP0_RESET_BULK: reply = dyn_mem::memory(sizeof(uint32_t)); reply->put(&err, sizeof(err)); @@ -435,12 +470,12 @@ void async_usb_gadget::thread_read_ep0(void) } void async_usb_gadget::thread_read_bulk(int fd) { - size_t bulk_size = unit_out_ * get_buf_coefficient(); + size_t bulk_size = unit_out_; // * get_buf_coefficient(); uint32_t cnt_0 = 0; while(run_) { - dyn_mem_ptr buf(dyn_mem::memory(bulk_size)); + dyn_mem_ptr buf = get_io_buffer(); int l = 0; statu_out_ = WORKER_STATUS_BUSY; @@ -449,7 +484,7 @@ void async_usb_gadget::thread_read_bulk(int fd) statu_out_ = WORKER_STATUS_IDLE; if(l <= 0) { - buf->release(); + free_io_buffer(buf); if(errno) { utils::to_log(LOG_LEVEL_ALL, "read bulk(%d) failed: %d(%s)\n", l, errno, strerror(errno)); @@ -512,6 +547,7 @@ void async_usb_gadget::thread_pump_task(void) statu_task_ = WORKER_STATUS_IDLE; if(cmd_que_.take(data, true) && data) { + bool pool = true; statu_task_ = WORKER_STATUS_BUSY; if(max_que < cmd_que_.size()) max_que = cmd_que_.size(); @@ -527,8 +563,9 @@ void async_usb_gadget::thread_pump_task(void) { utils::to_log(LOG_LEVEL_ALL, "Combine partial packet with length %u and %u ...\n", prev->get_rest(), data->get_rest()); *prev += *data; - data->release(); + free_io_buffer(data); data = prev; + pool = false; } prev = nullptr; } @@ -542,7 +579,10 @@ void async_usb_gadget::thread_pump_task(void) if (!online_ || data->get_session_id() != session_id_) { utils::to_log(LOG_LEVEL_DEBUG, "Discard task for session ID(%u) is not equal now(%u) or is offline.\n", data->get_session_id(), session_id_); - data->release(); + if(pool) + free_io_buffer(data); + else + data->release(); continue; } @@ -653,14 +693,28 @@ void async_usb_gadget::thread_pump_task(void) }while(used && data->get_rest()); if(data->get_rest()) - prev = data; + { + if(pool) + { + prev = dyn_mem::memory(unit_out_); + prev->put(data->ptr(), data->get_rest()); + free_io_buffer(data); + } + else + { + prev = data; + } + } else { if(!dh) { task_cmd_ = task_packet_id_ = want_bytes_task_ = 0; } - data->release(); + if(pool) + free_io_buffer(data); + else + data->release(); } } } diff --git a/usb/usb_io.h b/usb/usb_io.h index 4828d8d..9251ba3 100644 --- a/usb/usb_io.h +++ b/usb/usb_io.h @@ -69,6 +69,7 @@ class async_usb_gadget : public refer uint32_t task_cmd_ = 0; uint32_t task_packet_id_ = 0; + safe_fifo io_buf_; safe_fifo cmd_que_; safe_fifo sent_que_; @@ -83,6 +84,9 @@ class async_usb_gadget : public refer std::function handle_cmd_; std::function dev_connect_; + dyn_mem_ptr get_io_buffer(void); + void free_io_buffer(dyn_mem_ptr buf); + const char* ep0_status_desc(int ep0_status, char* unk_buf/*>= 40 bytes*/); int wait_fd_event(int fd, int to_ms = -1);