/[guile]/guile/guile-core/libguile/null-threads.c
ViewVC logotype

Diff of /guile/guile-core/libguile/null-threads.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.2 by mvo, Mon Oct 21 12:03:54 2002 UTC revision 1.3 by mvo, Sun Oct 27 20:12:27 2002 UTC
# Line 49  Line 49 
49  #include <sys/time.h>  #include <sys/time.h>
50  #include <sys/types.h>  #include <sys/types.h>
51  #include <time.h>  #include <time.h>
52    #include <stdio.h>
53    
54  void *scm_null_threads_data;  void *scm_null_threads_data;
55    
56  static SCM main_thread;  static SCM main_thread;
57    
58    typedef struct {
59      int level;
60    } scm_null_mutex;
61    
62    typedef struct {
63      int signalled;
64    } scm_null_cond;
65    
66  void  void
67  scm_threads_init (SCM_STACKITEM *i)  scm_threads_init (SCM_STACKITEM *i)
68  {  {
69      scm_tc16_thread = scm_make_smob_type ("thread", 0);
70      scm_tc16_mutex = scm_make_smob_type ("mutex", sizeof (scm_null_mutex));
71      scm_tc16_condvar = scm_make_smob_type ("condition-variable",
72                                             sizeof (scm_null_cond));
73    
74    main_thread = scm_permanent_object (scm_cell (scm_tc16_thread, 0));    main_thread = scm_permanent_object (scm_cell (scm_tc16_thread, 0));
75    scm_null_threads_data = NULL;    scm_null_threads_data = NULL;
76  }  }
# Line 147  scm_join_thread (SCM thread) Line 161  scm_join_thread (SCM thread)
161  }  }
162  #undef FUNC_NAME  #undef FUNC_NAME
163    
 SCM  
 scm_yield (void)  
 {  
   return SCM_BOOL_T;  
 }  
   
 /* Block until a new async might have been queued.  
  */  
 static void  
 block ()  
 {  
   select (0, NULL, NULL, NULL, NULL);  
 }  
   
164  int  int
165  scm_null_mutex_init (scm_null_mutex *m)  scm_c_thread_exited_p (SCM thread)
166    #define FUNC_NAME s_scm_thread_exited_p
167  {  {
   m->locked = 0;  
168    return 0;    return 0;
169  }  }
170    #undef FUNC_NAME
171    
172  int  SCM
173  scm_null_mutex_lock (scm_null_mutex *m)  scm_yield (void)
 {  
   while (m->locked)  
     {  
       block ();  
       SCM_ASYNC_TICK;  
     }  
   m->locked = 1;  
   return 1;  
 }  
   
 int  
 scm_null_mutex_unlock (scm_null_mutex *m)  
 {  
   if (m->locked == 0)  
     return 0;  
   m->locked = 0;  
   return 1;  
 }  
   
 int  
 scm_null_mutex_destroy (scm_null_mutex *m)  
174  {  {
175    return 1;    return SCM_BOOL_T;
176  }  }
177    
178  SCM  SCM
179  scm_make_mutex (void)  scm_make_mutex (void)
180  {  {
181    SCM m = scm_make_smob (scm_tc16_mutex);    SCM m = scm_make_smob (scm_tc16_mutex);
182    scm_null_mutex_init (SCM_MUTEX_DATA(m));    scm_null_mutex *mx = SCM_MUTEX_DATA(m);
183      mx->level = 0;
184    return m;    return m;
185  }  }
186    
187  SCM  SCM
188  scm_lock_mutex (SCM m)  scm_lock_mutex (SCM m)
189  {  {
190      scm_null_mutex *mx;
191    SCM_ASSERT (SCM_MUTEXP (m), m, SCM_ARG1, s_lock_mutex);    SCM_ASSERT (SCM_MUTEXP (m), m, SCM_ARG1, s_lock_mutex);
192    scm_null_mutex_lock (SCM_MUTEX_DATA(m));    mx = SCM_MUTEX_DATA(m);
193      mx->level++;
194    return SCM_BOOL_T;    return SCM_BOOL_T;
195  }  }
196    
197  SCM  SCM
198    scm_try_mutex (SCM m)
199    {
200      return scm_lock_mutex (m); /* will always succeed right away. */
201    }
202    
203    SCM
204  scm_unlock_mutex (SCM m)  scm_unlock_mutex (SCM m)
205  {  {
206      scm_null_mutex *mx;
207    SCM_ASSERT (SCM_MUTEXP (m), m, SCM_ARG1, s_unlock_mutex);    SCM_ASSERT (SCM_MUTEXP (m), m, SCM_ARG1, s_unlock_mutex);
208    if (!scm_null_mutex_unlock (SCM_MUTEX_DATA(m)))    mx = SCM_MUTEX_DATA(m);
209      if (mx->level == 0)
210      scm_misc_error (s_unlock_mutex, "mutex is not locked", SCM_EOL);      scm_misc_error (s_unlock_mutex, "mutex is not locked", SCM_EOL);
211      mx->level--;
212    return SCM_BOOL_T;    return SCM_BOOL_T;
213  }  }
214    
 int  
 scm_null_condvar_init (scm_null_condvar *c)  
 {  
   c->signalled = 0;  
   return 0;  
 }  
   
 int  
 scm_null_condvar_wait (scm_null_condvar *c, scm_null_mutex *m)  
 {  
   scm_null_mutex_unlock (m);  
   while (!c->signalled)  
     {  
       block ();  
       SCM_ASYNC_TICK;  
     }  
   scm_null_mutex_lock (m);  
   c->signalled = 0;  
   return 0;  
 }  
   
 int  
 scm_null_condvar_signal (scm_null_condvar *c)  
 {  
   c->signalled = 1;  
   return 0;  
 }  
   
 int  
 scm_null_condvar_destroy (scm_null_condvar *c)  
 {  
   return 1;  
 }  
   
215  SCM  SCM
216  scm_make_condition_variable (void)  scm_make_condition_variable (void)
217  {  {
218      scm_null_cond *cv;
219    SCM c = scm_make_smob (scm_tc16_condvar);    SCM c = scm_make_smob (scm_tc16_condvar);
220    scm_null_condvar_init (SCM_CONDVAR_DATA (c));    cv = SCM_CONDVAR_DATA (c);
221      cv->signalled = 0;
222    return c;    return c;
223  }  }
224    
225    /* Subtract the `struct timeval' values X and Y,
226       storing the result in RESULT.  Might modify Y.
227       Return 1 if the difference is negative or zero, otherwise 0.  */
228    
229    static int
230    timeval_subtract (result, x, y)
231         struct timeval *result, *x, *y;
232    {
233      /* Perform the carry for the later subtraction by updating Y. */
234      if (x->tv_usec < y->tv_usec) {
235        int nsec = (y->tv_usec - x->tv_usec) / 1000000 + 1;
236        y->tv_usec -= 1000000 * nsec;
237        y->tv_sec += nsec;
238      }
239      if (x->tv_usec - y->tv_usec > 1000000) {
240        int nsec = (x->tv_usec - y->tv_usec) / 1000000;
241        y->tv_usec += 1000000 * nsec;
242        y->tv_sec -= nsec;
243      }
244      
245      /* Compute the time remaining to wait.
246         `tv_usec' is certainly positive. */
247      result->tv_sec = x->tv_sec - y->tv_sec;
248      result->tv_usec = x->tv_usec - y->tv_usec;
249      
250      /* Return 1 if result is negative or zero. */
251      return x->tv_sec < y->tv_sec
252        || (result->tv_sec == 0 && result->tv_usec == 0);
253    }
254    
255  SCM  SCM
256  scm_wait_condition_variable (SCM c, SCM m)  scm_timed_wait_condition_variable (SCM c, SCM m, SCM t)
257    #define FUNC_NAME s_wait_condition_variable
258  {  {
259      scm_null_cond *cv;
260      struct timeval waittime;
261    
262    SCM_ASSERT (SCM_CONDVARP (c),    SCM_ASSERT (SCM_CONDVARP (c),
263                c,                c,
264                SCM_ARG1,                SCM_ARG1,
# Line 273  scm_wait_condition_variable (SCM c, SCM Line 267  scm_wait_condition_variable (SCM c, SCM
267                m,                m,
268                SCM_ARG2,                SCM_ARG2,
269                s_wait_condition_variable);                s_wait_condition_variable);
270    scm_null_condvar_wait (SCM_CONDVAR_DATA (c), SCM_MUTEX_DATA (m));    if (!SCM_UNBNDP (t))
271    return SCM_BOOL_T;      {
272          if (SCM_CONSP (t))
273            {
274              SCM_VALIDATE_UINT_COPY (3, SCM_CAR(t), waittime.tv_sec);
275              SCM_VALIDATE_UINT_COPY (3, SCM_CDR(t), waittime.tv_usec);
276            }
277          else
278            {
279              SCM_VALIDATE_UINT_COPY (3, t, waittime.tv_sec);
280              waittime.tv_usec = 0;
281            }
282        }
283    
284      cv = SCM_CONDVAR_DATA (c);
285    
286      scm_unlock_mutex (m);
287      while (!cv->signalled)
288        {
289          if (SCM_UNBNDP (t))
290            select (0, NULL, NULL, NULL, NULL);
291          else
292            {
293              struct timeval now, then, diff;
294              then = waittime;
295              gettimeofday (&now, NULL);
296              if (timeval_subtract (&diff, &then, &now))
297                break;
298              select (0, NULL, NULL, NULL, &diff);
299            }
300          SCM_ASYNC_TICK;
301        }
302      scm_lock_mutex (m);
303      if (cv->signalled)
304        {
305          cv->signalled = 0;
306          return SCM_BOOL_T;
307        }
308      return SCM_BOOL_F;
309  }  }
310    #undef FUNC_NAME
311    
312  SCM  SCM
313  scm_signal_condition_variable (SCM c)  scm_signal_condition_variable (SCM c)
314  {  {
315      scm_null_cond *cv;
316    SCM_ASSERT (SCM_CONDVARP (c),    SCM_ASSERT (SCM_CONDVARP (c),
317                c,                c,
318                SCM_ARG1,                SCM_ARG1,
319                s_signal_condition_variable);                s_signal_condition_variable);
320    scm_null_condvar_signal (SCM_CONDVAR_DATA (c));    cv = SCM_CONDVAR_DATA (c);
321      cv->signalled = 1;
322    return SCM_BOOL_T;    return SCM_BOOL_T;
323  }  }
324    
325    SCM
326    scm_broadcast_condition_variable (SCM c)
327    {
328      return scm_signal_condition_variable (c); /* only one thread anyway. */
329    }
330    
331  unsigned long  unsigned long
332  scm_thread_usleep (unsigned long usec)  scm_thread_usleep (unsigned long usec)
333  {  {

Legend:
Removed from v.1.2  
changed lines
  Added in v.1.3

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26