[project @ 2002-02-04 20:14:56 by sof]
[ghc-hetmet.git] / ghc / rts / Capability.c
1 /* ---------------------------------------------------------------------------
2  *
3  * (c) The GHC Team, 2001
4  *
5  * Capabilities
6  *
7  * The notion of a capability is used when operating in multi-threaded
8  * environments (which the SMP and Threads builds of the RTS do), to
9  * hold all the state an OS thread/task needs to run Haskell code:
10  * its STG registers, a pointer to its  TSO, a nursery etc. During
11  * STG execution, a pointer to the capabilitity is kept in a 
12  * register (BaseReg).
13  *
14  * Only in an SMP build will there be multiple capabilities, the threaded
15  * RTS and other non-threaded builds, there is one global capability,
16  * namely MainRegTable.
17  *
18  * 
19  * --------------------------------------------------------------------------*/
20 #include "PosixSource.h"
21 #include "Rts.h"
22 #include "RtsUtils.h"
23 #include "Capability.h"
24
25
26 static
27 void
28 initCapability( Capability *cap )
29 {
30     cap->f.stgChk0         = (F_)__stg_chk_0;
31     cap->f.stgChk1         = (F_)__stg_chk_1;
32     cap->f.stgGCEnter1     = (F_)__stg_gc_enter_1;
33     cap->f.stgUpdatePAP    = (F_)__stg_update_PAP;
34 }
35
36 #ifdef SMP
37 static void initCapabilities_(nat n);
38 #endif
39
40 /* 
41  */
42 void
43 initCapabilities()
44 {
45 #if defined(SMP)
46   initCapabilities_(RtsFlags.ParFlags.nNodes);
47 #else
48   initCapability(&MainCapability);
49 #endif
50
51   return;
52 }
53
54 /* Free capability list.
55  * Locks required: sched_mutex.
56  */
57 #if defined(SMP)
58 static Capability *free_capabilities; /* Available capabilities for running threads */
59 #endif
60
61 void grabCapability(Capability** cap)
62 {
63 #if !defined(SMP)
64   *cap = &MainCapability;
65 #else
66   *cap = free_capabilities;
67   free_capabilities = (*cap)->link;
68   rts_n_free_capabilities--;
69 #endif
70 }
71
72 void releaseCapability(Capability** cap)
73 {
74 #if defined(SMP)
75   (*cap)->link = free_capabilities;
76   free_capabilities = *cap;
77   rts_n_free_capabilities++;
78 #endif
79   return;
80 }
81
82 #if defined(SMP)
83 /* Allocate 'n' capabilities */
84 static void
85 initCapabilities_(nat n)
86 {
87   nat i;
88   Capability *cap, *prev;
89   cap  = NULL;
90   prev = NULL;
91   for (i = 0; i < n; i++) {
92     cap = stgMallocBytes(sizeof(Capability), "initCapabilities");
93     initCapability(cap);
94     cap->link = prev;
95     prev = cap;
96   }
97   free_capabilities = cap;
98   rts_n_free_capabilities = n;
99   IF_DEBUG(scheduler,fprintf(stderr,"scheduler: Allocated %d capabilities\n", n_free_capabilities););
100 }
101 #endif /* SMP */
102