NSUKit 1.4.0
板卡级统一交互接口
载入中...
搜索中...
未找到
data_uploadfeiting.cpp
浏览该文件的文档.
1
2// Copyright (c) 2024. Naishu
3// NSUKit is licensed under Mulan PSL v2.
4// You can use this software according to the terms and conditions of the Mulan PSL v2.
5// You may obtain a copy of Mulan PSL v2 at:
6// http://license.coscl.org.cn/MulanPSL2
7// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
8// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
9// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
10// See the Mulan PSL v2 for more details.
12
13//
14// Created by jilianyi<jilianyi@naishu.tech> on 2024/4/12.
15//
16
17/*
18 * +---------------+ +-------------------+
19 * | | +---------------+ | |
20 * | |-----> | full_queue |-----> | |
21 * | | +---------------+ | |
22 * | upload_thread | | write_file_thread |
23 * | | +---------------+ | |
24 * | |<----- | empty_queue |<----- | |
25 * | | +---------------+ | |
26 * +---------------+ +-------------------+
27 * @class ThreadSafeQueue
28 */
29#include <iostream>
30#include <queue>
31#include <thread>
32#include <condition_variable>
33#include "NSUKit.h"
34
35
36#define STREAM_WITH_PCIE
37//#define STREAM_WITH_TCP
38#define SocType nsukit::NSUSoc <nsukit::SimCmdUItf, nsukit::SimCmdUItf, nsukit::SimStreamUItf>
39
40#ifdef STREAM_WITH_PCIE
41#define SocType nsukit::NSUSoc <nsukit::TCPCmdUItf, nsukit::TCPCmdUItf, nsukit::PCIERingUItf>
42#endif
43
44#ifdef STREAM_WITH_TCP
45#define SocType nsukit::NSUSoc <nsukit::TCPCmdUItf, nsukit::TCPCmdUItf, nsukit::TCPStreamUItf>
46#endif
47
48
53template <typename T>
54class ThreadSafeQueue {
55public:
57
58 //
59 void Push(T *value) {
60 std::unique_lock<std::mutex> lock(mutex_);
61 queue_.push(value);
62 lock.unlock();
63 condition_.notify_one();
64 }
65
66 //
67 T *Pop() {
68 std::unique_lock<std::mutex> lock(mutex_);
69 condition_.wait(lock, [this] { return !queue_.empty(); });
70 auto value = (T *)queue_.front();
71 queue_.pop();
72 return value;
73 }
74
75private:
76 std::queue<T *> queue_;
77 std::mutex mutex_;
78 std::condition_variable condition_;
79};
80
81
83
84
85struct Deque {
86 memQueue full{};
88 int stopFlag = 0;
89};
90
91
100void upload_thread(nsukit::BaseKit *_kit, Deque *q, nsuSize_t block, nsuSize_t total, std::mutex *mu, nsuChnlNum_t chnl) {
101 std::unique_lock<std::mutex> *lock;
102 nsuMemory_p mem;
103 nsuSize_t current = 0;
104 while (true) {
105 mem = q->empty.Pop();
106 auto s = _kit->open_recv(chnl, mem, block, 0);
108 std::cout << "Establish CS and CR connections: " << std::endl;
109 std::cout << "Failed to enable data uplink " << nsukit::status2_string(s) << ", currently uplinked: " << current << std::endl;
110 break;
111 }
114 s = _kit->wait_stream(mem, 1.);
115 }
116 current += block;
117 q->full.Push(mem);
118 if (current == total) {
119 break;
120 };
121 }
122 lock = new std::unique_lock<std::mutex>(*mu);
123 q->stopFlag = 1;
124 delete lock;
125}
126
127
136void write_file_thread(nsukit::BaseKit *_kit, Deque *q, nsuSize_t block, const std::string &path, std::mutex *mu) {
137 std::unique_lock<std::mutex> *lock;
138 nsuMemory_p mem;
139 std::ofstream outF;
140 outF.open(path, std::ofstream::binary);
141 int cnt = 0;
142 nsuSize_t speed_count = 0;
143 auto st = std::chrono::steady_clock::now();
144
145 while (true) {
146 lock = new std::unique_lock<std::mutex>(*mu);
147 if (q->stopFlag == 1) {
148 break;
149 }
150 delete lock;
151 mem = q->full.Pop();
152 outF.write((char *)_kit->get_buffer(mem, block), block);
153 q->empty.Push(mem);
154// std::this_thread::sleep_for(std::chrono::seconds(1));
155 speed_count += block;
156
157 if (cnt % 20 == 0) {
158 auto count = std::chrono::steady_clock::now() - st;
159 std::cout << std::flush << '\r' << "current write file speed: " << speed_count*1000./(count.count()) << "MB/s" << std::endl;
160 speed_count = 0;
161 st = std::chrono::steady_clock::now();
162 }
163 cnt++;
164 }
165 std::cout << std::endl;
166 outF.close();
167}
168
169
170int main(int argc, char *argv[]) {
171 unsigned int ds_block = 32*1024*1024;
172 Deque q;
173 std::mutex mu;
174 SocType* kit = new SocType{};
175
176 if (argc != 4) {
177 std::cout << "Unsupported parameter passing method" << std::endl;
178 // DataUpload 127.0.0.1 104857600 ./da_data_1.dat
179 std::cout << argv[0] << " {IP} {totalBytes} {filePath} {chnl}" << std::endl;
180 return 1;
181 }
182 nsuSize_t total_len = std::atoi(argv[2]);
183 if (total_len % ds_block != 0) {
184 std::cout << "The total length of upstream data total_len "
185 << total_len << " Bytes should be "
186 << ds_block << "Integer multiple of Bytes" << std::endl;
187 return 1;
188 }
189
190 nsuInitParam_t param;
191 param.stream_board = 0;
192
193 auto res = kit->link_stream(&param);
195 std::cout << "Establish a DS connection: " << nsukit::status2_string(res) << std::endl;
196 }
197
198 std::cout << "SocLink Successful!!! now alloc buffer" << std::endl;
199 for (int i=0; i<10; i++) {
200 nsuMemory_p mem = kit->alloc_buffer(ds_block);
201 q.empty.Push(mem);
202 }
203
204 // Start the upstream and storage threads.
205 std::thread up_trd(upload_thread, kit, &q, ds_block, total_len, &mu, std::atoi(argv[4]));
206 std::thread write_trd(write_file_thread, kit, &q, ds_block, argv[3], &mu);
207
208 std::cout << "Stream thread start successful!!!" << std::endl;
209
210 up_trd.join();
211 write_trd.join();
212
213 std::cout << "Data upload completed" << std::endl;
214
215 return 0;
216}
void Push(T *value)
virtual nsukitStatus_t open_recv(nsuChnlNum_t chnl, nsuMemory_p fd, nsuStreamLen_t length, nsuStreamLen_t offset=0)
Definition: base_kit.h:98
virtual nsuVoidBuf_p get_buffer(nsuMemory_p fd, nsuStreamLen_t length=0)
Definition: base_kit.h:76
virtual nsukitStatus_t wait_stream(nsuMemory_p fd, float timeout=0.)
Definition: base_kit.h:103
nsukitStatus_t link_stream(nsuInitParam_t *param) override
Definition: NSUKit.h:376
nsuMemory_p alloc_buffer(nsuStreamLen_t length, nsuVoidBuf_p buf=nullptr) override
Definition: NSUKit.h:575
void write_file_thread(nsukit::BaseKit *_kit, Deque *q, nsuSize_t block, const std::string &path, std::mutex *mu)
void upload_thread(nsukit::BaseKit *_kit, Deque *q, nsuSize_t block, nsuSize_t total, std::mutex *mu, nsuChnlNum_t chnl)
ThreadSafeQueue< void > memQueue
std::string NSU_DLLEXPORT status2_string(nsukitStatus_t status)
Definition: config.cpp:15
int stopFlag
memQueue empty
memQueue full
nsuBoardNum_t stream_board
Definition: type.h:121
@ NSUKIT_STATUS_STREAM_RUNNING
DLLEXTERN typedef size_t nsuSize_t
Definition: type.h:87
DLLEXTERN typedef void * nsuMemory_p
Definition: type.h:86
DLLEXTERN typedef uint8_t nsuChnlNum_t
Definition: type.h:85