[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Chicken-users] Improving the scheduler
From: |
Chris Double |
Subject: |
[Chicken-users] Improving the scheduler |
Date: |
Mon, 19 May 2003 03:31:29 +1200 |
User-agent: |
KMail/1.5.1 |
Currently a thread-sleep! can cause a busy loop in the scheduler if no other
threads are ready. For example, starting 'csi' and executing (thread-sleep!
20) will cause the only thread to sleep for 20 seconds. But the scheduler
loops busily for that entire 20 seconds checking the timeouts.
I propose adding to the scheduler before the 'loop2' loop something like the
following:
--------------8<-------------
;; If there are no threads blocking on a select call (fd-list)
;; but there are threads in the timeout list then sleep for
;; the number of microseconds of next thread to wake up.
(when (and (not (pair? ##sys#ready-queue-head))
(null? ##sys#fd-list)
(pair? ##sys#timeout-list))
(let* ([tmo1 (caar ##sys#timeout-list)]
[now (##sys#fudge 16)])
(when (< now tmo1)
(usleep (- tmo1 now))))
(loop1))
--------------8<-------------
Where the usleep call wraps the system function usleep (which sleeps for a
specified number of milliseconds).
--------------8<-------------
(define usleep (foreign-lambda int "usleep" unsigned-long))
--------------8<-------------
This means when there are no ready threads, no threads waiting on file
selectors and threads waiting for a timeout then the process will sleep for
the number of seconds for the next timeout thread to awaken.
For the case where there are no ready threads but there are threads waiting
for file selectors and timeouts then ##sys#unblock-threads-for-i/o could be
changed to include:
------------------8<-----------------------
(dbg "fd-list: " ##sys#fd-list)
(let* ([n (##sys#fdset-select-timeout
(or (pair? ##sys#ready-queue-head)
(pair? ##sys#timeout-list) )
(if (and (pair? ##sys#timeout-list) ;if threads are waiting for
timeout
(not (pair? ##sys#ready-queue-head)))
(let* ([tmo1 (caar ##sys#timeout-list)]
[now (##sys#fudge 16)])
(if (< now tmo1) ; set timeout to be that of next timeout
thread.
(- tmo1 now)
0))
0) ) ] ) ; otherwise immediate timeout.
(dbg n " fds ready")
------------------8<-----------------------
The fdset-select-timeout function is:
------------------8<-----------------------
(define ##sys#fdset-select-timeout
(foreign-lambda* int ([bool to] [int tm])
"struct timeval timeout;"
"timeout.tv_sec = 0;"
"timeout.tv_usec = tm;"
"C_fdset_input_2 = C_fdset_input;"
"C_fdset_output_2 = C_fdset_output;"
"return(select(FD_SETSIZE, &C_fdset_input, &C_fdset_output, NULL, to ?
&timeout : NULL));") )
------------------8<-----------------------
This should reduce the CPU usage for Chicken in the case of threads that are
sleeping with thread-sleep! and/or waiting on a socket/file handle and with
no ready threads to zero. I have this case in some OpenGL examples that use
animation.
Is it possible for something like this to be added to the Chicken scheduler?
Chris.
--
http://radio.weblogs.com/0102385
- [Chicken-users] Improving the scheduler,
Chris Double <=