Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 29 additions & 8 deletions core/iwasm/common/wasm_c_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,12 @@ WASM_DEFINE_VEC_OWN(module, wasm_module_delete_internal)
WASM_DEFINE_VEC_OWN(store, wasm_store_delete)
WASM_DEFINE_VEC_OWN(valtype, wasm_valtype_delete)

#ifndef NDEBUG
#define WASM_C_DUMP_PROC_MEM() LOG_PROC_MEM()
#else
#define WASM_C_DUMP_PROC_MEM() (void)0
#endif

/* Runtime Environment */
own wasm_config_t *
wasm_config_new(void)
Expand Down Expand Up @@ -307,6 +313,14 @@ wasm_engine_new_internal(mem_alloc_type_t type, const MemAllocOption *opts)
RuntimeInitArgs init_args = { 0 };
init_args.mem_alloc_type = type;

#ifndef NDEBUG
bh_log_set_verbose_level(BH_LOG_LEVEL_VERBOSE);
#else
bh_log_set_verbose_level(BH_LOG_LEVEL_WARNING);
#endif

WASM_C_DUMP_PROC_MEM();

if (type == Alloc_With_Pool) {
if (!opts) {
return NULL;
Expand Down Expand Up @@ -337,14 +351,6 @@ wasm_engine_new_internal(mem_alloc_type_t type, const MemAllocOption *opts)
goto failed;
}

#ifndef NDEBUG
/*DEBUG*/
bh_log_set_verbose_level(BH_LOG_LEVEL_VERBOSE);
#else
/*VERBOSE*/
bh_log_set_verbose_level(BH_LOG_LEVEL_WARNING);
#endif

/* create wasm_engine_t */
if (!(engine = malloc_internal(sizeof(wasm_engine_t)))) {
goto failed;
Expand All @@ -358,6 +364,8 @@ wasm_engine_new_internal(mem_alloc_type_t type, const MemAllocOption *opts)

engine->ref_count = 1;

WASM_C_DUMP_PROC_MEM();

RETURN_OBJ(engine, wasm_engine_delete_internal)
}

Expand Down Expand Up @@ -442,6 +450,8 @@ wasm_store_new(wasm_engine_t *engine)
{
wasm_store_t *store = NULL;

WASM_C_DUMP_PROC_MEM();

if (!engine || singleton_engine != engine) {
return NULL;
}
Expand Down Expand Up @@ -474,6 +484,8 @@ wasm_store_new(wasm_engine_t *engine)
goto failed;
}

WASM_C_DUMP_PROC_MEM();

return store;
failed:
wasm_store_delete(store);
Expand Down Expand Up @@ -1903,6 +1915,8 @@ wasm_module_new(wasm_store_t *store, const wasm_byte_vec_t *binary)

bh_assert(singleton_engine);

WASM_C_DUMP_PROC_MEM();

if (!store || !binary || binary->size == 0 || binary->size > UINT32_MAX)
goto quit;

Expand Down Expand Up @@ -1958,6 +1972,9 @@ wasm_module_new(wasm_store_t *store, const wasm_byte_vec_t *binary)
goto destroy_lock;

module_ex->ref_count = 1;

WASM_C_DUMP_PROC_MEM();

return module_ext_to_module(module_ex);

destroy_lock:
Expand Down Expand Up @@ -4453,6 +4470,8 @@ wasm_instance_new_with_args(wasm_store_t *store, const wasm_module_t *module,
return NULL;
}

WASM_C_DUMP_PROC_MEM();

instance = malloc_internal(sizeof(wasm_instance_t));
if (!instance) {
goto failed;
Expand Down Expand Up @@ -4595,6 +4614,8 @@ wasm_instance_new_with_args(wasm_store_t *store, const wasm_module_t *module,
goto failed;
}

WASM_C_DUMP_PROC_MEM();

return instance;

failed:
Expand Down
6 changes: 6 additions & 0 deletions core/shared/platform/alios/alios_platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ void
os_free(void *ptr)
{}

int
os_dumps_proc_mem_info(char *out, unsigned int size)
{
return -1;
}

void *
os_mmap(void *hint, size_t size, int prot, int flags)
{
Expand Down
6 changes: 6 additions & 0 deletions core/shared/platform/common/freertos/freertos_malloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,9 @@ os_realloc(void *ptr, unsigned size)
void
os_free(void *ptr)
{}

int
os_dumps_proc_mem_info(char *out, unsigned int size)
{
return -1;
}
48 changes: 48 additions & 0 deletions core/shared/platform/common/posix/posix_malloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,51 @@ os_free(void *ptr)
{
free(ptr);
}

int
os_dumps_proc_mem_info(char *out, unsigned int size)
{
int ret = -1;
FILE *f;
char line[128] = { 0 };
unsigned int out_idx = 0;

if (!out || !size)
goto quit;

f = fopen("/proc/self/status", "r");
if (!f) {
perror("fopen failed: ");
goto quit;
}

memset(out, 0, size);

while (fgets(line, sizeof(line), f)) {
#if WASM_ENABLE_MEMORY_PROFILING != 0
if (strncmp(line, "Vm", 2) == 0 || strncmp(line, "Rss", 3) == 0) {
#else
if (strncmp(line, "VmRSS", 5) == 0
|| strncmp(line, "RssAnon", 7) == 0) {
#endif
size_t line_len = strlen(line);
if (line_len >= size - 1 - out_idx)
goto close_file;

/* copying without null-terminated byte */
memcpy(out + out_idx, line, line_len);
out_idx += line_len;
}
}

if (ferror(f)) {
perror("fgets failed: ");
goto close_file;
}

ret = 0;
close_file:
fclose(f);
quit:
return ret;
}
6 changes: 6 additions & 0 deletions core/shared/platform/esp-idf/espidf_malloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,9 @@ os_free(void *ptr)
free(mem_origin);
}
}

int
os_dumps_proc_mem_info(char *out, unsigned int size)
{
return -1;
}
13 changes: 13 additions & 0 deletions core/shared/platform/include/platform_api_extension.h
Original file line number Diff line number Diff line change
Expand Up @@ -977,6 +977,19 @@ os_socket_set_broadcast(bh_socket_t socket, bool is_enabled);
int
os_socket_get_broadcast(bh_socket_t socket, bool *is_enabled);

/**
* Dump memory information of the current process
* It may have variant implementations in different platforms
*
* @param out the output buffer. It is for sure the return content
* is a c-string which ends up with '\0'
* @param size the size of the output buffer
*
* @return 0 if success, -1 otherwise
*/
int
os_dumps_proc_mem_info(char *out, unsigned int size);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[minor] could we use size_t -like type for the size variable?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, I think we could probably make the API more verbose - having char * type as a return value doesn't tell implementation and the user how the data should be structured (so on windows we might have different format, on linux there will be a different format).
I'd suggest using a well-defined structure that's being returned here so:

  1. implementers know exactly what sort of data needs to be returned
  2. users of that method know what to expect
  3. we can have a consistent formatting defined in a common layer, rather than have different formatting for each system
  4. If we ever want to emit metrics from WAMR or generate statistics, we can't rely on unstructured text.

This is just a suggestion - if returning an unstructured blob from this function is really what we want, that's fine, just wanted to raise the concern and make sure we're making a conscious decision.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am thinking that os_dumps_proc_mem_info should return some kind of memory usage reports of the current process. The developer should not be worried about how the memory data is structured or how different every platform is. It doesn't limit the output format and the output items.


#ifdef __cplusplus
}
#endif
Expand Down
6 changes: 6 additions & 0 deletions core/shared/platform/linux-sgx/sgx_platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,12 @@ os_free(void *ptr)
free(ptr);
}

int
os_dumps_proc_mem_info(char *out, unsigned int size)
{
return -1;
}

int
putchar(int c)
{
Expand Down
6 changes: 6 additions & 0 deletions core/shared/platform/nuttx/nuttx_platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ os_free(void *ptr)
free(ptr);
}

int
os_dumps_proc_mem_info(char *out, unsigned int size)
{
return -1;
}

void *
os_mmap(void *hint, size_t size, int prot, int flags)
{
Expand Down
6 changes: 6 additions & 0 deletions core/shared/platform/riot/riot_platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ os_free(void *ptr)
free(ptr);
}

int
os_dumps_proc_mem_info(char *out, unsigned int size)
{
return -1;
}

void *
os_mmap(void *hint, size_t size, int prot, int flags)
{
Expand Down
6 changes: 6 additions & 0 deletions core/shared/platform/rt-thread/rtt_platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,12 @@ os_free(void *ptr)
}
}

int
os_dumps_proc_mem_info(char *out, unsigned int size)
{
return -1;
}

static char wamr_vprint_buf[RT_CONSOLEBUF_SIZE * 2];

int
Expand Down
6 changes: 6 additions & 0 deletions core/shared/platform/windows/win_malloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,9 @@ os_free(void *ptr)
{
free(ptr);
}

int
os_dumps_proc_mem_info(char *out, unsigned int size)
{
return -1;
}
6 changes: 6 additions & 0 deletions core/shared/platform/zephyr/zephyr_platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,12 @@ void
os_free(void *ptr)
{}

int
os_dumps_proc_mem_info(char *out, unsigned int size)
{
return -1;
}

#if 0
struct out_context {
int count;
Expand Down
26 changes: 26 additions & 0 deletions core/shared/utils/bh_log.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,29 @@ bh_print_time(const char *prompt)

last_time_ms = curr_time_ms;
}

void
bh_print_proc_mem(const char *prompt)
{
char buf[1024] = { 0 };

if (log_verbose_level < BH_LOG_LEVEL_DEBUG)
return;

if (os_dumps_proc_mem_info(buf, sizeof(buf)) != 0)
return;

os_printf("%s\n", prompt);
os_printf("===== memory usage =====\n");
os_printf("%s", buf);
os_printf("==========\n");
return;
}

void
bh_log_proc_mem(const char *function, uint32 line)
{
char prompt[128] = { 0 };
snprintf(prompt, sizeof(prompt), "[MEM] %s(...) L%u", function, line);
return bh_print_proc_mem(prompt);
}
8 changes: 8 additions & 0 deletions core/shared/utils/bh_log.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,14 @@ bh_log(LogLevel log_level, const char *file, int line, const char *fmt, ...);
void
bh_print_time(const char *prompt);

void
bh_print_proc_mem(const char *prompt);

void
bh_log_proc_mem(const char *function, uint32 line);

#define LOG_PROC_MEM(...) bh_log_proc_mem(__FUNCTION__, __LINE__)

#ifdef __cplusplus
}
#endif
Expand Down