1*8e33eff8Schristos #include "jemalloc/internal/jemalloc_preamble.h" 2*8e33eff8Schristos #include "jemalloc/internal/jemalloc_internal_includes.h" 3*8e33eff8Schristos 4*8e33eff8Schristos #include "jemalloc/internal/log.h" 5*8e33eff8Schristos 6*8e33eff8Schristos char log_var_names[JEMALLOC_LOG_VAR_BUFSIZE]; 7*8e33eff8Schristos atomic_b_t log_init_done = ATOMIC_INIT(false); 8*8e33eff8Schristos 9*8e33eff8Schristos /* 10*8e33eff8Schristos * Returns true if we were able to pick out a segment. Fills in r_segment_end 11*8e33eff8Schristos * with a pointer to the first character after the end of the string. 12*8e33eff8Schristos */ 13*8e33eff8Schristos static const char * 14*8e33eff8Schristos log_var_extract_segment(const char* segment_begin) { 15*8e33eff8Schristos const char *end; 16*8e33eff8Schristos for (end = segment_begin; *end != '\0' && *end != '|'; end++) { 17*8e33eff8Schristos } 18*8e33eff8Schristos return end; 19*8e33eff8Schristos } 20*8e33eff8Schristos 21*8e33eff8Schristos static bool 22*8e33eff8Schristos log_var_matches_segment(const char *segment_begin, const char *segment_end, 23*8e33eff8Schristos const char *log_var_begin, const char *log_var_end) { 24*8e33eff8Schristos assert(segment_begin <= segment_end); 25*8e33eff8Schristos assert(log_var_begin < log_var_end); 26*8e33eff8Schristos 27*8e33eff8Schristos ptrdiff_t segment_len = segment_end - segment_begin; 28*8e33eff8Schristos ptrdiff_t log_var_len = log_var_end - log_var_begin; 29*8e33eff8Schristos /* The special '.' segment matches everything. */ 30*8e33eff8Schristos if (segment_len == 1 && *segment_begin == '.') { 31*8e33eff8Schristos return true; 32*8e33eff8Schristos } 33*8e33eff8Schristos if (segment_len == log_var_len) { 34*8e33eff8Schristos return strncmp(segment_begin, log_var_begin, segment_len) == 0; 35*8e33eff8Schristos } else if (segment_len < log_var_len) { 36*8e33eff8Schristos return strncmp(segment_begin, log_var_begin, segment_len) == 0 37*8e33eff8Schristos && log_var_begin[segment_len] == '.'; 38*8e33eff8Schristos } else { 39*8e33eff8Schristos return false; 40*8e33eff8Schristos } 41*8e33eff8Schristos } 42*8e33eff8Schristos 43*8e33eff8Schristos unsigned 44*8e33eff8Schristos log_var_update_state(log_var_t *log_var) { 45*8e33eff8Schristos const char *log_var_begin = log_var->name; 46*8e33eff8Schristos const char *log_var_end = log_var->name + strlen(log_var->name); 47*8e33eff8Schristos 48*8e33eff8Schristos /* Pointer to one before the beginning of the current segment. */ 49*8e33eff8Schristos const char *segment_begin = log_var_names; 50*8e33eff8Schristos 51*8e33eff8Schristos /* 52*8e33eff8Schristos * If log_init done is false, we haven't parsed the malloc conf yet. To 53*8e33eff8Schristos * avoid log-spew, we default to not displaying anything. 54*8e33eff8Schristos */ 55*8e33eff8Schristos if (!atomic_load_b(&log_init_done, ATOMIC_ACQUIRE)) { 56*8e33eff8Schristos return LOG_INITIALIZED_NOT_ENABLED; 57*8e33eff8Schristos } 58*8e33eff8Schristos 59*8e33eff8Schristos while (true) { 60*8e33eff8Schristos const char *segment_end = log_var_extract_segment( 61*8e33eff8Schristos segment_begin); 62*8e33eff8Schristos assert(segment_end < log_var_names + JEMALLOC_LOG_VAR_BUFSIZE); 63*8e33eff8Schristos if (log_var_matches_segment(segment_begin, segment_end, 64*8e33eff8Schristos log_var_begin, log_var_end)) { 65*8e33eff8Schristos atomic_store_u(&log_var->state, LOG_ENABLED, 66*8e33eff8Schristos ATOMIC_RELAXED); 67*8e33eff8Schristos return LOG_ENABLED; 68*8e33eff8Schristos } 69*8e33eff8Schristos if (*segment_end == '\0') { 70*8e33eff8Schristos /* Hit the end of the segment string with no match. */ 71*8e33eff8Schristos atomic_store_u(&log_var->state, 72*8e33eff8Schristos LOG_INITIALIZED_NOT_ENABLED, ATOMIC_RELAXED); 73*8e33eff8Schristos return LOG_INITIALIZED_NOT_ENABLED; 74*8e33eff8Schristos } 75*8e33eff8Schristos /* Otherwise, skip the delimiter and continue. */ 76*8e33eff8Schristos segment_begin = segment_end + 1; 77*8e33eff8Schristos } 78*8e33eff8Schristos } 79