1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-04-27 21:16:50 +03:00

Merge pull request #585 from esp8266/optimistic-yield

Pass timeout to optimistic_yield, add cont_can_yield check
This commit is contained in:
Ivan Grokhotkov 2015-07-22 17:15:25 +03:00
commit 31344df515
11 changed files with 193 additions and 177 deletions

View File

@ -38,9 +38,6 @@ extern "C" {
#include "esp8266_peri.h" #include "esp8266_peri.h"
#include "twi.h" #include "twi.h"
void yield(void);
void optimistic_yield(void);
#define HIGH 0x1 #define HIGH 0x1
#define LOW 0x0 #define LOW 0x0
@ -207,6 +204,9 @@ void detachInterrupt(uint8_t);
void setup(void); void setup(void);
void loop(void); void loop(void);
void yield(void);
void optimistic_yield(uint32_t interval_us);
// Get the bit location within the hardware port of the given virtual pin. // Get the bit location within the hardware port of the given virtual pin.
// This comes from the pins_*.c file for the active board configuration. // This comes from the pins_*.c file for the active board configuration.
#define digitalPinToPort(pin) (0) #define digitalPinToPort(pin) (0)

View File

@ -559,7 +559,7 @@ int HardwareSerial::available(void) {
} }
if (!result) { if (!result) {
optimistic_yield(); optimistic_yield(USD(_uart->uart_nr) / 128);
} }
return result; return result;

View File

@ -18,106 +18,109 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
.text .text
.align 4 .align 4
.literal_position .literal_position
.global cont_yield .global cont_yield
.type cont_yield, @function .type cont_yield, @function
cont_yield: cont_yield:
/* a1: sp */ /* a1: sp */
/* a2: void* cont_ctx */ /* a2: void* cont_ctx */
/* adjust stack and save registers */ /* adjust stack and save registers */
addi a1, a1, -24 addi a1, a1, -24
s32i a12, a1, 0 s32i a12, a1, 0
s32i a13, a1, 4 s32i a13, a1, 4
s32i a14, a1, 8 s32i a14, a1, 8
s32i a15, a1, 12 s32i a15, a1, 12
s32i a0, a1, 16 s32i a0, a1, 16
s32i a2, a1, 20 s32i a2, a1, 20
/* &cont_continue -> cont_ctx.pc_yield */ /* &cont_continue -> cont_ctx.pc_yield */
movi a3, cont_continue movi a3, cont_continue
s32i a3, a2, 8 s32i a3, a2, 8
/* sp -> cont_ctx.sp_yield */ /* sp -> cont_ctx.sp_yield */
s32i a1, a2, 12 s32i a1, a2, 12
/* a0 <- cont_ctx.pc_ret */ /* a0 <- cont_ctx.pc_ret */
l32i a0, a2, 0 l32i a0, a2, 0
/* sp <- cont_ctx.sp_ret */ /* sp <- cont_ctx.sp_ret */
l32i a1, a2, 4 l32i a1, a2, 4
jx a0 jx a0
cont_continue: cont_continue:
l32i a12, a1, 0 l32i a12, a1, 0
l32i a13, a1, 4 l32i a13, a1, 4
l32i a14, a1, 8 l32i a14, a1, 8
l32i a15, a1, 12 l32i a15, a1, 12
l32i a0, a1, 16 l32i a0, a1, 16
l32i a2, a1, 20 l32i a2, a1, 20
addi a1, a1, 24 addi a1, a1, 24
ret ret
.size cont_yield, . - cont_yield .size cont_yield, . - cont_yield
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
.text .text
.align 4 .align 4
.literal_position .literal_position
.global cont_run .global cont_run
.type cont_run, @function .type cont_run, @function
cont_run: cont_run:
/* a1: sp */ /* a1: sp */
/* a2: void* cont_ctx */ /* a2: void* cont_ctx */
/* a3: void (*pfn) */ /* a3: void (*pfn) */
/* adjust stack and save registers */ /* adjust stack and save registers */
addi a1, a1, -20 addi a1, a1, -20
s32i a12, a1, 0 s32i a12, a1, 0
s32i a13, a1, 4 s32i a13, a1, 4
s32i a14, a1, 8 s32i a14, a1, 8
s32i a15, a1, 12 s32i a15, a1, 12
s32i a0, a1, 16 s32i a0, a1, 16
/* cont_ret -> a4 -> cont_ctx.pc_ret*/ /* cont_ret -> a4 -> cont_ctx.pc_ret*/
movi a4, cont_ret movi a4, cont_ret
s32i a4, a2, 0 s32i a4, a2, 0
/* sp -> cont_ctx.sp_ret */ /* sp -> cont_ctx.sp_ret */
s32i a1, a2, 4 s32i a1, a2, 4
/* if cont_ctx.pc_yield != 0, goto cont_resume */ /* if cont_ctx.pc_yield != 0, goto cont_resume */
l32i a4, a2, 8 l32i a4, a2, 8
bnez a4, cont_resume bnez a4, cont_resume
/* else */ /* else */
/* set new stack*/ /* set new stack*/
l32i a1, a2, 16; l32i a1, a2, 16;
/* goto pfn */ /* goto pfn */
movi a0, cont_norm movi a0, cont_norm
jx a3 jx a3
cont_resume: cont_resume:
/* a1 <- cont_ctx.sp_yield */ /* a1 <- cont_ctx.sp_yield */
l32i a1, a2, 12 l32i a1, a2, 12
/* reset yield flag, 0 -> cont_ctx.pc_yield */ /* reset yield flag, 0 -> cont_ctx.pc_yield */
movi a3, 0 movi a3, 0
s32i a3, a2, 8 s32i a3, a2, 8
/* jump to saved cont_ctx.pc_yield */ /* jump to saved cont_ctx.pc_yield */
movi a0, cont_ret movi a0, cont_ret
jx a4 jx a4
cont_norm: cont_norm:
/* calculate pointer to cont_ctx.struct_start from sp */ /* calculate pointer to cont_ctx.struct_start from sp */
l32i a2, a1, 4 l32i a2, a1, 4
/* sp <- cont_ctx.sp_ret */ /* sp <- cont_ctx.sp_ret */
l32i a1, a2, 4 l32i a1, a2, 4
/* 0 -> cont_ctx.pc_ret */
movi a4, 0
s32i a4, a2, 0
cont_ret: cont_ret:
/* restore registers */ /* restore registers */
l32i a12, a1, 0 l32i a12, a1, 0
l32i a13, a1, 4 l32i a13, a1, 4
l32i a14, a1, 8 l32i a14, a1, 8
l32i a15, a1, 12 l32i a15, a1, 12
l32i a0, a1, 16 l32i a0, a1, 16
/* adjust stack and return */ /* adjust stack and return */
addi a1, a1, 20 addi a1, a1, 20
ret ret
.size cont_run, . - cont_run .size cont_run, . - cont_run

View File

@ -21,6 +21,8 @@
#ifndef CONT_H_ #ifndef CONT_H_
#define CONT_H_ #define CONT_H_
#include <stdbool.h>
#ifndef CONT_STACKSIZE #ifndef CONT_STACKSIZE
#define CONT_STACKSIZE 4096 #define CONT_STACKSIZE 4096
#endif #endif
@ -58,4 +60,8 @@ void cont_yield(cont_t*);
// return 1 if guard bytes were overwritten. // return 1 if guard bytes were overwritten.
int cont_check(cont_t* cont); int cont_check(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);
#endif /* CONT_H_ */ #endif /* CONT_H_ */

View File

@ -19,6 +19,9 @@
*/ */
#include "cont.h" #include "cont.h"
#include <stddef.h>
#include "ets_sys.h"
#define CONT_STACKGUARD 0xfeefeffe #define CONT_STACKGUARD 0xfeefeffe
@ -34,3 +37,8 @@ int cont_check(cont_t* cont) {
return 0; return 0;
} }
bool cont_can_yield(cont_t* cont) {
return !ETS_INTR_WITHINISR() &&
cont->pc_ret != 0 && cont->pc_yield == 0;
}

View File

@ -64,16 +64,16 @@ extern void (*__init_array_end)(void);
cont_t g_cont __attribute__ ((aligned (16))); cont_t g_cont __attribute__ ((aligned (16)));
static os_event_t g_loop_queue[LOOP_QUEUE_SIZE]; static os_event_t g_loop_queue[LOOP_QUEUE_SIZE];
static uint32_t g_micros_at_last_task_yield; static uint32_t g_micros_at_task_start;
extern "C" void abort() { extern "C" void abort() {
while(1) { do {
} *((int*)0) = 0;
} while(true);
} }
extern "C" void esp_yield() { extern "C" void esp_yield() {
g_micros_at_last_task_yield = system_get_time();
cont_yield(&g_cont); cont_yield(&g_cont);
} }
@ -82,16 +82,22 @@ extern "C" void esp_schedule() {
} }
extern "C" void __yield() { extern "C" void __yield() {
esp_schedule(); if (cont_can_yield(&g_cont)) {
esp_yield(); esp_schedule();
esp_yield();
}
else {
abort();
}
} }
extern "C" void yield(void) __attribute__ ((weak, alias("__yield"))); extern "C" void yield(void) __attribute__ ((weak, alias("__yield")));
extern "C" void optimistic_yield(void) { extern "C" void optimistic_yield(uint32_t interval_us) {
if (!ETS_INTR_WITHINISR() && if (cont_can_yield(&g_cont) &&
(system_get_time() - g_micros_at_last_task_yield) > OPTIMISTIC_YIELD_TIME_US) (system_get_time() - g_micros_at_task_start) > interval_us)
{ {
__yield(); yield();
} }
} }
@ -107,10 +113,10 @@ static void loop_wrapper() {
} }
static void loop_task(os_event_t *events) { static void loop_task(os_event_t *events) {
g_micros_at_last_task_yield = system_get_time(); g_micros_at_task_start = system_get_time();
cont_run(&g_cont, &loop_wrapper); cont_run(&g_cont, &loop_wrapper);
if(cont_check(&g_cont) != 0) { if(cont_check(&g_cont) != 0) {
ets_printf("\r\nheap collided with sketch stack\r\n"); ets_printf("\r\nsketch stack overflow detected\r\n");
abort(); abort();
} }
} }
@ -127,13 +133,11 @@ void init_done() {
esp_schedule(); esp_schedule();
} }
extern "C" {
void user_init(void) { extern "C" void user_init(void) {
struct rst_info *rtc_info_ptr = system_get_rst_info(); struct rst_info *rtc_info_ptr = system_get_rst_info();
memcpy((void *) &resetInfo, (void *) rtc_info_ptr, sizeof(resetInfo)); memcpy((void *) &resetInfo, (void *) rtc_info_ptr, sizeof(resetInfo));
uart_div_modify(0, UART_CLK_FREQ / (115200)); uart_div_modify(0, UART_CLK_FREQ / (115200));
init(); init();
@ -143,10 +147,8 @@ void user_init(void) {
cont_init(&g_cont); cont_init(&g_cont);
system_os_task(loop_task, system_os_task(loop_task,
LOOP_TASK_PRIORITY, g_loop_queue, LOOP_TASK_PRIORITY, g_loop_queue,
LOOP_QUEUE_SIZE); LOOP_QUEUE_SIZE);
system_init_done_cb(&init_done); system_init_done_cb(&init_done);
} }
}

View File

@ -653,7 +653,7 @@ bool ESP8266WiFiClass::beginWPSConfig(void) {
disconnect(); disconnect();
DEBUGV("wps begin: %d\n", wps_type); DEBUGV("wps begin\n");
if(!wifi_wps_disable()) { if(!wifi_wps_disable()) {
DEBUGV("wps disable faild\n"); DEBUGV("wps disable faild\n");

View File

@ -179,14 +179,13 @@ size_t WiFiClient::write(const uint8_t *buf, size_t size)
int WiFiClient::available() int WiFiClient::available()
{ {
int result = 0; if (!_client)
return false;
if (_client) { int result = _client->getSize();
result = _client->getSize();
}
if (!result) { if (!result) {
optimistic_yield(); optimistic_yield(100);
} }
return result; return result;
} }

View File

@ -99,7 +99,7 @@ WiFiClient WiFiServer::available(byte* status)
return result; return result;
} }
optimistic_yield(); optimistic_yield(1000);
return WiFiClient(); return WiFiClient();
} }
@ -161,4 +161,3 @@ void WiFiServer::_s_discard(void* server, ClientContext* ctx)
{ {
reinterpret_cast<WiFiServer*>(server)->_discard(ctx); reinterpret_cast<WiFiServer*>(server)->_discard(ctx);
} }

View File

@ -122,10 +122,6 @@ int WiFiUDP::available() {
result = static_cast<int>(_ctx->getSize()); result = static_cast<int>(_ctx->getSize());
} }
if (!result) {
optimistic_yield();
}
return result; return result;
} }
@ -207,8 +203,12 @@ int WiFiUDP::parsePacket()
{ {
if (!_ctx) if (!_ctx)
return 0; return 0;
if (!_ctx->next())
if (!_ctx->next()) {
optimistic_yield(100);
return 0; return 0;
}
return _ctx->getSize(); return _ctx->getSize();
} }
@ -284,4 +284,3 @@ void WiFiUDP::stopAll()
it->stop(); it->stop();
} }
} }

View File

@ -65,8 +65,8 @@ inline bool ETS_INTR_WITHINISR()
{ {
uint32_t ps; uint32_t ps;
__asm__ __volatile__("rsr %0,ps":"=a" (ps)); __asm__ __volatile__("rsr %0,ps":"=a" (ps));
// PS.EXCM and PS.UM bit checks // PS.EXCM bit check
return ((ps & ((1 << 4) | (1 << 5))) > 0); return ((ps & (1 << 4)) != 0);
} }
inline uint32_t ETS_INTR_ENABLED(void) inline uint32_t ETS_INTR_ENABLED(void)