#pragma once // Objects life management // // created on 2022-11-29 // #include #include #define ALIGN_INT(val, n) ((((val) + (n) - 1) / (n)) * (n)) #define SIZE_KB(n) ((n) * 1024) #define SIZE_MB(n) SIZE_KB((n) * 1024) #define SIZE_GB(n) SIZE_MB((n) * 1024) #define WAIT_INFINITE 0 #define SEC_2_MS(s) ((s) * 1000) #define MSEC_2_US(ms) ((ms) * 1000) #define USEC_2_NS(us) ((us) * 1000) #define SEC_2_US(s) MSEC_2_US(SEC_2_MS(s)) #define SEC_2_NS(s) USEC_2_NS(MSEC_2_US(SEC_2_MS(s))) #define MSEC_2_NS(ms) USEC_2_NS(MSEC_2_US(ms)) //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// typedef std::mutex MUTEX; typedef std::lock_guard LOCKER; // object life referer // // derived from 'refer' if your class used in multi-threads // class refer { volatile int32_t ref_; MUTEX mutex_; protected: refer(); virtual ~refer(); virtual void on_born(void); virtual void on_dead(void); public: virtual int32_t add_ref(void); virtual int32_t release(void); }; #include class chronograph { struct timeval bgn_; public: chronograph(); ~chronograph(); static bool now(struct timeval* tv); static bool now(uint64_t* seconds, uint64_t* u_seconds); static std::string now(bool with_ms = true/*whether with milliseconds*/); // return '2022-11-30 10:38:42.123', no '.123' if with_ms was false public: uint64_t elapse_s(void); uint64_t elapse_ms(void); uint64_t elapse_us(void); void reset(void); }; #include namespace sys_util { int32_t enum_modules(bool(*on_found)(const char* path_module_name, bool is_dir, void* param),// return false to stop enumeratin void* param, // user defined data, passed into callback on_found unsigned pid = -1 // process id, -1 is self ); // return errno int32_t enum_files(const char* dir // dir path , bool(*on_found)(const char* path_name, bool is_dir, void* param)// return false to stop enumeratin , void* param // user defined data, passed into callback on_found , bool recursive = true // walk recursive ); // return errno int32_t enum_processes(bool(*on_found)(uint64_t pid, const char* path_name, void* param), void* param); uint32_t enum_threads(uint64_t pid, bool(*on_found)(uint64_t tid, void* start_addr, void* param), void* param); uint32_t get_thread_callstack(uint64_t pid, uint64_t tid, bool(*on_found)(uint64_t off, const char* module, void* param), void* param); uint32_t read_line(const char* file, bool(*on_line)(char* line, void* param), void* param); std::string get_module_path(const char* module_name = nullptr , unsigned pid = -1); // get module full path, nullptr is for main-exe std::string read_link(const char* lnk); size_t get_page_size(void); bool create_folder(const char* dir); // Function: pick single-line info file data, return count of set-value variable // // Parameters: file - full path of local file // // line_max - max bytes of a line in file 'file' // // fmt - line fromat string, e.g. "model name : %60[\x20-\x7e]", "MemoryTotal: %ld", "address sizes : %d bits physical, %d bits virtual", ... // // args - variable list // // Return: count of the variable which got the value template int32_t get_inf_file_data(const char* file, size_t line_max, const char* fmt, Args ... args) { std::string buf("\0", line_max + 8); FILE* src = fopen(file, "rb"); int32_t count = 0; if (!src) return 0; while (fgets(&buf[0], line_max, src)) { count = sscanf(&buf[0], fmt, args ...); if (count > 0) break; } fclose(src); return count; } int32_t get_memory_info(uint64_t* total, uint64_t* available); std::string format_readable_bytes(uint64_t bytes); // convert to readable text: 512B, 1.21KB, 1.10MB, 3.45GB, 1,234.56GB ... std::string get_command_output(const char* cmd, uint16_t max_line_len = 256, bool one_line = true); // trim string, return whether space trimmed bool trim_left(std::string& str, const char* space = " \t"); bool trim_right(std::string& str, const char* space = " \t"); uint64_t from_hex_str(const char* hex, const char** end = nullptr); // convert 0x100 to 256. parameter 'end' to receive the stopped position // Function: convert number string to integer, support hex, dec, oct and bin // // Parameter: str - number string. // 0x.../...h: as hexadecimal // ...o: as octonary // ...b: as binary // ...: as decimal, or as hexadecimal if has hex letter // // end - to receive the ending point when covert over // // Return: integer, default is ZERO, you should check the ending point when this value returned uint64_t to_int(const char* str, const char** end = nullptr); std::string transform_between_gbk_and_utf8(const char* in, bool to_utf8, int* err = nullptr); std::string transform_between_utf16_and_utf8(const char* in, size_t bytes, bool to_utf8); std::string to_abs_path(const char* base, const char* rel_path); std::string to_rel_path(const char* base, const char* abs_path); // Function: pick simple block in pair chars // // Parameter: head - beginning of the string, and the first character is the beginning char // // end - ending character of the block // // Return: the last positoin of the block (*ret = end), or nullptr if not matched const char* pick_simple_block(const char* head, char end); }