chicken-users
[Top][All Lists]
Advanced

[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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]