Added JSON output for lock stats.
Also added option 'x' to malloc_stats() to bypass lock section.
This commit is contained in:
parent
ca9074deff
commit
bd2006a41b
@ -430,7 +430,8 @@ for (i = 0; i < nbins; i++) {
|
|||||||
can be specified to omit merged arena, destroyed merged arena, and per
|
can be specified to omit merged arena, destroyed merged arena, and per
|
||||||
arena statistics, respectively; <quote>b</quote> and <quote>l</quote> can
|
arena statistics, respectively; <quote>b</quote> and <quote>l</quote> can
|
||||||
be specified to omit per size class statistics for bins and large objects,
|
be specified to omit per size class statistics for bins and large objects,
|
||||||
respectively. Unrecognized characters are silently ignored. Note that
|
respectively; <quote>x</quote> can be specified to omit all mutex
|
||||||
|
statistics. Unrecognized characters are silently ignored. Note that
|
||||||
thread caching may prevent some statistics from being completely up to
|
thread caching may prevent some statistics from being completely up to
|
||||||
date, since extra locking would be required to merge counters that track
|
date, since extra locking would be required to merge counters that track
|
||||||
thread cache operations.</para>
|
thread cache operations.</para>
|
||||||
|
@ -960,7 +960,9 @@ ctl_refresh(tsdn_t *tsdn) {
|
|||||||
malloc_mutex_unlock(tsdn, &mtx);
|
malloc_mutex_unlock(tsdn, &mtx);
|
||||||
|
|
||||||
READ_GLOBAL_MUTEX_PROF_DATA(b0get()->mtx, base_mtx_data);
|
READ_GLOBAL_MUTEX_PROF_DATA(b0get()->mtx, base_mtx_data);
|
||||||
READ_GLOBAL_MUTEX_PROF_DATA(bt2gctx_mtx, prof_mtx_data);
|
if (config_prof && opt_prof) {
|
||||||
|
READ_GLOBAL_MUTEX_PROF_DATA(bt2gctx_mtx, prof_mtx_data);
|
||||||
|
}
|
||||||
/* We own ctl mutex already. */
|
/* We own ctl mutex already. */
|
||||||
malloc_lock_prof_read(tsdn, &ctl_stats->ctl_mtx_data, &ctl_mtx);
|
malloc_lock_prof_read(tsdn, &ctl_stats->ctl_mtx_data, &ctl_mtx);
|
||||||
#undef READ_GLOBAL_MUTEX_PROF_DATA
|
#undef READ_GLOBAL_MUTEX_PROF_DATA
|
||||||
|
154
src/stats.c
154
src/stats.c
@ -57,6 +57,25 @@ get_rate_str(uint64_t dividend, uint64_t divisor, char str[6]) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gen_lock_ctl_str(char *str, const char *prefix, const char *lock,
|
||||||
|
const char *counter) {
|
||||||
|
sprintf(str, "stats.%s.%s.%s", prefix, lock, counter);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
read_arena_bin_lock_stats(unsigned arena_ind, unsigned bin_ind,
|
||||||
|
uint64_t results[NUM_LOCK_PROF_COUNTERS]) {
|
||||||
|
char cmd[128];
|
||||||
|
|
||||||
|
unsigned i;
|
||||||
|
for (i = 0; i < NUM_LOCK_PROF_COUNTERS; i++) {
|
||||||
|
gen_lock_ctl_str(cmd, "arenas.0.bins.0","lock",
|
||||||
|
lock_counter_names[i]);
|
||||||
|
CTL_M2_M4_GET(cmd, arena_ind, bin_ind, &results[i], uint64_t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
stats_arena_bins_print(void (*write_cb)(void *, const char *), void *cbopaque,
|
stats_arena_bins_print(void (*write_cb)(void *, const char *), void *cbopaque,
|
||||||
bool json, bool large, unsigned i) {
|
bool json, bool large, unsigned i) {
|
||||||
@ -127,16 +146,10 @@ stats_arena_bins_print(void (*write_cb)(void *, const char *), void *cbopaque,
|
|||||||
CTL_M2_M4_GET("stats.arenas.0.bins.0.curslabs", i, j, &curslabs,
|
CTL_M2_M4_GET("stats.arenas.0.bins.0.curslabs", i, j, &curslabs,
|
||||||
size_t);
|
size_t);
|
||||||
|
|
||||||
/* Output less info for bin locks to save space. */
|
|
||||||
uint64_t num_ops, num_wait, max_wait;
|
|
||||||
CTL_M2_M4_GET("stats.arenas.0.bins.0.lock.num_wait", i, j,
|
|
||||||
&num_wait, uint64_t);
|
|
||||||
CTL_M2_M4_GET("stats.arenas.0.bins.0.lock.max_wait_time", i, j,
|
|
||||||
&max_wait, uint64_t);
|
|
||||||
CTL_M2_M4_GET("stats.arenas.0.bins.0.lock.num_ops", i, j,
|
|
||||||
&num_ops, uint64_t);
|
|
||||||
|
|
||||||
if (json) {
|
if (json) {
|
||||||
|
uint64_t lock_stats[NUM_LOCK_PROF_COUNTERS];
|
||||||
|
read_arena_bin_lock_stats(i, j, lock_stats);
|
||||||
|
|
||||||
malloc_cprintf(write_cb, cbopaque,
|
malloc_cprintf(write_cb, cbopaque,
|
||||||
"\t\t\t\t\t{\n"
|
"\t\t\t\t\t{\n"
|
||||||
"\t\t\t\t\t\t\"nmalloc\": %"FMTu64",\n"
|
"\t\t\t\t\t\t\"nmalloc\": %"FMTu64",\n"
|
||||||
@ -156,10 +169,21 @@ stats_arena_bins_print(void (*write_cb)(void *, const char *), void *cbopaque,
|
|||||||
}
|
}
|
||||||
malloc_cprintf(write_cb, cbopaque,
|
malloc_cprintf(write_cb, cbopaque,
|
||||||
"\t\t\t\t\t\t\"nreslabs\": %"FMTu64",\n"
|
"\t\t\t\t\t\t\"nreslabs\": %"FMTu64",\n"
|
||||||
"\t\t\t\t\t\t\"curslabs\": %zu\n"
|
"\t\t\t\t\t\t\"curslabs\": %zu,\n"
|
||||||
"\t\t\t\t\t}%s\n",
|
"\t\t\t\t\t\t\"lock\": {\n",
|
||||||
nreslabs,
|
nreslabs,
|
||||||
curslabs,
|
curslabs);
|
||||||
|
|
||||||
|
for (unsigned k = 0; k < NUM_LOCK_PROF_COUNTERS; k++) {
|
||||||
|
malloc_cprintf(write_cb, cbopaque,
|
||||||
|
"\t\t\t\t\t\t\t\"%s\": %"FMTu64"%s\n",
|
||||||
|
lock_counter_names[k], lock_stats[k],
|
||||||
|
k == NUM_LOCK_PROF_COUNTERS - 1 ? "" : ",");
|
||||||
|
}
|
||||||
|
|
||||||
|
malloc_cprintf(write_cb, cbopaque,
|
||||||
|
"\t\t\t\t\t\t}\n"
|
||||||
|
"\t\t\t\t\t}%s\n",
|
||||||
(j + 1 < nbins) ? "," : "");
|
(j + 1 < nbins) ? "," : "");
|
||||||
} else if (!in_gap) {
|
} else if (!in_gap) {
|
||||||
size_t availregs = nregs * curslabs;
|
size_t availregs = nregs * curslabs;
|
||||||
@ -183,6 +207,16 @@ stats_arena_bins_print(void (*write_cb)(void *, const char *), void *cbopaque,
|
|||||||
not_reached();
|
not_reached();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* Output less info for bin locks to save space. */
|
||||||
|
uint64_t num_ops, num_wait, max_wait;
|
||||||
|
CTL_M2_M4_GET("stats.arenas.0.bins.0.lock.num_wait",
|
||||||
|
i, j, &num_wait, uint64_t);
|
||||||
|
CTL_M2_M4_GET(
|
||||||
|
"stats.arenas.0.bins.0.lock.max_wait_time", i, j,
|
||||||
|
&max_wait, uint64_t);
|
||||||
|
CTL_M2_M4_GET("stats.arenas.0.bins.0.lock.num_ops",
|
||||||
|
i, j, &num_ops, uint64_t);
|
||||||
|
|
||||||
char rate[6];
|
char rate[6];
|
||||||
if (get_rate_str(num_wait, num_ops, rate)) {
|
if (get_rate_str(num_wait, num_ops, rate)) {
|
||||||
if (num_ops == 0) {
|
if (num_ops == 0) {
|
||||||
@ -291,12 +325,7 @@ stats_arena_lextents_print(void (*write_cb)(void *, const char *),
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gen_lock_ctl_str(char *str, const char *prefix, const char *lock,
|
read_arena_lock_stats(unsigned arena_ind,
|
||||||
const char *counter) {
|
|
||||||
sprintf(str, "stats.%s.%s.%s", prefix, lock, counter);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void read_arena_lock_stats(unsigned arena_ind,
|
|
||||||
uint64_t results[NUM_ARENA_PROF_LOCKS][NUM_LOCK_PROF_COUNTERS]) {
|
uint64_t results[NUM_ARENA_PROF_LOCKS][NUM_LOCK_PROF_COUNTERS]) {
|
||||||
char cmd[128];
|
char cmd[128];
|
||||||
|
|
||||||
@ -310,8 +339,24 @@ static void read_arena_lock_stats(unsigned arena_ind,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void lock_stats_output(void (*write_cb)(void *, const char *),
|
static void
|
||||||
void *cbopaque, const char *name, uint64_t stats[NUM_LOCK_PROF_COUNTERS],
|
lock_stats_output_json(void (*write_cb)(void *, const char *), void *cbopaque,
|
||||||
|
const char *name, uint64_t stats[NUM_LOCK_PROF_COUNTERS],
|
||||||
|
const char *json_indent, bool last) {
|
||||||
|
|
||||||
|
malloc_cprintf(write_cb, cbopaque, "%s\"%s\": {\n", json_indent, name);
|
||||||
|
for (unsigned i = 0; i < NUM_LOCK_PROF_COUNTERS; i++) {
|
||||||
|
malloc_cprintf(write_cb, cbopaque, "%s\t\"%s\": %"FMTu64"%s\n",
|
||||||
|
json_indent, lock_counter_names[i], stats[i],
|
||||||
|
i < (NUM_LOCK_PROF_COUNTERS - 1) ? "," : "");
|
||||||
|
}
|
||||||
|
malloc_cprintf(write_cb, cbopaque, "%s}%s\n", json_indent,
|
||||||
|
last ? "" : ",");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
lock_stats_output(void (*write_cb)(void *, const char *), void *cbopaque,
|
||||||
|
const char *name, uint64_t stats[NUM_LOCK_PROF_COUNTERS],
|
||||||
bool first_mutex) {
|
bool first_mutex) {
|
||||||
if (first_mutex) {
|
if (first_mutex) {
|
||||||
/* Print title. */
|
/* Print title. */
|
||||||
@ -333,25 +378,31 @@ static void lock_stats_output(void (*write_cb)(void *, const char *),
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
stats_arena_locks_print(void (*write_cb)(void *, const char *),
|
stats_arena_locks_print(void (*write_cb)(void *, const char *),
|
||||||
void *cbopaque, bool json, unsigned arena_ind) {
|
void *cbopaque, bool json, bool json_end, unsigned arena_ind) {
|
||||||
uint64_t lock_stats[NUM_ARENA_PROF_LOCKS][NUM_LOCK_PROF_COUNTERS];
|
uint64_t lock_stats[NUM_ARENA_PROF_LOCKS][NUM_LOCK_PROF_COUNTERS];
|
||||||
read_arena_lock_stats(arena_ind, lock_stats);
|
read_arena_lock_stats(arena_ind, lock_stats);
|
||||||
|
|
||||||
/* Output lock stats. */
|
/* Output lock stats. */
|
||||||
if (json) {
|
if (json) {
|
||||||
//TODO
|
malloc_cprintf(write_cb, cbopaque, "\t\t\t\t\"locks\": {\n");
|
||||||
|
for (unsigned i = 0; i < NUM_ARENA_PROF_LOCKS; i++) {
|
||||||
|
lock_stats_output_json(write_cb, cbopaque,
|
||||||
|
arena_lock_names[i], lock_stats[i],
|
||||||
|
"\t\t\t\t\t", (i == NUM_ARENA_PROF_LOCKS - 1));
|
||||||
|
}
|
||||||
|
malloc_cprintf(write_cb, cbopaque, "\t\t\t\t}%s\n",
|
||||||
|
json_end ? "" : ",");
|
||||||
} else {
|
} else {
|
||||||
for (unsigned i = 0; i < NUM_ARENA_PROF_LOCKS; i++) {
|
for (unsigned i = 0; i < NUM_ARENA_PROF_LOCKS; i++) {
|
||||||
lock_stats_output(write_cb, cbopaque,
|
lock_stats_output(write_cb, cbopaque,
|
||||||
arena_lock_names[i], lock_stats[i], i == 0);
|
arena_lock_names[i], lock_stats[i], i == 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
stats_arena_print(void (*write_cb)(void *, const char *), void *cbopaque,
|
stats_arena_print(void (*write_cb)(void *, const char *), void *cbopaque,
|
||||||
bool json, unsigned i, bool bins, bool large) {
|
bool json, unsigned i, bool bins, bool large, bool lock) {
|
||||||
unsigned nthreads;
|
unsigned nthreads;
|
||||||
const char *dss;
|
const char *dss;
|
||||||
ssize_t dirty_decay_time, muzzy_decay_time;
|
ssize_t dirty_decay_time, muzzy_decay_time;
|
||||||
@ -573,14 +624,17 @@ stats_arena_print(void (*write_cb)(void *, const char *), void *cbopaque,
|
|||||||
CTL_M2_GET("stats.arenas.0.resident", i, &resident, size_t);
|
CTL_M2_GET("stats.arenas.0.resident", i, &resident, size_t);
|
||||||
if (json) {
|
if (json) {
|
||||||
malloc_cprintf(write_cb, cbopaque,
|
malloc_cprintf(write_cb, cbopaque,
|
||||||
"\t\t\t\t\"resident\": %zu%s\n", resident, (bins || large) ?
|
"\t\t\t\t\"resident\": %zu%s\n", resident,
|
||||||
"," : "");
|
(bins || large || lock) ? "," : "");
|
||||||
} else {
|
} else {
|
||||||
malloc_cprintf(write_cb, cbopaque,
|
malloc_cprintf(write_cb, cbopaque,
|
||||||
"resident: %12zu\n", resident);
|
"resident: %12zu\n", resident);
|
||||||
}
|
}
|
||||||
|
|
||||||
stats_arena_locks_print(write_cb, cbopaque, json, i);
|
if (lock) {
|
||||||
|
stats_arena_locks_print(write_cb, cbopaque, json,
|
||||||
|
!(bins || large), i);
|
||||||
|
}
|
||||||
if (bins) {
|
if (bins) {
|
||||||
stats_arena_bins_print(write_cb, cbopaque, json, large, i);
|
stats_arena_bins_print(write_cb, cbopaque, json, large, i);
|
||||||
}
|
}
|
||||||
@ -956,7 +1010,7 @@ static void read_global_lock_stats(
|
|||||||
static void
|
static void
|
||||||
stats_print_helper(void (*write_cb)(void *, const char *), void *cbopaque,
|
stats_print_helper(void (*write_cb)(void *, const char *), void *cbopaque,
|
||||||
bool json, bool merged, bool destroyed, bool unmerged, bool bins,
|
bool json, bool merged, bool destroyed, bool unmerged, bool bins,
|
||||||
bool large) {
|
bool large, bool lock) {
|
||||||
size_t allocated, active, metadata, resident, mapped, retained;
|
size_t allocated, active, metadata, resident, mapped, retained;
|
||||||
|
|
||||||
CTL_GET("stats.allocated", &allocated, size_t);
|
CTL_GET("stats.allocated", &allocated, size_t);
|
||||||
@ -967,7 +1021,9 @@ stats_print_helper(void (*write_cb)(void *, const char *), void *cbopaque,
|
|||||||
CTL_GET("stats.retained", &retained, size_t);
|
CTL_GET("stats.retained", &retained, size_t);
|
||||||
|
|
||||||
uint64_t lock_stats[NUM_GLOBAL_PROF_LOCKS][NUM_LOCK_PROF_COUNTERS];
|
uint64_t lock_stats[NUM_GLOBAL_PROF_LOCKS][NUM_LOCK_PROF_COUNTERS];
|
||||||
read_global_lock_stats(lock_stats);
|
if (lock) {
|
||||||
|
read_global_lock_stats(lock_stats);
|
||||||
|
}
|
||||||
|
|
||||||
if (json) {
|
if (json) {
|
||||||
malloc_cprintf(write_cb, cbopaque,
|
malloc_cprintf(write_cb, cbopaque,
|
||||||
@ -984,19 +1040,31 @@ stats_print_helper(void (*write_cb)(void *, const char *), void *cbopaque,
|
|||||||
malloc_cprintf(write_cb, cbopaque,
|
malloc_cprintf(write_cb, cbopaque,
|
||||||
"\t\t\t\"mapped\": %zu,\n", mapped);
|
"\t\t\t\"mapped\": %zu,\n", mapped);
|
||||||
malloc_cprintf(write_cb, cbopaque,
|
malloc_cprintf(write_cb, cbopaque,
|
||||||
"\t\t\t\"retained\": %zu\n", retained);
|
"\t\t\t\"retained\": %zu,\n", retained);
|
||||||
|
if (lock) {
|
||||||
|
malloc_cprintf(write_cb, cbopaque,
|
||||||
|
"\t\t\t\"locks\": {\n");
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < NUM_GLOBAL_PROF_LOCKS; i++) {
|
||||||
|
lock_stats_output_json(write_cb, cbopaque,
|
||||||
|
global_lock_names[i], lock_stats[i],
|
||||||
|
"\t\t\t\t", i == NUM_GLOBAL_PROF_LOCKS - 1);
|
||||||
|
}
|
||||||
|
malloc_cprintf(write_cb, cbopaque, "\t\t\t}\n");
|
||||||
|
}
|
||||||
malloc_cprintf(write_cb, cbopaque,
|
malloc_cprintf(write_cb, cbopaque,
|
||||||
"\t\t}%s\n", (merged || unmerged) ? "," : "");
|
"\t\t}%s\n", (merged || unmerged || destroyed) ? "," : "");
|
||||||
} else {
|
} else {
|
||||||
malloc_cprintf(write_cb, cbopaque,
|
malloc_cprintf(write_cb, cbopaque,
|
||||||
"Allocated: %zu, active: %zu, metadata: %zu,"
|
"Allocated: %zu, active: %zu, metadata: %zu,"
|
||||||
" resident: %zu, mapped: %zu, retained: %zu\n",
|
" resident: %zu, mapped: %zu, retained: %zu\n",
|
||||||
allocated, active, metadata, resident, mapped, retained);
|
allocated, active, metadata, resident, mapped, retained);
|
||||||
|
if (lock) {
|
||||||
for (unsigned i = 0; i < NUM_GLOBAL_PROF_LOCKS; i++) {
|
for (unsigned i = 0; i < NUM_GLOBAL_PROF_LOCKS; i++) {
|
||||||
lock_stats_output(write_cb, cbopaque,
|
lock_stats_output(write_cb, cbopaque,
|
||||||
global_lock_names[i], lock_stats[i], i == 0);
|
global_lock_names[i], lock_stats[i],
|
||||||
|
i == 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1043,7 +1111,7 @@ stats_print_helper(void (*write_cb)(void *, const char *), void *cbopaque,
|
|||||||
"\nMerged arenas stats:\n");
|
"\nMerged arenas stats:\n");
|
||||||
}
|
}
|
||||||
stats_arena_print(write_cb, cbopaque, json,
|
stats_arena_print(write_cb, cbopaque, json,
|
||||||
MALLCTL_ARENAS_ALL, bins, large);
|
MALLCTL_ARENAS_ALL, bins, large, lock);
|
||||||
if (json) {
|
if (json) {
|
||||||
malloc_cprintf(write_cb, cbopaque,
|
malloc_cprintf(write_cb, cbopaque,
|
||||||
"\t\t\t}%s\n",
|
"\t\t\t}%s\n",
|
||||||
@ -1064,7 +1132,8 @@ stats_print_helper(void (*write_cb)(void *, const char *), void *cbopaque,
|
|||||||
"\nDestroyed arenas stats:\n");
|
"\nDestroyed arenas stats:\n");
|
||||||
}
|
}
|
||||||
stats_arena_print(write_cb, cbopaque, json,
|
stats_arena_print(write_cb, cbopaque, json,
|
||||||
MALLCTL_ARENAS_DESTROYED, bins, large);
|
MALLCTL_ARENAS_DESTROYED, bins, large,
|
||||||
|
lock);
|
||||||
if (json) {
|
if (json) {
|
||||||
malloc_cprintf(write_cb, cbopaque,
|
malloc_cprintf(write_cb, cbopaque,
|
||||||
"\t\t\t}%s\n", unmerged ? "," :
|
"\t\t\t}%s\n", unmerged ? "," :
|
||||||
@ -1090,7 +1159,7 @@ stats_print_helper(void (*write_cb)(void *, const char *), void *cbopaque,
|
|||||||
}
|
}
|
||||||
stats_arena_print(write_cb,
|
stats_arena_print(write_cb,
|
||||||
cbopaque, json, i, bins,
|
cbopaque, json, i, bins,
|
||||||
large);
|
large, lock);
|
||||||
if (json) {
|
if (json) {
|
||||||
malloc_cprintf(write_cb,
|
malloc_cprintf(write_cb,
|
||||||
cbopaque,
|
cbopaque,
|
||||||
@ -1123,6 +1192,7 @@ stats_print(void (*write_cb)(void *, const char *), void *cbopaque,
|
|||||||
bool unmerged = config_stats;
|
bool unmerged = config_stats;
|
||||||
bool bins = true;
|
bool bins = true;
|
||||||
bool large = true;
|
bool large = true;
|
||||||
|
bool lock = true;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Refresh stats, in case mallctl() was called by the application.
|
* Refresh stats, in case mallctl() was called by the application.
|
||||||
@ -1172,6 +1242,9 @@ stats_print(void (*write_cb)(void *, const char *), void *cbopaque,
|
|||||||
case 'l':
|
case 'l':
|
||||||
large = false;
|
large = false;
|
||||||
break;
|
break;
|
||||||
|
case 'x':
|
||||||
|
lock = false;
|
||||||
|
break;
|
||||||
default:;
|
default:;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1187,12 +1260,11 @@ stats_print(void (*write_cb)(void *, const char *), void *cbopaque,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (general) {
|
if (general) {
|
||||||
bool more = (merged || unmerged);
|
stats_general_print(write_cb, cbopaque, json, config_stats);
|
||||||
stats_general_print(write_cb, cbopaque, json, more);
|
|
||||||
}
|
}
|
||||||
if (config_stats) {
|
if (config_stats) {
|
||||||
stats_print_helper(write_cb, cbopaque, json, merged, destroyed,
|
stats_print_helper(write_cb, cbopaque, json, merged, destroyed,
|
||||||
unmerged, bins, large);
|
unmerged, bins, large, lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (json) {
|
if (json) {
|
||||||
|
@ -938,11 +938,16 @@ TEST_BEGIN(test_stats_print_json) {
|
|||||||
"Ja",
|
"Ja",
|
||||||
"Jb",
|
"Jb",
|
||||||
"Jl",
|
"Jl",
|
||||||
|
"Jx",
|
||||||
"Jbl",
|
"Jbl",
|
||||||
"Jal",
|
"Jal",
|
||||||
"Jab",
|
"Jab",
|
||||||
"Jabl",
|
"Jabl",
|
||||||
"Jgmdabl",
|
"Jax",
|
||||||
|
"Jbx",
|
||||||
|
"Jlx",
|
||||||
|
"Jablx",
|
||||||
|
"Jgmdablx",
|
||||||
};
|
};
|
||||||
unsigned arena_ind, i;
|
unsigned arena_ind, i;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user