~ chicken-core (chicken-5) 027b8cbb97edcdc412529cc867bb7a1442b0afd5
commit 027b8cbb97edcdc412529cc867bb7a1442b0afd5 Author: felix <felix@call-with-current-continuation.org> AuthorDate: Thu Aug 26 16:50:26 2010 +0200 Commit: felix <felix@call-with-current-continuation.org> CommitDate: Thu Aug 26 16:50:26 2010 +0200 simplified fdset handling; fixed incorrectly named variable in ##sys#thread-unblock<bang> diff --git a/scheduler.scm b/scheduler.scm index 15d100be..93697522 100644 --- a/scheduler.scm +++ b/scheduler.scm @@ -32,7 +32,8 @@ ##sys#update-thread-state-buffer ##sys#restore-thread-state-buffer ##sys#remove-from-ready-queue ##sys#unblock-threads-for-i/o ##sys#force-primordial ##sys#fdset-input-set ##sys#fdset-output-set ##sys#fdset-clear - ##sys#fdset-select-timeout ##sys#fdset-restore + ##sys#fdset-select-timeout ##sys#fdset-set + ##sys#create-fdset ##sys#clear-i/o-state-for-thread! ##sys#abandon-mutexes) (not inline ##sys#interrupt-hook) (unsafe) @@ -73,7 +74,7 @@ C_word C_msleep(C_word ms) { return C_SCHEME_TRUE; } #endif -static fd_set C_fdset_input, C_fdset_output, C_fdset_input_2, C_fdset_output_2; +static fd_set C_fdset_input, C_fdset_output; #define C_fd_test_input(fd) C_mk_bool(FD_ISSET(C_unfix(fd), &C_fdset_input)) #define C_fd_test_output(fd) C_mk_bool(FD_ISSET(C_unfix(fd), &C_fdset_output)) EOF @@ -326,25 +327,31 @@ EOF ;;; `select()'-based blocking: -(define ##sys#fd-list '()) +(define ##sys#fd-list '()) ; ((FD1 THREAD1 ...) ...) + +(define (##sys#create-fdset) + (##sys#fdset-clear) + (let loop ((lst ##sys#fd-list)) + (unless (null? lst) + (let ((fd (caar lst))) + (for-each + (lambda (t) + (let ((p (##sys#slot t 11))) + (##sys#fdset-set fd (cdr p)))) + (cdar lst)) + (loop (cdr lst)))))) (define ##sys#fdset-select-timeout (foreign-lambda* int ([bool to] [double tm]) "struct timeval timeout;" "timeout.tv_sec = tm / 1000;" "timeout.tv_usec = fmod(tm, 1000) * 1000;" - "C_fdset_input_2 = C_fdset_input;" - "C_fdset_output_2 = C_fdset_output;" "C_return(select(FD_SETSIZE, &C_fdset_input, &C_fdset_output, NULL, to ? &timeout : NULL));") ) -(define ##sys#fdset-restore +(define (##sys#fdset-clear) (foreign-lambda* void () - "C_fdset_input = C_fdset_input_2;" - "C_fdset_output = C_fdset_output_2;") ) - -((foreign-lambda* void () - "FD_ZERO(&C_fdset_input);" - "FD_ZERO(&C_fdset_output);") ) + "FD_ZERO(&C_fdset_input);" + "FD_ZERO(&C_fdset_output);") ) (define ##sys#fdset-input-set (foreign-lambda* void ([int fd]) @@ -354,10 +361,13 @@ EOF (foreign-lambda* void ([int fd]) "FD_SET(fd, &C_fdset_output);" ) ) -(define ##sys#fdset-clear - (foreign-lambda* void ([int fd]) - "FD_CLR(fd, &C_fdset_input_2);" - "FD_CLR(fd, &C_fdset_output_2);") ) +(define (##sys#fdset-set fd i/o) + (case i/o + ((#t #:input) (##sys#fdset-input-set fd)) + ((#f #:output) (##sys#fdset-output-set fd)) + ((#:all) + (##sys#fdset-input-set fd) + (##sys#fdset-output-set fd) ) )) (define (##sys#thread-block-for-i/o! t fd i/o) (dbg t " blocks for I/O " fd) @@ -368,23 +378,18 @@ EOF (if (fx= fd (car a)) (##sys#setslot a 1 (cons t (cdr a))) (loop (cdr lst)) ) ) ) ) - (case i/o - ((#t #:input) (##sys#fdset-input-set fd)) - ((#f #:output) (##sys#fdset-output-set fd)) - ((#:all) - (##sys#fdset-input-set fd) - (##sys#fdset-output-set fd) ) ) (##sys#setslot t 3 'blocked) (##sys#setislot t 13 #f) (##sys#setslot t 11 (cons fd i/o)) ) (define (##sys#unblock-threads-for-i/o) (dbg "fd-list: " ##sys#fd-list) + (##sys#create-fdset) (let* ([to? (pair? ##sys#timeout-list)] [rq? (pair? ##sys#ready-queue-head)] [n (##sys#fdset-select-timeout ; we use FD_SETSIZE, but really should use max fd (or rq? to?) - (if (and to? (not rq?)) ; no thread was unblocked by timeout, so wait + (if (and to? (not rq?)) ; no thread was unblocked by timeout, so wait (let* ((tmo1 (caar ##sys#timeout-list)) (now (##core#inline_allocate ("C_a_i_current_milliseconds" 4) #f))) (fpmax 0.0 (fp- tmo1 now)) ) @@ -405,9 +410,7 @@ EOF (if (or inf outf) (let loop2 ([threads (cdr a)]) (if (null? threads) - (begin - (##sys#fdset-clear fd) - (loop (sub1 n) (cdr lst)) ) + (loop (sub1 n) (cdr lst)) (let* ([t (car threads)] [p (##sys#slot t 11)] ) (when (and (pair? p) @@ -415,32 +418,28 @@ EOF (not (##sys#slot t 13) ) ) ; not unblocked by timeout (##sys#thread-basic-unblock! t) ) (loop2 (cdr threads)) ) ) ) - (cons a (loop n (cdr lst))) ) ) ) ) ) ] ) - (##sys#fdset-restore) ) ) + (cons a (loop n (cdr lst))) ) ) ) ) ) ] ))) ;;; Clear I/O state for unblocked thread (define (##sys#clear-i/o-state-for-thread! t) (when (pair? (##sys#slot t 11)) - (let ((fd (##sys#slot (##sys#slot t 11) 0))) + (let ((fd (car (##sys#slot t 11)))) (set! ##sys#fd-list (let loop ([lst ##sys#fd-list]) (if (null? lst) '() - (let* ([a (##sys#slot lst 0)] - [fd2 (##sys#slot a 0)] ) + (let* ([a (car lst)] + [fd2 (car a)] ) (if (eq? fd fd2) - (let ((ts (##sys#delq t (##sys#slot a 1)))) ; remove from fd-list entry + (let ((ts (##sys#delq t (cdr a)))) ; remove from fd-list entry (cond ((null? ts) - ;;(pp `(CLEAR FD: ,fd ,t) ##sys#standard-error) - (##sys#fdset-clear fd) ; no more threads waiting for this fd - (##sys#fdset-restore) - (##sys#slot lst 1) ) + (cdr lst) ) (else (##sys#setslot a 1 ts) ; fd-list entry is list with t removed lst) ) ) - (cons a (loop (##sys#slot lst 1))))))))))) + (cons a (loop (cdr lst))))))))))) ;;; Get list of all threads that are ready or waiting for timeout or waiting for I/O: @@ -491,7 +490,7 @@ EOF (define (##sys#thread-unblock! t) (when (or (eq? 'blocked (##sys#slot t 3)) - (eq? 'sleeping (##sys#slot r 3))) + (eq? 'sleeping (##sys#slot t 3))) (##sys#remove-from-timeout-list t) (set! ##sys#fd-list (let loop ([fdl ##sys#fd-list])Trap