| | 88 | |
| | 89 | == More about Capabilities == |
| | 90 | |
| | 91 | It is useful to understand capabilities well because it is closely tied to the maintenance of the program roots and multithreading in Haskell - all of which the GC has to be aware of. If however you are readin this the first time, you may want to skip this section and come back to it later. |
| | 92 | |
| | 93 | Capabilities are defined in capability.h. The file OSThreads.h provide an platform neutral absraction for OS level threads used by Haskell. |
| | 94 | |
| | 95 | {{{ |
| | 96 | struct Capability_ { |
| | 97 | // State required by the STG virtual machine when running Haskell |
| | 98 | // code. During STG execution, the BaseReg register always points |
| | 99 | // to the StgRegTable of the current Capability (&cap->r). |
| | 100 | StgFunTable f; |
| | 101 | StgRegTable r; |
| | 102 | |
| | 103 | nat no; // capability number. |
| | 104 | |
| | 105 | // The Task currently holding this Capability. This task has |
| | 106 | // exclusive access to the contents of this Capability (apart from |
| | 107 | // returning_tasks_hd/returning_tasks_tl). |
| | 108 | // Locks required: cap->lock. |
| | 109 | Task *running_task; |
| | 110 | |
| | 111 | // true if this Capability is running Haskell code, used for |
| | 112 | // catching unsafe call-ins. |
| | 113 | rtsBool in_haskell; |
| | 114 | |
| | 115 | // The run queue. The Task owning this Capability has exclusive |
| | 116 | // access to its run queue, so can wake up threads without |
| | 117 | // taking a lock, and the common path through the scheduler is |
| | 118 | // also lock-free. |
| | 119 | StgTSO *run_queue_hd; |
| | 120 | StgTSO *run_queue_tl; |
| | 121 | |
| | 122 | // Tasks currently making safe foreign calls. Doubly-linked. |
| | 123 | // When returning, a task first acquires the Capability before |
| | 124 | // removing itself from this list, so that the GC can find all |
| | 125 | // the suspended TSOs easily. Hence, when migrating a Task from |
| | 126 | // the returning_tasks list, we must also migrate its entry from |
| | 127 | // this list. |
| | 128 | Task *suspended_ccalling_tasks; |
| | 129 | |
| | 130 | // One mutable list per generation, so we don't need to take any |
| | 131 | // locks when updating an old-generation thunk. These |
| | 132 | // mini-mut-lists are moved onto the respective gen->mut_list at |
| | 133 | // each GC. |
| | 134 | bdescr **mut_lists; |
| | 135 | |
| | 136 | #if defined(THREADED_RTS) |
| | 137 | // Worker Tasks waiting in the wings. Singly-linked. |
| | 138 | Task *spare_workers; |
| | 139 | |
| | 140 | // This lock protects running_task, returning_tasks_{hd,tl}, wakeup_queue. |
| | 141 | Mutex lock; |
| | 142 | |
| | 143 | // Tasks waiting to return from a foreign call, or waiting to make |
| | 144 | // a new call-in using this Capability (NULL if empty). |
| | 145 | // NB. this field needs to be modified by tasks other than the |
| | 146 | // running_task, so it requires cap->lock to modify. A task can |
| | 147 | // check whether it is NULL without taking the lock, however. |
| | 148 | Task *returning_tasks_hd; // Singly-linked, with head/tail |
| | 149 | Task *returning_tasks_tl; |
| | 150 | |
| | 151 | // A list of threads to append to this Capability's run queue at |
| | 152 | // the earliest opportunity. These are threads that have been |
| | 153 | // woken up by another Capability. |
| | 154 | StgTSO *wakeup_queue_hd; |
| | 155 | StgTSO *wakeup_queue_tl; |
| | 156 | #endif |
| | 157 | |
| | 158 | // Per-capability STM-related data |
| | 159 | StgTVarWaitQueue *free_tvar_wait_queues; |
| | 160 | StgTRecChunk *free_trec_chunks; |
| | 161 | StgTRecHeader *free_trec_headers; |
| | 162 | nat transaction_tokens; |
| | 163 | }; // typedef Capability, defined in RtsAPI.h |
| | 164 | }}} |
| | 165 | |