From 70ea45ab84f5bdd9850cabbd57cd7b31d5ff47b6 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Tue, 17 Aug 2004 00:42:30 +0000 Subject: [PATCH] single-tasking callback i/o works --- Makefile | 2 +- TODO.FACTOR.txt | 8 ++-- library/platform/native/io-internals.factor | 13 ++++-- native/fd.c | 47 ++++++++++++++++++--- native/iomux.c | 6 +-- native/memory.c | 29 ++++++------- native/memory.h | 10 ++++- native/port.c | 1 + native/port.h | 2 + 9 files changed, 80 insertions(+), 38 deletions(-) diff --git a/Makefile b/Makefile index 45c2860ea2..9efeeaa30d 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ CC = gcc34 -CFLAGS = -Os -march=pentium4 -Wall -Wno-long-long +CFLAGS = -Os -march=pentium4 -Wall -Wno-long-long -fomit-frame-pointer LIBS = -lm STRIP = strip diff --git a/TODO.FACTOR.txt b/TODO.FACTOR.txt index 5baa00f7df..9183dad358 100644 --- a/TODO.FACTOR.txt +++ b/TODO.FACTOR.txt @@ -1,8 +1,8 @@ 0.62: -- read-line: handle \r\n -- ignore errors from flush -- can-read-line? +- gc call in the middle of some ops might affect callstack +- sending ^C on socket +- postpone errors until actual read/write op - vector-each/map examples - unparse examples - finish second practical @@ -83,7 +83,7 @@ + httpd: -- httpd: don't flush so much +- if user clicks stop in browser, doesn't stop sending? - log with date - log user agent - add a socket timeout diff --git a/library/platform/native/io-internals.factor b/library/platform/native/io-internals.factor index b7c8facb9b..2bb5c71f19 100644 --- a/library/platform/native/io-internals.factor +++ b/library/platform/native/io-internals.factor @@ -38,7 +38,9 @@ USE: strings : stderr 2 getenv ; : flush-fd ( port -- ) - [ swap add-write-io-task next-io-task drop ( call ) ] callcc0 ; + [ + swap add-write-io-task next-io-task call + ] callcc0 drop ; : wait-to-write ( len port -- ) tuck can-write? [ drop ] [ flush-fd ] ifte ; @@ -49,7 +51,9 @@ USE: strings over wait-to-write write-fd-8 ; : fill-fd ( port -- ) - [ swap add-read-line-io-task next-io-task drop ( call ) ] callcc0 ; + [ + swap add-read-line-io-task next-io-task call + ] callcc0 drop ; : wait-to-read-line ( port -- ) dup can-read-line? [ drop ] [ fill-fd ] ifte ; @@ -58,8 +62,9 @@ USE: strings dup wait-to-read-line read-line-fd-8 dup [ sbuf>str ] when ; : wait-to-accept ( socket -- ) - [ swap add-accept-io-task next-io-task drop ( call ) ] callcc0 ; + [ + swap add-accept-io-task next-io-task call + ] callcc0 drop ; : blocking-accept ( socket -- host port in out ) dup wait-to-accept accept-fd ; - diff --git a/native/fd.c b/native/fd.c index 310114b447..744e2fd73a 100644 --- a/native/fd.c +++ b/native/fd.c @@ -8,7 +8,13 @@ void init_io(void) bool can_read_line(PORT* port) { - return false; + if(port->line_ready) + return true; + else + { + read_line_step(port); + return port->line_ready; + } } void primitive_can_read_line(void) @@ -43,32 +49,61 @@ bool read_line_step(PORT* port) int i; char ch; - SBUF* line = untag_sbuf(port->line); + SBUF* line; + + if(port->line == F) + { + line = sbuf(LINE_SIZE); + port->line = tag_object(line); + } + else + { + line = untag_sbuf(port->line); + line->top = 0; + } for(i = port->buf_pos; i < port->buf_fill; i++) { ch = bget((CELL)port->buffer + sizeof(STRING) + i); + + if(ch == '\r') + { + if(i != port->buf_fill - 1) + { + ch = bget((CELL)port->buffer + + sizeof(STRING) + i + 1); + if(ch == '\n') + i++; + } + } + if(ch == '\n') { port->buf_pos = i + 1; + port->line_ready = true; return true; } else set_sbuf_nth(line,line->top,ch); } - port->buf_pos = port->buf_fill; - /* We've reached the end of the above loop, without seeing a newline or EOF, so read again */ + port->line_ready = false; return false; } void primitive_read_line_fd_8(void) { PORT* port = untag_port(dpeek()); - drepl(port->line); - port->line = F; + if(port->line_ready) + { + drepl(port->line); + port->line = F; + port->line_ready = false; + } + else + io_error(port,__FUNCTION__); } diff --git a/native/iomux.c b/native/iomux.c index 43651c41f7..472cbc49aa 100644 --- a/native/iomux.c +++ b/native/iomux.c @@ -111,11 +111,6 @@ bool set_up_fd_set(fd_set* fdset, int fd_count, IO_TASK* io_tasks) bool perform_read_line_io_task(PORT* port) { - if(port->line == F) - port->line = tag_object(sbuf(LINE_SIZE)); - else - untag_sbuf(port->line)->top = 0; - if(port->buf_pos >= port->buf_fill) { if(!read_step(port)) @@ -126,6 +121,7 @@ bool perform_read_line_io_task(PORT* port) { /* EOF */ port->line = F; + port->line_ready = true; return true; } else diff --git a/native/memory.c b/native/memory.c index e3858f6f92..6e9328ad2d 100644 --- a/native/memory.c +++ b/native/memory.c @@ -24,7 +24,7 @@ ZONE* zalloc(CELL size) ZONE* z = (ZONE*)malloc(sizeof(ZONE)); if(z == 0) fatal_error("Cannot allocate zone header",size); - z->base = z->here = (CELL)malloc(size); + z->base = z->here = align8((CELL)malloc(size)); if(z->base == 0) fatal_error("Cannot allocate zone",size); z->limit = z->base + size; @@ -40,28 +40,23 @@ void init_arena(CELL size) active = z1; } -void* allot(CELL a) +void check_memory(void) { - CELL h = active->here; - active->here = align8(active->here + a); + if(active->here > active->alarm) + { + if(active->here > active->limit) + { + printf("Out of memory\n"); + printf("active->base = %ld\n",active->base); + printf("active->here = %ld\n",active->here); + printf("active->limit = %ld\n",active->limit); + exit(1); + } - if(active->here > active->limit) - { - printf("Out of memory\n"); - printf("active->base = %ld\n",active->base); - printf("active->here = %ld\n",active->here); - printf("active->limit = %ld\n",active->limit); - printf("request = %ld\n",a); - exit(1); - } - else if(active->here > active->alarm) - { /* Execute the 'garbage-collection' word */ cpush(env.cf); env.cf = env.user[GC_ENV]; } - - return (void*)h; } void flip_zones() diff --git a/native/memory.h b/native/memory.h index db41363a66..c08025f7f2 100644 --- a/native/memory.h +++ b/native/memory.h @@ -15,13 +15,21 @@ ZONE* zalloc(CELL size); void init_arena(CELL size); void flip_zones(); -void* allot(CELL a); +void check_memory(void); INLINE CELL align8(CELL a) { return ((a & 7) == 0) ? a : ((a + 8) & ~7); } +INLINE void* allot(CELL a) +{ + CELL h = active->here; + active->here += align8(a); + check_memory(); + return (void*)h; +} + INLINE CELL get(CELL where) { return *((CELL*)where); diff --git a/native/port.c b/native/port.c index 92b47eaed0..0e48c5ffde 100644 --- a/native/port.c +++ b/native/port.c @@ -22,6 +22,7 @@ PORT* port(PORT_MODE type, CELL fd) port->client_port = F; port->client_socket = F; port->line = F; + port->line_ready = false; port->buf_fill = 0; port->buf_pos = 0; diff --git a/native/port.h b/native/port.h index 34f445861a..4793354666 100644 --- a/native/port.h +++ b/native/port.h @@ -8,6 +8,8 @@ typedef struct { STRING* buffer; /* tagged partial line used by read_line_fd */ CELL line; + /* is it ready to be returned? */ + bool line_ready; /* tagged client info used by accept_fd */ CELL client_host; CELL client_port;