diff --git a/cores/esp8266/cont.h b/cores/esp8266/cont.h index 4fe742f44..46daad100 100644 --- a/cores/esp8266/cont.h +++ b/cores/esp8266/cont.h @@ -60,6 +60,10 @@ void cont_yield(cont_t*); // return 1 if guard bytes were overwritten. int cont_check(cont_t* cont); +// Go through stack and check how many bytes are most probably still unchanged +// and thus weren't used by the user code. i.e. that stack space is free. (high water mark) +int cont_get_free_stack(cont_t* cont); + // Check if yield() may be called. Returns true if we are running inside // continuation stack bool cont_can_yield(cont_t* cont); diff --git a/cores/esp8266/cont_util.c b/cores/esp8266/cont_util.c index 2a29e7eac..52a79e34e 100644 --- a/cores/esp8266/cont_util.c +++ b/cores/esp8266/cont_util.c @@ -30,6 +30,12 @@ void ICACHE_RAM_ATTR cont_init(cont_t* cont) { cont->stack_guard2 = CONT_STACKGUARD; cont->stack_end = cont->stack + (sizeof(cont->stack) / 4); cont->struct_start = (unsigned*) cont; + + // fill stack with magic values to check high water mark + for(int pos = 0; pos < sizeof(cont->stack) / 4; pos++) + { + cont->stack[pos] = CONT_STACKGUARD; + } } int ICACHE_RAM_ATTR cont_check(cont_t* cont) { @@ -38,6 +44,19 @@ int ICACHE_RAM_ATTR cont_check(cont_t* cont) { return 0; } +int ICACHE_RAM_ATTR cont_get_free_stack(cont_t* cont) { + uint32_t *head = cont->stack; + int freeWords = 0; + + while(*head == CONT_STACKGUARD) + { + head++; + freeWords++; + } + + return freeWords * 4; +} + bool ICACHE_RAM_ATTR cont_can_yield(cont_t* cont) { return !ETS_INTR_WITHINISR() && cont->pc_ret != 0 && cont->pc_yield == 0;