1 /* ---------------------------------------------------------------------------
3 * (c) The GHC Team, 2001
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
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.
19 * --------------------------------------------------------------------------*/
20 #include "PosixSource.h"
23 #include "Capability.h"
27 initCapability( Capability *cap )
29 cap->f.stgChk0 = (F_)__stg_chk_0;
30 cap->f.stgChk1 = (F_)__stg_chk_1;
31 cap->f.stgGCEnter1 = (F_)__stg_gc_enter_1;
32 cap->f.stgUpdatePAP = (F_)__stg_update_PAP;
35 /* Free capability list.
36 * Locks required: sched_mutex.
39 static Capability *free_capabilities; /* Available capabilities for running threads */
42 void grabCapability(Capability** cap)
44 *cap = free_capabilities;
45 free_capabilities = (*cap)->link;
46 rts_n_free_capabilities--;
49 void releaseCapability(Capability** cap)
51 (*cap)->link = free_capabilities;
52 free_capabilities = *cap;
53 rts_n_free_capabilities++;
57 /* Allocate 'n' capabilities */
59 initCapabilities(nat n)
62 Capability *cap, *prev;
65 for (i = 0; i < n; i++) {
66 cap = stgMallocBytes(sizeof(Capability), "initCapabilities");
71 free_capabilities = cap;
72 rts_n_free_capabilities = n;
73 IF_DEBUG(scheduler,fprintf(stderr,"scheduler: Allocated %d capabilities\n", n_free_capabilities););