winlin

for bug #251, use macro to define the fast cache and cond wait. 2.0.58

@@ -598,9 +598,11 @@ int SrsRtmpConn::do_playing(SrsSource* source, SrsQueueRecvThread* trd) @@ -598,9 +598,11 @@ int SrsRtmpConn::do_playing(SrsSource* source, SrsQueueRecvThread* trd)
598 // collect elapse for pithy print. 598 // collect elapse for pithy print.
599 pithy_print.elapse(); 599 pithy_print.elapse();
600 600
  601 +#ifdef SRS_PERF_QUEUE_COND_WAIT
601 // wait for message to incoming. 602 // wait for message to incoming.
602 // @see https://github.com/winlinvip/simple-rtmp-server/issues/251 603 // @see https://github.com/winlinvip/simple-rtmp-server/issues/251
603 consumer->wait(SRS_PERF_MW_MIN_MSGS, mw_sleep); 604 consumer->wait(SRS_PERF_MW_MIN_MSGS, mw_sleep);
  605 +#endif
604 606
605 // get messages from consumer. 607 // get messages from consumer.
606 // each msg in msgs.msgs must be free, for the SrsMessageArray never free them. 608 // each msg in msgs.msgs must be free, for the SrsMessageArray never free them.
@@ -610,8 +612,14 @@ int SrsRtmpConn::do_playing(SrsSource* source, SrsQueueRecvThread* trd) @@ -610,8 +612,14 @@ int SrsRtmpConn::do_playing(SrsSource* source, SrsQueueRecvThread* trd)
610 return ret; 612 return ret;
611 } 613 }
612 614
  615 +#ifdef SRS_PERF_QUEUE_COND_WAIT
613 // we use wait to get messages, so the count must be positive. 616 // we use wait to get messages, so the count must be positive.
614 srs_assert(count > 0); 617 srs_assert(count > 0);
  618 +#else
  619 + if (count <= 0) {
  620 + st_usleep(mw_sleep * 1000);
  621 + }
  622 +#endif
615 srs_info("got %d msgs, min=%d, mw=%d", count, SRS_PERF_MW_MIN_MSGS, mw_sleep); 623 srs_info("got %d msgs, min=%d, mw=%d", count, SRS_PERF_MW_MIN_MSGS, mw_sleep);
616 624
617 // reportable 625 // reportable
@@ -167,6 +167,16 @@ SrsMessageQueue::~SrsMessageQueue() @@ -167,6 +167,16 @@ SrsMessageQueue::~SrsMessageQueue()
167 clear(); 167 clear();
168 } 168 }
169 169
  170 +int SrsMessageQueue::size()
  171 +{
  172 + return (int)msgs.size();
  173 +}
  174 +
  175 +int SrsMessageQueue::duration()
  176 +{
  177 + return (int)(av_end_time - av_start_time);
  178 +}
  179 +
170 void SrsMessageQueue::set_queue_size(double queue_size) 180 void SrsMessageQueue::set_queue_size(double queue_size)
171 { 181 {
172 queue_size_ms = (int)(queue_size * 1000); 182 queue_size_ms = (int)(queue_size * 1000);
@@ -297,28 +307,37 @@ SrsConsumer::SrsConsumer(SrsSource* _source) @@ -297,28 +307,37 @@ SrsConsumer::SrsConsumer(SrsSource* _source)
297 queue = new SrsMessageQueue(); 307 queue = new SrsMessageQueue();
298 should_update_source_id = false; 308 should_update_source_id = false;
299 309
  310 +#ifdef SRS_PERF_QUEUE_COND_WAIT
300 mw_wait = st_cond_new(); 311 mw_wait = st_cond_new();
301 mw_min_msgs = 0; 312 mw_min_msgs = 0;
302 mw_duration = 0; 313 mw_duration = 0;
303 mw_waiting = false; 314 mw_waiting = false;
  315 +#endif
304 316
  317 +#ifdef SRS_PERF_QUEUE_FAST_CACHE
305 mw_cache = new SrsMessageArray(SRS_PERF_MW_MSGS); 318 mw_cache = new SrsMessageArray(SRS_PERF_MW_MSGS);
306 mw_count = 0; 319 mw_count = 0;
307 mw_first_pkt = mw_last_pkt = 0; 320 mw_first_pkt = mw_last_pkt = 0;
  321 +#endif
308 } 322 }
309 323
310 SrsConsumer::~SrsConsumer() 324 SrsConsumer::~SrsConsumer()
311 { 325 {
  326 +#ifdef SRS_PERF_QUEUE_FAST_CACHE
312 if (mw_cache) { 327 if (mw_cache) {
313 mw_cache->free(mw_count); 328 mw_cache->free(mw_count);
314 mw_count = 0; 329 mw_count = 0;
315 } 330 }
316 srs_freep(mw_cache); 331 srs_freep(mw_cache);
  332 +#endif
317 333
318 source->on_consumer_destroy(this); 334 source->on_consumer_destroy(this);
319 srs_freep(jitter); 335 srs_freep(jitter);
320 srs_freep(queue); 336 srs_freep(queue);
  337 +
  338 +#ifdef SRS_PERF_QUEUE_COND_WAIT
321 st_cond_destroy(mw_wait); 339 st_cond_destroy(mw_wait);
  340 +#endif
322 } 341 }
323 342
324 void SrsConsumer::set_queue_size(double queue_size) 343 void SrsConsumer::set_queue_size(double queue_size)
@@ -347,6 +366,7 @@ int SrsConsumer::enqueue(SrsSharedPtrMessage* msg, bool atc, int tba, int tbv, S @@ -347,6 +366,7 @@ int SrsConsumer::enqueue(SrsSharedPtrMessage* msg, bool atc, int tba, int tbv, S
347 } 366 }
348 } 367 }
349 368
  369 +#ifdef SRS_PERF_QUEUE_FAST_CACHE
350 // use fast cache if available 370 // use fast cache if available
351 if (mw_count < mw_cache->max) { 371 if (mw_count < mw_cache->max) {
352 // update fast cache timestamps 372 // update fast cache timestamps
@@ -371,6 +391,7 @@ int SrsConsumer::enqueue(SrsSharedPtrMessage* msg, bool atc, int tba, int tbv, S @@ -371,6 +391,7 @@ int SrsConsumer::enqueue(SrsSharedPtrMessage* msg, bool atc, int tba, int tbv, S
371 } 391 }
372 } 392 }
373 393
  394 + #ifdef SRS_PERF_QUEUE_COND_WAIT
374 // fire the mw when msgs is enough. 395 // fire the mw when msgs is enough.
375 if (mw_waiting) { 396 if (mw_waiting) {
376 // when fast cache not overflow, always flush. 397 // when fast cache not overflow, always flush.
@@ -385,6 +406,26 @@ int SrsConsumer::enqueue(SrsSharedPtrMessage* msg, bool atc, int tba, int tbv, S @@ -385,6 +406,26 @@ int SrsConsumer::enqueue(SrsSharedPtrMessage* msg, bool atc, int tba, int tbv, S
385 mw_waiting = false; 406 mw_waiting = false;
386 } 407 }
387 } 408 }
  409 + #endif
  410 +#else
  411 + if ((ret = queue->enqueue(msg, NULL)) != ERROR_SUCCESS) {
  412 + return ret;
  413 + }
  414 +
  415 + #ifdef SRS_PERF_QUEUE_COND_WAIT
  416 + // fire the mw when msgs is enough.
  417 + if (mw_waiting) {
  418 + int duration_ms = queue->duration();
  419 + bool match_min_msgs = queue->size() > mw_min_msgs;
  420 +
  421 + // when duration ok, signal to flush.
  422 + if (match_min_msgs && duration_ms > mw_duration) {
  423 + st_cond_signal(mw_wait);
  424 + mw_waiting = false;
  425 + }
  426 + }
  427 + #endif
  428 +#endif
388 429
389 return ret; 430 return ret;
390 } 431 }
@@ -405,6 +446,7 @@ int SrsConsumer::dump_packets(SrsMessageArray* msgs, int* count) @@ -405,6 +446,7 @@ int SrsConsumer::dump_packets(SrsMessageArray* msgs, int* count)
405 return ret; 446 return ret;
406 } 447 }
407 448
  449 +#ifdef SRS_PERF_QUEUE_FAST_CACHE
408 // only dumps an whole array to msgs. 450 // only dumps an whole array to msgs.
409 for (int i = 0; i < mw_count; i++) { 451 for (int i = 0; i < mw_count; i++) {
410 msgs->msgs[i] = mw_cache->msgs[i]; 452 msgs->msgs[i] = mw_cache->msgs[i];
@@ -420,13 +462,26 @@ int SrsConsumer::dump_packets(SrsMessageArray* msgs, int* count) @@ -420,13 +462,26 @@ int SrsConsumer::dump_packets(SrsMessageArray* msgs, int* count)
420 } 462 }
421 463
422 return dumps_queue_to_fast_cache(); 464 return dumps_queue_to_fast_cache();
  465 +#else
  466 +
  467 + // pump msgs from queue.
  468 + int nb_msgs = 0;
  469 + if ((ret = queue->dump_packets(msgs->max, msgs->msgs, nb_msgs)) != ERROR_SUCCESS) {
  470 + return ret;
  471 + }
  472 + *count = nb_msgs;
  473 +
  474 + return ret;
  475 +#endif
423 } 476 }
424 477
  478 +#ifdef SRS_PERF_QUEUE_COND_WAIT
425 void SrsConsumer::wait(int nb_msgs, int duration) 479 void SrsConsumer::wait(int nb_msgs, int duration)
426 { 480 {
427 mw_min_msgs = nb_msgs; 481 mw_min_msgs = nb_msgs;
428 mw_duration = duration; 482 mw_duration = duration;
429 483
  484 +#ifdef SRS_PERF_QUEUE_FAST_CACHE
430 // when fast cache not overflow, always flush. 485 // when fast cache not overflow, always flush.
431 // so we donot care about the queue. 486 // so we donot care about the queue.
432 bool fast_cache_overflow = mw_count >= mw_cache->max; 487 bool fast_cache_overflow = mw_count >= mw_cache->max;
@@ -437,12 +492,22 @@ void SrsConsumer::wait(int nb_msgs, int duration) @@ -437,12 +492,22 @@ void SrsConsumer::wait(int nb_msgs, int duration)
437 if (fast_cache_overflow || (match_min_msgs && duration_ms > mw_duration)) { 492 if (fast_cache_overflow || (match_min_msgs && duration_ms > mw_duration)) {
438 return; 493 return;
439 } 494 }
  495 +#else
  496 + int duration_ms = queue->duration();
  497 + bool match_min_msgs = queue->size() > mw_min_msgs;
  498 +
  499 + // when duration ok, signal to flush.
  500 + if (match_min_msgs && duration_ms > mw_duration) {
  501 + return;
  502 + }
  503 +#endif
440 504
441 // the enqueue will notify this cond. 505 // the enqueue will notify this cond.
442 mw_waiting = true; 506 mw_waiting = true;
443 // wait for msgs to incoming. 507 // wait for msgs to incoming.
444 st_cond_wait(mw_wait); 508 st_cond_wait(mw_wait);
445 } 509 }
  510 +#endif
446 511
447 int SrsConsumer::on_play_client_pause(bool is_pause) 512 int SrsConsumer::on_play_client_pause(bool is_pause)
448 { 513 {
@@ -454,6 +519,7 @@ int SrsConsumer::on_play_client_pause(bool is_pause) @@ -454,6 +519,7 @@ int SrsConsumer::on_play_client_pause(bool is_pause)
454 return ret; 519 return ret;
455 } 520 }
456 521
  522 +#ifdef SRS_PERF_QUEUE_FAST_CACHE
457 int SrsConsumer::dumps_queue_to_fast_cache() 523 int SrsConsumer::dumps_queue_to_fast_cache()
458 { 524 {
459 int ret =ERROR_SUCCESS; 525 int ret =ERROR_SUCCESS;
@@ -473,6 +539,7 @@ int SrsConsumer::dumps_queue_to_fast_cache() @@ -473,6 +539,7 @@ int SrsConsumer::dumps_queue_to_fast_cache()
473 539
474 return ret; 540 return ret;
475 } 541 }
  542 +#endif
476 543
477 SrsGopCache::SrsGopCache() 544 SrsGopCache::SrsGopCache()
478 { 545 {
@@ -36,6 +36,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -36,6 +36,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
36 36
37 #include <srs_app_st.hpp> 37 #include <srs_app_st.hpp>
38 #include <srs_app_reload.hpp> 38 #include <srs_app_reload.hpp>
  39 +#include <srs_core_performance.hpp>
39 40
40 class SrsPlayEdge; 41 class SrsPlayEdge;
41 class SrsPublishEdge; 42 class SrsPublishEdge;
@@ -117,6 +118,14 @@ public: @@ -117,6 +118,14 @@ public:
117 virtual ~SrsMessageQueue(); 118 virtual ~SrsMessageQueue();
118 public: 119 public:
119 /** 120 /**
  121 + * get the size of queue.
  122 + */
  123 + virtual int size();
  124 + /**
  125 + * get the duration of queue.
  126 + */
  127 + virtual int duration();
  128 + /**
120 * set the queue size 129 * set the queue size
121 * @param queue_size the queue size in seconds. 130 * @param queue_size the queue size in seconds.
122 */ 131 */
@@ -156,12 +165,15 @@ private: @@ -156,12 +165,15 @@ private:
156 bool paused; 165 bool paused;
157 // when source id changed, notice all consumers 166 // when source id changed, notice all consumers
158 bool should_update_source_id; 167 bool should_update_source_id;
  168 +#ifdef SRS_PERF_QUEUE_COND_WAIT
159 // the cond wait for mw. 169 // the cond wait for mw.
160 // @see https://github.com/winlinvip/simple-rtmp-server/issues/251 170 // @see https://github.com/winlinvip/simple-rtmp-server/issues/251
161 st_cond_t mw_wait; 171 st_cond_t mw_wait;
162 bool mw_waiting; 172 bool mw_waiting;
163 int mw_min_msgs; 173 int mw_min_msgs;
164 int mw_duration; 174 int mw_duration;
  175 +#endif
  176 +#ifdef SRS_PERF_QUEUE_FAST_CACHE
165 // use fast cache for msgs 177 // use fast cache for msgs
166 // @see https://github.com/winlinvip/simple-rtmp-server/issues/251 178 // @see https://github.com/winlinvip/simple-rtmp-server/issues/251
167 SrsMessageArray* mw_cache; 179 SrsMessageArray* mw_cache;
@@ -170,6 +182,7 @@ private: @@ -170,6 +182,7 @@ private:
170 // the packet time in fast cache. 182 // the packet time in fast cache.
171 int64_t mw_first_pkt; 183 int64_t mw_first_pkt;
172 int64_t mw_last_pkt; 184 int64_t mw_last_pkt;
  185 +#endif
173 public: 186 public:
174 SrsConsumer(SrsSource* _source); 187 SrsConsumer(SrsSource* _source);
175 virtual ~SrsConsumer(); 188 virtual ~SrsConsumer();
@@ -204,22 +217,26 @@ public: @@ -204,22 +217,26 @@ public:
204 * @max_count the max count to dequeue, must be positive. 217 * @max_count the max count to dequeue, must be positive.
205 */ 218 */
206 virtual int dump_packets(SrsMessageArray* msgs, int* count); 219 virtual int dump_packets(SrsMessageArray* msgs, int* count);
  220 +#ifdef SRS_PERF_QUEUE_COND_WAIT
207 /** 221 /**
208 * wait for messages incomming, atleast nb_msgs and in duration. 222 * wait for messages incomming, atleast nb_msgs and in duration.
209 * @param nb_msgs the messages count to wait. 223 * @param nb_msgs the messages count to wait.
210 * @param duration the messgae duration to wait. 224 * @param duration the messgae duration to wait.
211 */ 225 */
212 virtual void wait(int nb_msgs, int duration); 226 virtual void wait(int nb_msgs, int duration);
  227 +#endif
213 /** 228 /**
214 * when client send the pause message. 229 * when client send the pause message.
215 */ 230 */
216 virtual int on_play_client_pause(bool is_pause); 231 virtual int on_play_client_pause(bool is_pause);
217 private: 232 private:
  233 +#ifdef SRS_PERF_QUEUE_FAST_CACHE
218 /** 234 /**
219 * dumps the queue to fast cache, 235 * dumps the queue to fast cache,
220 * when fast cache is clear or queue is overflow. 236 * when fast cache is clear or queue is overflow.
221 */ 237 */
222 virtual int dumps_queue_to_fast_cache(); 238 virtual int dumps_queue_to_fast_cache();
  239 +#endif
223 }; 240 };
224 241
225 /** 242 /**
@@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 // current release version 31 // current release version
32 #define VERSION_MAJOR 2 32 #define VERSION_MAJOR 2
33 #define VERSION_MINOR 0 33 #define VERSION_MINOR 0
34 -#define VERSION_REVISION 57 34 +#define VERSION_REVISION 58
35 // server info. 35 // server info.
36 #define RTMP_SIG_SRS_KEY "SRS" 36 #define RTMP_SIG_SRS_KEY "SRS"
37 #define RTMP_SIG_SRS_ROLE "origin/edge server" 37 #define RTMP_SIG_SRS_ROLE "origin/edge server"
@@ -110,6 +110,20 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -110,6 +110,20 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
110 #define SRS_PERF_MW_MIN_MSGS 32 110 #define SRS_PERF_MW_MIN_MSGS 32
111 111
112 /** 112 /**
  113 +* whether enable the fast cache.
  114 +* @remark this improve performance for large connectios.
  115 +* @remark this also introduce complex, default to disable it.
  116 +* @see https://github.com/winlinvip/simple-rtmp-server/issues/251
  117 +*/
  118 +#undef SRS_PERF_QUEUE_FAST_CACHE
  119 +/**
  120 +* whether use cond wait to send messages.
  121 +* @remark this improve performance for large connectios.
  122 +* @see https://github.com/winlinvip/simple-rtmp-server/issues/251
  123 +*/
  124 +#undef SRS_PERF_QUEUE_COND_WAIT
  125 +
  126 +/**
113 * how many chunk stream to cache, [0, N]. 127 * how many chunk stream to cache, [0, N].
114 * to imporove about 10% performance when chunk size small, and 5% for large chunk. 128 * to imporove about 10% performance when chunk size small, and 5% for large chunk.
115 * @see https://github.com/winlinvip/simple-rtmp-server/issues/249 129 * @see https://github.com/winlinvip/simple-rtmp-server/issues/249