diff --git a/trunk/3rdparty/st-srs/common.h b/trunk/3rdparty/st-srs/common.h index 0c0685b9a..80258b453 100644 --- a/trunk/3rdparty/st-srs/common.h +++ b/trunk/3rdparty/st-srs/common.h @@ -299,6 +299,7 @@ extern _st_eventsys_t *_st_eventsys; #define _ST_DEL_IOQ(_pq) ST_REMOVE_LINK(&_pq.links) #define _ST_ADD_RUNQ(_thr) ST_APPEND_LINK(&(_thr)->links, &_ST_RUNQ) +#define _ST_INSERT_RUNQ(_thr) ST_INSERT_LINK(&(_thr)->links, &_ST_RUNQ) #define _ST_DEL_RUNQ(_thr) ST_REMOVE_LINK(&(_thr)->links) #define _ST_ADD_SLEEPQ(_thr, _timeout) _st_add_sleep_q(_thr, _timeout) diff --git a/trunk/3rdparty/st-srs/sched.c b/trunk/3rdparty/st-srs/sched.c index e7e8da36c..aea6b555d 100644 --- a/trunk/3rdparty/st-srs/sched.c +++ b/trunk/3rdparty/st-srs/sched.c @@ -54,14 +54,14 @@ // Global stat. #ifdef DEBUG -unsigned long long _st_stat_sched_us = 0; -unsigned long long _st_stat_sched_10ms = 0; +unsigned long long _st_stat_sched_15ms = 0; unsigned long long _st_stat_sched_20ms = 0; +unsigned long long _st_stat_sched_25ms = 0; +unsigned long long _st_stat_sched_30ms = 0; +unsigned long long _st_stat_sched_35ms = 0; unsigned long long _st_stat_sched_40ms = 0; unsigned long long _st_stat_sched_80ms = 0; unsigned long long _st_stat_sched_160ms = 0; -unsigned long long _st_stat_sched_320ms = 0; -unsigned long long _st_stat_sched_1000ms = 0; unsigned long long _st_stat_sched_s = 0; unsigned long long _st_stat_thread_run = 0; @@ -504,26 +504,26 @@ void _st_vp_check_clock(void) st_utime_t elapsed, now; now = st_utime(); - elapsed = now - _ST_LAST_CLOCK; + elapsed = now < _ST_LAST_CLOCK? 0 : now - _ST_LAST_CLOCK; // Might step back. _ST_LAST_CLOCK = now; #ifdef DEBUG - if (elapsed <= 1000) { - ++_st_stat_sched_us; - } else if (elapsed <= 10000) { - ++_st_stat_sched_10ms; + if (elapsed <= 10000) { + ++_st_stat_sched_15ms; } else if (elapsed <= 21000) { ++_st_stat_sched_20ms; + } else if (elapsed <= 25000) { + ++_st_stat_sched_25ms; + } else if (elapsed <= 30000) { + ++_st_stat_sched_30ms; + } else if (elapsed <= 35000) { + ++_st_stat_sched_35ms; } else if (elapsed <= 40000) { ++_st_stat_sched_40ms; } else if (elapsed <= 80000) { ++_st_stat_sched_80ms; } else if (elapsed <= 160000) { ++_st_stat_sched_160ms; - } else if (elapsed <= 320000) { - ++_st_stat_sched_320ms; - } else if (elapsed <= 1000000) { - ++_st_stat_sched_1000ms; } else { ++_st_stat_sched_s; } @@ -548,7 +548,8 @@ void _st_vp_check_clock(void) /* Make thread runnable */ ST_ASSERT(!(thread->flags & _ST_FL_IDLE_THREAD)); thread->state = _ST_ST_RUNNABLE; - _ST_ADD_RUNQ(thread); + // Insert at the head of RunQ, to execute timer first. + _ST_INSERT_RUNQ(thread); } } diff --git a/trunk/conf/full.conf b/trunk/conf/full.conf index 142dfc233..4e0c76424 100644 --- a/trunk/conf/full.conf +++ b/trunk/conf/full.conf @@ -152,6 +152,9 @@ heartbeat { # @remark the heartbeat depends on the network, # for example, the eth0 maybe the device which index is 0. stats { + # Whether enable the stat of system resources. + # Default: on + enabled on; # the index of device ip. # we may retrieve more than one network device. # default: 0 diff --git a/trunk/research/st/.gitignore b/trunk/research/st/.gitignore index 827222cf2..95683a3be 100644 --- a/trunk/research/st/.gitignore +++ b/trunk/research/st/.gitignore @@ -1,2 +1,4 @@ udp-server udp-client +cost +cost.log diff --git a/trunk/research/st/cost.cpp b/trunk/research/st/cost.cpp index c7caeb5fa..78a71e554 100644 --- a/trunk/research/st/cost.cpp +++ b/trunk/research/st/cost.cpp @@ -1,10 +1,11 @@ /* -g++ -g -O0 cost.cpp -o cost && ./cost | grep COST +g++ -g -O0 cost.cpp ../../objs/st/libst.a -I../../objs/st -o cost && ./cost | grep COST */ #include #include #include #include +#include #define SRS_UTIME_MILLISECONDS 1000 #define srsu2i(us) ((int)(us)) @@ -143,6 +144,18 @@ int main(int argc, char** argv) ); } + // The cost for ST timer. + st_set_eventsys(ST_EVENTSYS_ALT); + st_init(); + for (;;) { + int64_t start = srs_update_system_time(); + st_usleep(20 * 1000); + int64_t cost = srs_update_system_time() - start; + if (cost > (20 + 10) * 1000) { + printf("[COST] timer=%dms\n", (int)(cost / 1000)); + } + } + return 0; } diff --git a/trunk/src/app/srs_app_config.cpp b/trunk/src/app/srs_app_config.cpp index 0d2575f3f..efd7e236b 100644 --- a/trunk/src/app/srs_app_config.cpp +++ b/trunk/src/app/srs_app_config.cpp @@ -3640,7 +3640,7 @@ srs_error_t SrsConfig::check_normal_config() SrsConfDirective* conf = get_stats(); for (int i = 0; conf && i < (int)conf->directives.size(); i++) { string n = conf->at(i)->name; - if (n != "network" && n != "disk") { + if (n != "enabled" && n != "network" && n != "disk") { return srs_error_new(ERROR_SYSTEM_CONFIG_INVALID, "illegal stats.%s", n.c_str()); } } @@ -8353,6 +8353,23 @@ SrsConfDirective* SrsConfig::get_stats() return root->get("stats"); } +bool SrsConfig::get_stats_enabled() +{ + static bool DEFAULT = true; + + SrsConfDirective* conf = get_stats(); + if (!conf) { + return DEFAULT; + } + + conf = conf->get("enabled"); + if (!conf || conf->arg0().empty()) { + return DEFAULT; + } + + return SRS_CONF_PERFER_TRUE(conf->arg0()); +} + int SrsConfig::get_stats_network() { static int DEFAULT = 0; diff --git a/trunk/src/app/srs_app_config.hpp b/trunk/src/app/srs_app_config.hpp index 485725912..507467073 100644 --- a/trunk/src/app/srs_app_config.hpp +++ b/trunk/src/app/srs_app_config.hpp @@ -1084,6 +1084,8 @@ private: // Get the stats directive. virtual SrsConfDirective* get_stats(); public: + // Whether enabled stats. + virtual bool get_stats_enabled(); // Get the network device index, used to retrieve the ip of device, // For heartbeat to report to server, or to get the local ip. // For example, 0 means the eth0 maybe. diff --git a/trunk/src/app/srs_app_hybrid.cpp b/trunk/src/app/srs_app_hybrid.cpp index 06fdc6464..941fef02b 100644 --- a/trunk/src/app/srs_app_hybrid.cpp +++ b/trunk/src/app/srs_app_hybrid.cpp @@ -83,23 +83,23 @@ SrsPps* _srs_pps_epoll_zero = new SrsPps(_srs_clock); SrsPps* _srs_pps_epoll_shake = new SrsPps(_srs_clock); SrsPps* _srs_pps_epoll_spin = new SrsPps(_srs_clock); -extern unsigned long long _st_stat_sched_us; -extern unsigned long long _st_stat_sched_10ms; +extern unsigned long long _st_stat_sched_15ms; extern unsigned long long _st_stat_sched_20ms; +extern unsigned long long _st_stat_sched_25ms; +extern unsigned long long _st_stat_sched_30ms; +extern unsigned long long _st_stat_sched_35ms; extern unsigned long long _st_stat_sched_40ms; extern unsigned long long _st_stat_sched_80ms; extern unsigned long long _st_stat_sched_160ms; -extern unsigned long long _st_stat_sched_320ms; -extern unsigned long long _st_stat_sched_1000ms; extern unsigned long long _st_stat_sched_s; -SrsPps* _srs_pps_sched_us = new SrsPps(_srs_clock); -SrsPps* _srs_pps_sched_10ms = new SrsPps(_srs_clock); +SrsPps* _srs_pps_sched_15ms = new SrsPps(_srs_clock); SrsPps* _srs_pps_sched_20ms = new SrsPps(_srs_clock); +SrsPps* _srs_pps_sched_25ms = new SrsPps(_srs_clock); +SrsPps* _srs_pps_sched_30ms = new SrsPps(_srs_clock); +SrsPps* _srs_pps_sched_35ms = new SrsPps(_srs_clock); SrsPps* _srs_pps_sched_40ms = new SrsPps(_srs_clock); SrsPps* _srs_pps_sched_80ms = new SrsPps(_srs_clock); SrsPps* _srs_pps_sched_160ms = new SrsPps(_srs_clock); -SrsPps* _srs_pps_sched_320ms = new SrsPps(_srs_clock); -SrsPps* _srs_pps_sched_1000ms = new SrsPps(_srs_clock); SrsPps* _srs_pps_sched_s = new SrsPps(_srs_clock); SrsPps* _srs_pps_clock_15ms = new SrsPps(_srs_clock); @@ -112,6 +112,7 @@ SrsPps* _srs_pps_clock_80ms = new SrsPps(_srs_clock); SrsPps* _srs_pps_clock_160ms = new SrsPps(_srs_clock); SrsPps* _srs_pps_timer_s = new SrsPps(_srs_clock); +extern int _st_active_count; extern unsigned long long _st_stat_thread_run; extern unsigned long long _st_stat_thread_idle; SrsPps* _srs_pps_thread_run = new SrsPps(_srs_clock); @@ -277,6 +278,9 @@ SrsServerAdapter* SrsHybridServer::srs() return NULL; } +extern void _srs_coroutine_switch_in(); +extern void _srs_coroutine_switch_out(); + srs_error_t SrsHybridServer::setup_ticks() { srs_error_t err = srs_success; @@ -401,13 +405,13 @@ srs_error_t SrsHybridServer::notify(int event, srs_utime_t interval, srs_utime_t } string sched_desc; - _srs_pps_sched_us->update(_st_stat_sched_us); _srs_pps_sched_s->update(_st_stat_sched_s); - _srs_pps_sched_10ms->update(_st_stat_sched_10ms); _srs_pps_sched_20ms->update(_st_stat_sched_20ms); - _srs_pps_sched_40ms->update(_st_stat_sched_40ms); _srs_pps_sched_80ms->update(_st_stat_sched_80ms); - _srs_pps_sched_160ms->update(_st_stat_sched_160ms); _srs_pps_sched_320ms->update(_st_stat_sched_320ms); - _srs_pps_sched_1000ms->update(_st_stat_sched_1000ms); - if (_srs_pps_sched_us->r10s() || _srs_pps_sched_s->r10s() || _srs_pps_sched_10ms->r10s() || _srs_pps_sched_20ms->r10s() || _srs_pps_sched_40ms->r10s() || _srs_pps_sched_80ms->r10s() || _srs_pps_sched_160ms->r10s() || _srs_pps_sched_320ms->r10s() || _srs_pps_sched_1000ms->r10s()) { - snprintf(buf, sizeof(buf), ", sched=%d,%d,%d,%d,%d,%d,%d,%d,%d", _srs_pps_sched_us->r10s(), _srs_pps_sched_10ms->r10s(), _srs_pps_sched_20ms->r10s(), _srs_pps_sched_40ms->r10s(), _srs_pps_sched_80ms->r10s(), _srs_pps_sched_160ms->r10s(), _srs_pps_sched_320ms->r10s(), _srs_pps_sched_1000ms->r10s(), _srs_pps_sched_s->r10s()); + _srs_pps_sched_160ms->update(_st_stat_sched_160ms); _srs_pps_sched_s->update(_st_stat_sched_s); + _srs_pps_sched_15ms->update(_st_stat_sched_15ms); _srs_pps_sched_20ms->update(_st_stat_sched_20ms); + _srs_pps_sched_25ms->update(_st_stat_sched_25ms); _srs_pps_sched_30ms->update(_st_stat_sched_30ms); + _srs_pps_sched_35ms->update(_st_stat_sched_35ms); _srs_pps_sched_40ms->update(_st_stat_sched_40ms); + _srs_pps_sched_80ms->update(_st_stat_sched_80ms); + if (_srs_pps_sched_160ms->r10s() || _srs_pps_sched_s->r10s() || _srs_pps_sched_15ms->r10s() || _srs_pps_sched_20ms->r10s() || _srs_pps_sched_25ms->r10s() || _srs_pps_sched_30ms->r10s() || _srs_pps_sched_35ms->r10s() || _srs_pps_sched_40ms->r10s() || _srs_pps_sched_80ms->r10s()) { + snprintf(buf, sizeof(buf), ", sched=%d,%d,%d,%d,%d,%d,%d,%d,%d", _srs_pps_sched_15ms->r10s(), _srs_pps_sched_20ms->r10s(), _srs_pps_sched_25ms->r10s(), _srs_pps_sched_30ms->r10s(), _srs_pps_sched_35ms->r10s(), _srs_pps_sched_40ms->r10s(), _srs_pps_sched_80ms->r10s(), _srs_pps_sched_160ms->r10s(), _srs_pps_sched_s->r10s()); sched_desc = buf; } @@ -424,8 +428,8 @@ srs_error_t SrsHybridServer::notify(int event, srs_utime_t interval, srs_utime_t string thread_desc; _srs_pps_thread_run->update(_st_stat_thread_run); _srs_pps_thread_idle->update(_st_stat_thread_idle); - if (_srs_pps_thread_run->r10s() || _srs_pps_thread_idle->r10s()) { - snprintf(buf, sizeof(buf), ", co=%d,%d", _srs_pps_thread_run->r10s(), _srs_pps_thread_idle->r10s()); + if (_st_active_count > 0 || _srs_pps_thread_run->r10s() || _srs_pps_thread_idle->r10s()) { + snprintf(buf, sizeof(buf), ", co=%d,%d,%d", _st_active_count, _srs_pps_thread_run->r10s(), _srs_pps_thread_idle->r10s()); thread_desc = buf; } diff --git a/trunk/src/app/srs_app_server.cpp b/trunk/src/app/srs_app_server.cpp index 9be2a3bef..5bfe48111 100644 --- a/trunk/src/app/srs_app_server.cpp +++ b/trunk/src/app/srs_app_server.cpp @@ -1270,27 +1270,31 @@ srs_error_t SrsServer::setup_ticks() srs_freep(timer_); timer_ = new SrsHourGlass("srs", this, 1 * SRS_UTIME_SECONDS); - if ((err = timer_->tick(2, 3 * SRS_UTIME_SECONDS)) != srs_success) { - return srs_error_wrap(err, "tick"); - } - if ((err = timer_->tick(3, 3 * SRS_UTIME_SECONDS)) != srs_success) { - return srs_error_wrap(err, "tick"); - } - if ((err = timer_->tick(4, 6 * SRS_UTIME_SECONDS)) != srs_success) { - return srs_error_wrap(err, "tick"); - } - if ((err = timer_->tick(5, 6 * SRS_UTIME_SECONDS)) != srs_success) { - return srs_error_wrap(err, "tick"); - } - if ((err = timer_->tick(6, 9 * SRS_UTIME_SECONDS)) != srs_success) { - return srs_error_wrap(err, "tick"); - } - if ((err = timer_->tick(7, 9 * SRS_UTIME_SECONDS)) != srs_success) { - return srs_error_wrap(err, "tick"); - } - if ((err = timer_->tick(8, 3 * SRS_UTIME_SECONDS)) != srs_success) { - return srs_error_wrap(err, "tick"); + if (_srs_config->get_stats_enabled()) { + if ((err = timer_->tick(2, 3 * SRS_UTIME_SECONDS)) != srs_success) { + return srs_error_wrap(err, "tick"); + } + if ((err = timer_->tick(3, 3 * SRS_UTIME_SECONDS)) != srs_success) { + return srs_error_wrap(err, "tick"); + } + if ((err = timer_->tick(4, 6 * SRS_UTIME_SECONDS)) != srs_success) { + return srs_error_wrap(err, "tick"); + } + if ((err = timer_->tick(5, 6 * SRS_UTIME_SECONDS)) != srs_success) { + return srs_error_wrap(err, "tick"); + } + if ((err = timer_->tick(6, 9 * SRS_UTIME_SECONDS)) != srs_success) { + return srs_error_wrap(err, "tick"); + } + if ((err = timer_->tick(7, 9 * SRS_UTIME_SECONDS)) != srs_success) { + return srs_error_wrap(err, "tick"); + } + + if ((err = timer_->tick(8, 3 * SRS_UTIME_SECONDS)) != srs_success) { + return srs_error_wrap(err, "tick"); + } } + if (_srs_config->get_heartbeat_enabled()) { if ((err = timer_->tick(9, _srs_config->get_heartbeat_interval())) != srs_success) { return srs_error_wrap(err, "tick"); diff --git a/trunk/src/protocol/srs_protocol_kbps.cpp b/trunk/src/protocol/srs_protocol_kbps.cpp index 2ae0f11aa..b0d4bfa0f 100644 --- a/trunk/src/protocol/srs_protocol_kbps.cpp +++ b/trunk/src/protocol/srs_protocol_kbps.cpp @@ -43,6 +43,13 @@ SrsRateSample* SrsRateSample::update(int64_t nn, srs_utime_t t, int k) return this; } +void srs_pps_init(SrsRateSample& sample, int64_t nn, srs_utime_t now) +{ + if (sample.time < 0 || nn < sample.total) { + sample.update(nn, now, 0); + } +} + void srs_pps_update(SrsRateSample& sample, int64_t nn, srs_utime_t now) { int pps = (int)((nn - sample.total) * 1000 / srsu2ms(now - sample.time)); @@ -71,18 +78,11 @@ void SrsPps::update(int64_t nn) { srs_utime_t now = clk_->now(); - if (sample_30s_.time < 0) { - sample_30s_.update(nn, now, 0); - } - if (sample_1m_.time < 0) { - sample_1m_.update(nn, now, 0); - } - if (sample_5m_.time < 0) { - sample_5m_.update(nn, now, 0); - } - if (sample_60m_.time < 0) { - sample_60m_.update(nn, now, 0); - } + srs_pps_init(sample_10s_, nn, now); + srs_pps_init(sample_30s_, nn, now); + srs_pps_init(sample_1m_, nn, now); + srs_pps_init(sample_5m_, nn, now); + srs_pps_init(sample_60m_, nn, now); if (now - sample_10s_.time >= 10 * SRS_UTIME_SECONDS) { srs_pps_update(sample_10s_, nn, now);