/[hurd]/hurd/libthreads/cthreads.c
ViewVC logotype

Diff of /hurd/libthreads/cthreads.c

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

revision 1.11 by roland, Wed May 8 09:37:07 2002 UTC revision 1.12 by roland, Mon May 27 02:50:10 2002 UTC
# Line 1  Line 1 
1  /*  /*
2   * Mach Operating System   * Mach Operating System
3   * Copyright (c) 1991,1990,1989 Carnegie Mellon University   * Copyright (c) 1992,1991,1990,1989 Carnegie Mellon University
4   * All Rights Reserved.   * All Rights Reserved.
5   *   *
6   * Permission to use, copy, modify and distribute this software and its   * Permission to use, copy, modify and distribute this software and its
# Line 25  Line 25 
25   */   */
26  /*  /*
27   * HISTORY   * HISTORY
28   * $Log$   * 20-Oct-93  Tero Kivinen (kivinen) at Helsinki University of Technology
29   * Revision 1.11  2002/05/08 09:37:07  roland   *      Renamed cthread_t->catch to to cthread_t->catch_exit, because
30   * 2002-05-08  Roland McGrath  <roland@frob.com>   *      catch is reserved word in c++.
  *  
  *      * cthreads.c (cthread_exit): Cast any_t to long before int.  
31   *   *
32   * Revision 1.10  2001/03/31 23:01:01  roland   * $Log$
33   * 2001-03-31  Roland McGrath  <roland@frob.com>   * Revision 1.12  2002/05/27 02:50:10  roland
34     * 2002-05-26  Roland McGrath  <roland@frob.com>
35   *   *
36   *      * cthreads.h: Fix obsolescent #endif syntax.   *      Changes merged from CMU MK83a version:
37   *      * cthread_internals.h: Likewise.   *      * cthreads.h, options.h: Various cleanups.
38   *      * cancel-cond.c: Likewise.   *      * call.c, cthread_data.c, sync.c, mig_support.c: Likewise.
39   *      * stack.c: Likewise.   *      * i386/cthreads.h, i386/thread.c, i386/lock.s: Likewise.
40     *      * cthread_internals.h: Add decls for internal functions.
41     *      (struct cproc): Use vm_offset_t for stack_base and stack_size members.
42     *      Use natural_t for context member.
43     *      * cprocs.c: Use prototypes for all defns.
44   *      * cthreads.c: Likewise.   *      * cthreads.c: Likewise.
45   *      * cprocs.c: Likewise.   *      (cthread_exit): Cast any_t to integer_t before int.
  *      * call.c: Likewise.  
  *  
  * Revision 1.9  1998/11/22 18:18:10  roland  
  * 1998-11-12  Mark Kettenis  <kettenis@phys.uva.nl>  
  *  
  *      * cthreads.c (cthread_init): Move cthread_alloc call before  
  *      cproc_init call, since cthread_alloc uses malloc, and malloc won't  
  *      work between initializing the new stack and switching over to it.  
  *  
  * Revision 1.8  1998/06/10 19:38:01  tb  
  * Tue Jun  9 13:50:09 1998  Thomas Bushnell, n/BSG  <tb@mit.edu>  
  *  
  *      * cthreads.c (cthread_fork_prepare): Don't call  
  *      malloc_fork_prepare since we are no longer providing our own  
  *      malloc in this library.  
  *      (cthread_fork_parent): Likewise, for malloc_fork_parent.  
  *      (cthread_fork_child): Likewize, for malloc_fork_child.  
  *  
  * Revision 1.7  1997/08/20 19:41:20  thomas  
  * Wed Aug 20 15:39:44 1997  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>  
46   *   *
47   *      * cthreads.c (cthread_body): Wire self before calling user work   * Revision 2.13  93/01/21  12:27:55  danner
48   *      function.  This way all cthreads will be wired, which the ports   *      Remove deadlock in cproc_fork_child; must release malloc lock first.
49   *      library (and hurd_thread_cancel, etc.) depend on.   *      [93/01/19  16:37:43  bershad]
50     *
51     * Revision 2.12  93/01/14  18:05:00  danner
52     *      Converted file to ANSI C.
53     *      Removed use of obsolete type any_t.
54     *      [92/12/18            pds]
55     *      64bit cleanup.
56     *      [92/12/01            af]
57   *   *
58   * Revision 1.6  1997/06/10 01:22:19  thomas   *      Free private_data in cthread_exit, from Mike Kupfer.
59   * Mon Jun  9 21:18:46 1997  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>   *      [92/11/30            af]
  *  
  *      * cthreads.c (cthread_fork): Delete debugging oddity that crept  
  *      into source.  
  *  
  * Revision 1.5  1997/04/04 01:30:35  thomas  
  * *** empty log message ***  
  *  
  * Revision 1.4  1994/05/05 18:13:57  roland  
  * entered into RCS  
60   *   *
61   * Revision 2.11  92/07/20  13:33:37  cmaeda   * Revision 2.11  92/07/20  13:33:37  cmaeda
62   *      In cthread_init, do machine dependent initialization if it's defined.   *      In cthread_init, do machine dependent initialization if it's defined.
# Line 152  Line 133 
133   */   */
134    
135  #include <cthreads.h>  #include <cthreads.h>
136    #include <mach/mig_support.h>
137  #include "cthread_internals.h"  #include "cthread_internals.h"
138    
139  /*  /*
  * C Threads imports:  
  */  
 extern void cproc_create();  
 extern vm_offset_t cproc_init();  
 extern void mig_init();  
   
 /*  
  * Mach imports:  
  */  
   
 /*  
  * C library imports:  
  */  
   
 /*  
140   * Thread status bits.   * Thread status bits.
141   */   */
142  #define T_MAIN          0x1  #define T_MAIN          0x1
143  #define T_RETURNED      0x2  #define T_RETURNED      0x2
144  #define T_DETACHED      0x4  #define T_DETACHED      0x4
145    
146  #ifdef  DEBUG  #if     defined(DEBUG)
147  int cthread_debug = FALSE;  int cthread_debug = FALSE;
148  #endif   /* DEBUG */  #endif  /* defined(DEBUG) */
149    
150  private struct cthread_queue cthreads = QUEUE_INITIALIZER;  private struct cthread_queue cthreads = QUEUE_INITIALIZER;
151  private struct mutex cthread_lock = MUTEX_INITIALIZER;  private struct mutex cthread_lock = MUTEX_INITIALIZER;
# Line 194  private spin_lock_t free_lock = SPIN_LOC Line 161  private spin_lock_t free_lock = SPIN_LOC
161  private struct cthread initial_cthread = { 0 };  private struct cthread initial_cthread = { 0 };
162    
163  private cthread_t  private cthread_t
164  cthread_alloc(func, arg)  cthread_alloc(cthread_fn_t func, void *arg)
         cthread_fn_t func;  
         any_t arg;  
165  {  {
166          register cthread_t t = NO_CTHREAD;          register cthread_t t = NO_CTHREAD;
167    
# Line 228  cthread_alloc(func, arg) Line 193  cthread_alloc(func, arg)
193  }  }
194    
195  private void  private void
196  cthread_free(t)  cthread_free(cthread_t t)
         register cthread_t t;  
197  {  {
198          spin_lock(&free_lock);          spin_lock(&free_lock);
199          t->next = free_cthreads;          t->next = free_cthreads;
# Line 237  cthread_free(t) Line 201  cthread_free(t)
201          spin_unlock(&free_lock);          spin_unlock(&free_lock);
202  }  }
203    
204  int  vm_offset_t
205  cthread_init()  cthread_init(void)
206  {  {
207          static int cthreads_started = FALSE;          static int cthreads_started = FALSE;
208          register cproc_t p;          register cproc_t p;
# Line 247  cthread_init() Line 211  cthread_init()
211    
212          if (cthreads_started)          if (cthreads_started)
213                  return 0;                  return 0;
         t = cthread_alloc((cthread_fn_t) 0, (any_t) 0);  
214          stack = cproc_init();          stack = cproc_init();
215          cthread_cprocs = 1;          cthread_cprocs = 1;
216            t = cthread_alloc((cthread_fn_t) 0, (void *) 0);
217    
218  #ifdef cthread_md_init  #ifdef cthread_md_init
219          cthread_md_init();          cthread_md_init();
# Line 275  cthread_init() Line 239  cthread_init()
239    
240  /*  /*
241   * Used for automatic initialization by crt0.   * Used for automatic initialization by crt0.
  * Cast needed since too many C compilers choke on the type void (*)().  
242   */   */
243  int (*_cthread_init_routine)() = (int (*)()) cthread_init;  vm_offset_t (*_cthread_init_routine)(void) = cthread_init;
244    
245    
246  /*  /*
247   * Procedure invoked at the base of each cthread.   * Procedure invoked at the base of each cthread.
248   */   */
249  void  void
250  cthread_body(self)  cthread_body(cproc_t self)
         cproc_t self;  
251  {  {
252          register cthread_t t;          register cthread_t t;
253    
# Line 302  cthread_body(self) Line 265  cthread_body(self)
265                           */                           */
266                          mutex_unlock(&cthread_lock);                          mutex_unlock(&cthread_lock);
267                          cthread_assoc(self, t);         /* assume thread's identity */                          cthread_assoc(self, t);         /* assume thread's identity */
268                          if (_setjmp(t->catch) == 0) {   /* catch for cthread_exit() */                          if (_setjmp(t->catch_exit) == 0) {      /* catch for cthread_exit() */
                                 cthread_wire ();  
269                                  /*                                  /*
270                                   * Execute the fork request.                                   * Execute the fork request.
271                                   */                                   */
# Line 338  cthread_body(self) Line 300  cthread_body(self)
300  }  }
301    
302  cthread_t  cthread_t
303  cthread_fork(func, arg)  cthread_fork(cthread_fn_t func, void *arg)
         cthread_fn_t func;  
         any_t arg;  
304  {  {
305          register cthread_t t;          register cthread_t t;
306    
# Line 372  cthread_detach(t) Line 332  cthread_detach(t)
332          }          }
333  }  }
334    
335  any_t  void *
336  cthread_join(t)  cthread_join(cthread_t t)
         cthread_t t;  
337  {  {
338          any_t result;          void *result;
339    
340          TRACE(printf("[%s] join(%s)\n", cthread_name(cthread_self()), cthread_name(t)));          TRACE(printf("[%s] join(%s)\n", cthread_name(cthread_self()), cthread_name(t)));
341          mutex_lock(&t->lock);          mutex_lock(&t->lock);
# Line 390  cthread_join(t) Line 349  cthread_join(t)
349  }  }
350    
351  void  void
352  cthread_exit(result)  cthread_exit(void *result)
         any_t result;  
353  {  {
354          register cthread_t t = cthread_self();          register cthread_t t = cthread_self();
355    
356          TRACE(printf("[%s] exit()\n", cthread_name(t)));          TRACE(printf("[%s] exit()\n", cthread_name(t)));
357          t->result = result;          t->result = result;
358            if (t->private_data != 0) {
359                    free((char *)t->private_data);
360                    t->private_data = 0;
361            }
362          if (t->state & T_MAIN) {          if (t->state & T_MAIN) {
363                  mutex_lock(&cthread_lock);                  mutex_lock(&cthread_lock);
364                  while (cthread_cthreads > 1)                  while (cthread_cthreads > 1)
365                          condition_wait(&cthread_idle, &cthread_lock);                          condition_wait(&cthread_idle, &cthread_lock);
366                  mutex_unlock(&cthread_lock);                  mutex_unlock(&cthread_lock);
367                  exit((int)(long)result);                  exit((int) (integer_t) result);
368          } else {          } else {
369                  _longjmp(t->catch, TRUE);                  _longjmp(t->catch_exit, TRUE);
370          }          }
371  }  }
372    
# Line 415  cthread_exit(result) Line 377  cthread_exit(result)
377  int (*_cthread_exit_routine)() = (int (*)()) cthread_exit;  int (*_cthread_exit_routine)() = (int (*)()) cthread_exit;
378    
379  void  void
380  cthread_set_name(t, name)  cthread_set_name(cthread_t t, const char *name)
         cthread_t t;  
         char *name;  
381  {  {
382          t->name = name;          t->name = name;
383  }  }
384    
385  char *  const char *
386  cthread_name(t)  cthread_name(cthread_t t)
         cthread_t t;  
387  {  {
388          return (t == NO_CTHREAD          return (t == NO_CTHREAD ? "idle" : (t->name == 0 ? "?" : t->name));
                 ? "idle"  
                 : (t->name == 0 ? "?" : t->name));  
389  }  }
390    
391  int  int
392  cthread_limit()  cthread_limit(void)
393  {  {
394          return cthread_max_cprocs;          return cthread_max_cprocs;
395  }  }
396    
397  void  void
398  cthread_set_limit(n)  cthread_set_limit(int n)
         int n;  
399  {  {
400          cthread_max_cprocs = n;          cthread_max_cprocs = n;
401  }  }
402    
403  int  int
404  cthread_count()  cthread_count(void)
405  {  {
406          return cthread_cthreads;          return cthread_cthreads;
407  }  }
408    
409  cthread_fork_prepare()  void
410    cthread_fork_prepare(void)
411  {  {
412      spin_lock(&free_lock);      spin_lock(&free_lock);
413      mutex_lock(&cthread_lock);      mutex_lock(&cthread_lock);
414        malloc_fork_prepare();
415      cproc_fork_prepare();      cproc_fork_prepare();
416  }  }
417    
418  cthread_fork_parent()  void
419    cthread_fork_parent(void)
420  {  {
421      cproc_fork_parent();      cproc_fork_parent();
422        malloc_fork_parent();
423      mutex_unlock(&cthread_lock);      mutex_unlock(&cthread_lock);
424      spin_unlock(&free_lock);      spin_unlock(&free_lock);
425  }  }
426    
427  cthread_fork_child()  void
428    cthread_fork_child(void)
429  {  {
430      cthread_t t;      cthread_t t;
431      cproc_t p;      cproc_t p;
432    
433        malloc_fork_child();
434      cproc_fork_child();      cproc_fork_child();
435      mutex_unlock(&cthread_lock);      mutex_unlock(&cthread_lock);
436      spin_unlock(&free_lock);      spin_unlock(&free_lock);

Legend:
Removed from v.1.11  
changed lines
  Added in v.1.12

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