diff options
-rwxr-xr-x | build-aux/stack.c.gen | 124 | ||||
-rw-r--r-- | cmd/sbc_harness/config/config.h | 12 | ||||
-rw-r--r-- | cmd/sbc_harness/main.c | 2 | ||||
-rw-r--r-- | lib9p/tests/test_server/config/config.h | 2 | ||||
-rw-r--r-- | libcr/coroutine.c | 8 | ||||
-rw-r--r-- | libcr/include/libcr/coroutine.h | 16 | ||||
-rw-r--r-- | libcr/tests/test_matrix/config.h | 2 | ||||
-rw-r--r-- | libcr_ipc/tests/config.h | 2 |
8 files changed, 113 insertions, 55 deletions
diff --git a/build-aux/stack.c.gen b/build-aux/stack.c.gen index af5d740..07d5cfc 100755 --- a/build-aux/stack.c.gen +++ b/build-aux/stack.c.gen @@ -131,6 +131,18 @@ def synthetic_node( return n +class AnalyzeResultGroup(typing.NamedTuple): + rows: dict[str, int] + nmax: int + nsum: int + + +class AnalyzeResult(typing.NamedTuple): + groups: dict[str, AnalyzeResultGroup] + missing: set[str] + dynamic: set[str] + + def analyze( *, ci_fnames: list[str], @@ -140,7 +152,7 @@ def analyze( app_indirect_callees: typing.Callable[[VCGElem], list[str]], app_skip_call: typing.Callable[[list[str], str], bool], cfg_max_call_depth: int, -) -> None: +) -> AnalyzeResult: re_node_label = re.compile( r"(?P<funcname>[^\n]+)\n" + r"(?P<location>[^\n]+:[0-9]+:[0-9]+)\n" @@ -281,10 +293,8 @@ def analyze( ] ) - print("/*") - + groups: dict[str, AnalyzeResultGroup] = dict() for grp_name, grp_filter in app_func_filters.items(): - # Gather the data. nmax = 0 nsum = 0 rows: dict[str, int] = {} @@ -295,28 +305,9 @@ def analyze( if n > nmax: nmax = n nsum += cnt * n + groups[grp_name] = AnalyzeResultGroup(rows=rows, nmax=nmax, nsum=nsum) - # Figure sizes. - namelen = max([len(k) for k in rows.keys()] + [len(grp_name) + 4]) - numlen = len(str(nsum)) - sep1 = ("=" * namelen) + " " + "=" * numlen - sep2 = ("-" * namelen) + " " + "-" * numlen - - # Print. - print("= " + grp_name + " " + sep1[len(grp_name) + 3 :]) - for name, num in sorted(rows.items()): - print(f"{name.ljust(namelen)} {str(num).rjust(numlen)}") - print(sep2) - print(f"{'Total'.ljust(namelen)} {str(nsum).rjust(numlen)}") - print(f"{'Maximum'.ljust(namelen)} {str(nmax).rjust(numlen)}") - print(sep1) - - for funcname in sorted(missing): - print(f"warning: missing: {funcname}") - for funcname in sorted(dynamic): - print(f"warning: dynamic-stack-usage: {funcname}") - - print("*/") + return AnalyzeResult(groups=groups, missing=missing, dynamic=dynamic) ################################################################################ @@ -434,10 +425,13 @@ def main( def sbc_is_thread(name: str) -> int: if name.endswith("_cr") and name != "lib9p_srv_read_cr": if "9p" in name: + # TODO: FIXME: Sniff these numbers from config.h + _CONFIG_9P_NUM_SOCKS = 3 + CONFIG_9P_SRV_MAX_REQS = 2 if "read" in name: - return 8 + return _CONFIG_9P_NUM_SOCKS elif "write" in name: - return 16 + return _CONFIG_9P_NUM_SOCKS * CONFIG_9P_SRV_MAX_REQS return 1 if name == "main": return True @@ -463,7 +457,7 @@ def main( # 4=just 2 levels of subdirectories # ... # - # TODO: Sniff this from config.h + # TODO: FIXME: Sniff this from config.h CONFIG_9P_SRV_MAX_DEPTH = 3 def sbc_skip_call(chain: list[str], call: str) -> bool: @@ -632,14 +626,12 @@ def main( # src/rp2040/boot_stage2/boot2_${name,,}.S for name=W25Q080, # controlled by `#define PICO_BOOT_STAGE2_{name} 1` in # src/boards/include/boards/pico.h - synthetic_node("_stage2_boot", 0), # TODO + # synthetic_node("_stage2_boot", 0), # TODO # https://github.com/raspberrypi/pico-bootrom-rp2040 - synthetic_node( - "rom_func_lookup(ROM_FUNC_CONNECT_INTERNAL_FLASH)", 0 - ), # TODO - synthetic_node("rom_func_lookup(ROM_FUNC_FLASH_EXIT_XIP)", 0), # TODO - synthetic_node("rom_func_lookup(ROM_FUNC_FLASH_FLUSH_CACHE)", 0), # TODO - synthetic_node("rom_hword_as_ptr(BOOTROM_TABLE_LOOKUP_OFFSET)", 0), # TODO + # synthetic_node("rom_func_lookup(ROM_FUNC_CONNECT_INTERNAL_FLASH)", 0), # TODO + # synthetic_node("rom_func_lookup(ROM_FUNC_FLASH_EXIT_XIP)", 0), # TODO + # synthetic_node("rom_func_lookup(ROM_FUNC_FLASH_FLUSH_CACHE)", 0), # TODO + # synthetic_node("rom_hword_as_ptr(BOOTROM_TABLE_LOOKUP_OFFSET)", 0), # TODO ] # TinyUSB device ################################################# @@ -736,10 +728,10 @@ def main( synthetic_node("realloc", 8, {"_realloc_r"}), synthetic_node("aligned_alloc", 8, {"_memalign_r"}), synthetic_node("reallocarray", 24, {"realloc", "__errno"}), - synthetic_node("_free_r", 0), # TODO - synthetic_node("_malloc_r", 0), # TODO - synthetic_node("_realloc_r", 0), # TODO - synthetic_node("_memalign_r", 0), # TODO + # synthetic_node("_free_r", 0), # TODO + # synthetic_node("_malloc_r", 0), # TODO + # synthetic_node("_realloc_r", 0), # TODO + # synthetic_node("_memalign_r", 0), # TODO # execution synthetic_node("raise", 16, {"_getpid_r"}), synthetic_node("abort", 8, {"raise", "_exit"}), @@ -816,7 +808,7 @@ def main( return True return False - analyze( + result = analyze( ci_fnames=arg_ci_fnames, extra_nodes=all_nodes, app_func_filters={ @@ -830,6 +822,58 @@ def main( cfg_max_call_depth=100, ) + def print_group(grp_name: str) -> None: + grp = result.groups[grp_name] + + # Figure sizes. + namelen = max([len(k) for k in grp.rows.keys()] + [len(grp_name) + 4]) + numlen = len(str(grp.nsum)) + sep1 = ("=" * namelen) + " " + "=" * numlen + sep2 = ("-" * namelen) + " " + "-" * numlen + + # Print. + print("= " + grp_name + " " + sep1[len(grp_name) + 3 :]) + for name, num in sorted(grp.rows.items()): + print(f"{name.ljust(namelen)} {str(num).rjust(numlen)}") + print(sep2) + print(f"{'Total'.ljust(namelen)} {str(grp.nsum).rjust(numlen)}") + print(f"{'Maximum'.ljust(namelen)} {str(grp.nmax).rjust(numlen)}") + print(sep1) + + def next_power_of_2(x: int) -> int: + return 1 << (x.bit_length()) + + print("#include <stddef.h> /* for size_t */") + print() + print("/*") + print_group("Threads") + print_group("Interrupt handlers") + print("*/") + overhead = result.groups["Interrupt handlers"].nmax + rows: list[tuple[str, int, int]] = [] + for funcname, base in result.groups["Threads"].rows.items(): + rows.append((funcname.split(":")[-1], base, next_power_of_2(base + overhead))) + namelen = max(len(r[0]) for r in rows) + baselen = max(len(str(r[1])) for r in rows) + sizelen = max(len(str(r[2])) for r in rows) + for row in sorted(rows): + if row[0] == "main": + continue + print("const size_t CONFIG_COROUTINE_STACK_SIZE_", end="") + print(f"{row[0].ljust(namelen)} =", end="") + print(f" {str(row[2]).rjust(sizelen)};", end="") + print(f" /* LM_NEXT_POWER_OF_2({str(row[1]).rjust(baselen)}+{overhead}) */") + print() + print("/*") + print_group("Misc") + + for funcname in sorted(result.missing): + print(f"warning: missing: {funcname}") + for funcname in sorted(result.dynamic): + print(f"warning: dynamic-stack-usage: {funcname}") + + print("*/") + if __name__ == "__main__": pico_platform = sys.argv[1] diff --git a/cmd/sbc_harness/config/config.h b/cmd/sbc_harness/config/config.h index 6046b31..b569cd5 100644 --- a/cmd/sbc_harness/config/config.h +++ b/cmd/sbc_harness/config/config.h @@ -7,6 +7,8 @@ #ifndef _CONFIG_H_ #define _CONFIG_H_ +#include <stddef.h> /* for size_t */ + /* W5500 **********************************************************************/ /** @@ -86,7 +88,13 @@ /* COROUTINE ******************************************************************/ -#define CONFIG_COROUTINE_DEFAULT_STACK_SIZE (2*1024) +extern const size_t CONFIG_COROUTINE_STACK_SIZE_dhcp_cr; +extern const size_t CONFIG_COROUTINE_STACK_SIZE_init_cr; +extern const size_t CONFIG_COROUTINE_STACK_SIZE_lib9p_srv_write_cr; +extern const size_t CONFIG_COROUTINE_STACK_SIZE_read9p_cr; +extern const size_t CONFIG_COROUTINE_STACK_SIZE_usb_common_cr; +extern const size_t CONFIG_COROUTINE_STACK_SIZE_usb_keyboard_cr; +extern const size_t CONFIG_COROUTINE_STACK_SIZE_w5500_irq_cr; #define CONFIG_COROUTINE_NAME_LEN 16 #define CONFIG_COROUTINE_MEASURE_STACK 1 /* bool */ #define CONFIG_COROUTINE_PROTECT_STACK 1 /* bool */ @@ -94,7 +102,7 @@ #define CONFIG_COROUTINE_VALGRIND 0 /* bool */ #define CONFIG_COROUTINE_GDB 1 /* bool */ -#define _CONFIG_9P_NUM_SOCKS 7 +#define _CONFIG_9P_NUM_SOCKS 3 /* FIXME: bump this back up to 8 */ #define CONFIG_COROUTINE_NUM ( \ 1 /* usb_common */ + \ 1 /* usb_keyboard */ + \ diff --git a/cmd/sbc_harness/main.c b/cmd/sbc_harness/main.c index 69df077..2e83476 100644 --- a/cmd/sbc_harness/main.c +++ b/cmd/sbc_harness/main.c @@ -221,7 +221,7 @@ COROUTINE init_cr(void *) { coroutine_add("usb_common", usb_common_cr, NULL); coroutine_add("usb_keyboard", usb_keyboard_cr, &globals.keyboard_chan); //coroutine_add("hello_world", hello_world_cr, &globals.keyboard_chan); - coroutine_add_with_stack_size(4*1024, "dhcp", dhcp_cr, NULL); + coroutine_add("dhcp", dhcp_cr, NULL); for (int i = 0; i < _CONFIG_9P_NUM_SOCKS; i++) { char name[] = {'r', 'e', 'a', 'd', '-', hexdig[i], '\0'}; coroutine_add(name, read9p_cr, NULL); diff --git a/lib9p/tests/test_server/config/config.h b/lib9p/tests/test_server/config/config.h index a3660e8..201cfd0 100644 --- a/lib9p/tests/test_server/config/config.h +++ b/lib9p/tests/test_server/config/config.h @@ -48,7 +48,7 @@ /* COROUTINE ******************************************************************/ -#define CONFIG_COROUTINE_DEFAULT_STACK_SIZE (32*1024) +#define CONFIG_COROUTINE_STACK_SIZE_DEFAULT (32*1024) #define CONFIG_COROUTINE_NAME_LEN 16 #define CONFIG_COROUTINE_MEASURE_STACK 1 /* bool */ #define CONFIG_COROUTINE_PROTECT_STACK 1 /* bool */ diff --git a/libcr/coroutine.c b/libcr/coroutine.c index 39df3d5..33e8141 100644 --- a/libcr/coroutine.c +++ b/libcr/coroutine.c @@ -21,9 +21,6 @@ #include "config.h" -#ifndef CONFIG_COROUTINE_DEFAULT_STACK_SIZE - #error config.h must define CONFIG_COROUTINE_DEFAULT_STACK_SIZE (non-negative integer) -#endif #ifndef CONFIG_COROUTINE_NAME_LEN #error config.h must define CONFIG_COROUTINE_NAME_LEN (non-negative integer) #endif @@ -630,11 +627,6 @@ cid_t coroutine_add_with_stack_size(size_t stack_size, return child; } -cid_t coroutine_add(const char *name, cr_fn_t fn, void *args) { - return coroutine_add_with_stack_size( - CONFIG_COROUTINE_DEFAULT_STACK_SIZE, name, fn, args); -} - /* coroutine_main() ***********************************************************/ void coroutine_main(void) { diff --git a/libcr/include/libcr/coroutine.h b/libcr/include/libcr/coroutine.h index 756352e..2505782 100644 --- a/libcr/include/libcr/coroutine.h +++ b/libcr/include/libcr/coroutine.h @@ -29,8 +29,14 @@ #include <stddef.h> /* for size_t */ #include <stdbool.h> /* for bool */ +/* Configuration **************************************************************/ + #include "config.h" +#ifndef CONFIG_COROUTINE_MEASURE_STACK + #error config.h must define CONFIG_COROUTINE_MEASURE_STACK (bool) +#endif + /* typedefs *******************************************************************/ /** @@ -91,8 +97,16 @@ cid_t coroutine_add_with_stack_size(size_t stack_size, const char *name, cr_fn_t /** * Like coroutine_add_with_stack_size(), but uses a default stack size so * you don't need to think about it. + * + * Either define CONFIG_COROUTINE_STACK_SIZE_DEFAULT to use for all + * coroutines, or CONFIG_COROUTINE_STACK_SIZE_{fn} for each COROUTINE + * function. */ -cid_t coroutine_add(const char *name, cr_fn_t fn, void *args); +#ifdef CONFIG_COROUTINE_STACK_SIZE_DEFAULT +#define coroutine_add(name, fn, args) coroutine_add_with_stack_size(CONFIG_COROUTINE_STACK_SIZE_DEFAULT, name, fn, args) +#else +#define coroutine_add(name, fn, args) coroutine_add_with_stack_size(CONFIG_COROUTINE_STACK_SIZE_##fn, name, fn, args) +#endif /** * The main scheduler loop. Returns if all coroutines exit. diff --git a/libcr/tests/test_matrix/config.h b/libcr/tests/test_matrix/config.h index becfce0..83892df 100644 --- a/libcr/tests/test_matrix/config.h +++ b/libcr/tests/test_matrix/config.h @@ -7,7 +7,7 @@ #ifndef _CONFIG_H_ #define _CONFIG_H_ -#define CONFIG_COROUTINE_DEFAULT_STACK_SIZE (4*1024) +#define CONFIG_COROUTINE_STACK_SIZE_DEFAULT (4*1024) #define CONFIG_COROUTINE_NAME_LEN 16 #define CONFIG_COROUTINE_NUM 2 diff --git a/libcr_ipc/tests/config.h b/libcr_ipc/tests/config.h index e06c876..2a5cbc9 100644 --- a/libcr_ipc/tests/config.h +++ b/libcr_ipc/tests/config.h @@ -7,7 +7,7 @@ #ifndef _CONFIG_H_ #define _CONFIG_H_ -#define CONFIG_COROUTINE_DEFAULT_STACK_SIZE (4*1024) +#define CONFIG_COROUTINE_STACK_SIZE_DEFAULT (4*1024) #define CONFIG_COROUTINE_NAME_LEN 16 #define CONFIG_COROUTINE_NUM 8 |