bool operator()(int* stat) const { if (s_ever_reached_fd_scan_limit.load(butil::memory_order_relaxed)) { // Never update the count again. return false; } const int count = get_fd_count(MAX_FD_SCAN_COUNT); if (count < 0) { return false; } if (count == MAX_FD_SCAN_COUNT - 2 && s_ever_reached_fd_scan_limit.exchange( true, butil::memory_order_relaxed) == false) { // Rename the bvar to notify user. g_fd_num.hide(); g_fd_num.expose("process_fd_num_too_many"); } *stat = count; return true; }
static int GetUserCodeInPlace(void*) { return g_usercode_inplace.load(butil::memory_order_relaxed); }
// Update global stuff periodically. static void* GlobalUpdate(void*) { // Expose variables. bvar::PassiveStatus<int64_t> var_iobuf_block_count( "iobuf_block_count", GetIOBufBlockCount, NULL); bvar::PassiveStatus<int64_t> var_iobuf_block_count_hit_tls_threshold( "iobuf_block_count_hit_tls_threshold", GetIOBufBlockCountHitTLSThreshold, NULL); bvar::PassiveStatus<int64_t> var_iobuf_new_bigview_count( GetIOBufNewBigViewCount, NULL); bvar::PerSecond<bvar::PassiveStatus<int64_t> > var_iobuf_new_bigview_second( "iobuf_newbigview_second", &var_iobuf_new_bigview_count); bvar::PassiveStatus<int64_t> var_iobuf_block_memory( "iobuf_block_memory", GetIOBufBlockMemory, NULL); bvar::PassiveStatus<int> var_running_server_count( "rpc_server_count", GetRunningServerCount, NULL); butil::FileWatcher fw; if (fw.init_from_not_exist(DUMMY_SERVER_PORT_FILE) < 0) { LOG(FATAL) << "Fail to init FileWatcher on `" << DUMMY_SERVER_PORT_FILE << "'"; return NULL; } std::vector<SocketId> conns; const int64_t start_time_us = butil::gettimeofday_us(); const int WARN_NOSLEEP_THRESHOLD = 2; int64_t last_time_us = start_time_us; int consecutive_nosleep = 0; int64_t last_return_free_memory_time = start_time_us; while (1) { const int64_t sleep_us = 1000000L + last_time_us - butil::gettimeofday_us(); if (sleep_us > 0) { if (bthread_usleep(sleep_us) < 0) { PLOG_IF(FATAL, errno != ESTOP) << "Fail to sleep"; break; } consecutive_nosleep = 0; } else { if (++consecutive_nosleep >= WARN_NOSLEEP_THRESHOLD) { consecutive_nosleep = 0; LOG(WARNING) << __FUNCTION__ << " is too busy!"; } } last_time_us = butil::gettimeofday_us(); TrackMe(); if (!IsDummyServerRunning() && g_running_server_count.load(butil::memory_order_relaxed) == 0 && fw.check_and_consume() > 0) { long port = ReadPortOfDummyServer(DUMMY_SERVER_PORT_FILE); if (port >= 0) { StartDummyServerAt(port); } } SocketMapList(&conns); const int64_t now_ms = butil::cpuwide_time_ms(); for (size_t i = 0; i < conns.size(); ++i) { SocketUniquePtr ptr; if (Socket::Address(conns[i], &ptr) == 0) { ptr->UpdateStatsEverySecond(now_ms); } } const int return_mem_interval = FLAGS_free_memory_to_system_interval/*reloadable*/; if (return_mem_interval > 0 && last_time_us >= last_return_free_memory_time + return_mem_interval * 1000000L) { last_return_free_memory_time = last_time_us; // TODO: Calling MallocExtension::instance()->ReleaseFreeMemory may // crash the program in later calls to malloc, verified on tcmalloc // 1.7 and 2.5, which means making the static member function weak // in details/tcmalloc_extension.cpp is probably not correct, however // it does work for heap profilers. if (MallocExtension_ReleaseFreeMemory != NULL) { MallocExtension_ReleaseFreeMemory(); } else { #if defined(OS_LINUX) // GNU specific. malloc_trim(10 * 1024 * 1024/*leave 10M pad*/); #endif } } } return NULL; }
static int GetRunningServerCount(void*) { return g_running_server_count.load(butil::memory_order_relaxed); }