VMS/VMS_Implementations/Vthread_impls/Vthread_MC_shared_impl

view Vthread__startup_and_shutdown.c @ 29:b94dc57e4455

refactored many files -- chgd names, moved code around -- doesn't compile
author Some Random Person <seanhalle@yahoo.com>
date Wed, 09 May 2012 13:24:19 -0700
parents
children
line source
1 /*
2 * Copyright 2010 OpenSourceCodeStewardshipFoundation
3 *
4 * Licensed under BSD
5 */
7 #include <stdio.h>
8 #include <stdlib.h>
10 #include "VMS_impl/VMS.h"
11 #include "Vthread.h"
12 #include "C_Libraries/Queue_impl/PrivateQueue.h"
13 #include "C_Libraries/Hash_impl/PrivateHash.h"
17 //===========================================================================
19 //TODO: update these comments!
20 /*These are the library functions *called in the application*
21 *
22 *There's a pattern for the outside sequential code to interact with the
23 * VMS_HW code.
24 *The VMS_HW system is inside a boundary.. every Vthread system is in its
25 * own directory that contains the functions for each of the processor types.
26 * One of the processor types is the "seed" processor that starts the
27 * cascade of creating all the processors that do the work.
28 *So, in the directory is a file called "EntryPoint.c" that contains the
29 * function, named appropriately to the work performed, that the outside
30 * sequential code calls. This function follows a pattern:
31 *1) it calls Vthread__init()
32 *2) it creates the initial data for the seed processor, which is passed
33 * in to the function
34 *3) it creates the seed Vthread processor, with the data to start it with.
35 *4) it calls startVthreadThenWaitUntilWorkDone
36 *5) it gets the returnValue from the transfer struc and returns that
37 * from the function
38 *
39 *For now, a new Vthread system has to be created via Vthread__init every
40 * time an entry point function is called -- later, might add letting the
41 * Vthread system be created once, and let all the entry points just reuse
42 * it -- want to be as simple as possible now, and see by using what makes
43 * sense for later..
44 */
48 //===========================================================================
50 /*This is the "border crossing" function -- the thing that crosses from the
51 * outside world, into the VMS_HW world. It initializes and starts up the
52 * VMS system, then creates one processor from the specified function and
53 * puts it into the readyQ. From that point, that one function is resp.
54 * for creating all the other processors, that then create others, and so
55 * forth.
56 *When all the processors, including the seed, have dissipated, then this
57 * function returns. The results will have been written by side-effect via
58 * pointers read from, or written into initData.
59 *
60 *NOTE: no Threads should exist in the outside program that might touch
61 * any of the data reachable from initData passed in to here
62 */
63 void
64 Vthread__create_seed_slaveVP_and_do_work( TopLevelFnPtr fnPtr, void *initData )
65 { VthdSemEnv *semEnv;
66 SlaveVP *seedSlv;
68 #ifdef DEBUG__TURN_ON_SEQUENTIAL_MODE
69 Vthread__init_Seq(); //debug sequential exe
70 #else
71 Vthread__init(); //normal multi-thd
72 #endif
73 semEnv = _VMSMasterEnv->semanticEnv;
75 //Vthread starts with one processor, which is put into initial environ,
76 // and which then calls create() to create more, thereby expanding work
77 seedSlv = Vthread__create_slaveVP_helper( fnPtr, initData, semEnv, -1 );
79 resume_slaveVP( seedSlv, semEnv );
81 #ifdef DEBUG__TURN_ON_SEQUENTIAL_MODE
82 VMS_SS__start_the_work_then_wait_until_done_Seq(); //debug sequential exe
83 #else
84 VMS_SS__start_the_work_then_wait_until_done(); //normal multi-thd
85 #endif
87 Vthread__cleanup_after_shutdown();
88 }
91 //===========================================================================
92 //
93 /*Initializes all the data-structures for a Vthread system -- but doesn't
94 * start it running yet!
95 *
96 *
97 *This sets up the semantic layer over the VMS system
98 *
99 *First, calls VMS_Setup, then creates own environment, making it ready
100 * for creating the seed processor and then starting the work.
101 */
102 void
103 Vthread__init()
104 {
105 MEAS__Make_Meas_Hists_for_Language;
107 VMS_SS__init();
108 //masterEnv, a global var, now is partially set up by init_VMS
110 Vthread__init_Helper();
111 }
113 #ifdef DEBUG__TURN_ON_SEQUENTIAL_MODE
114 void
115 Vthread__init_Seq()
116 {
117 VMS_SS__init_Seq();
118 flushRegisters();
119 //masterEnv, a global var, now is partially set up by init_VMS
121 Vthread__init_Helper();
122 }
123 #endif
125 void
126 Vthread__init_Helper()
127 { VthdSemEnv *semanticEnv;
128 PrivQueueStruc **readySlvQs;
129 int coreIdx, i;
131 //Hook up the semantic layer's plug-ins to the Master virt procr
132 _VMSMasterEnv->requestHandler = &Vthread__Request_Handler;
133 _VMSMasterEnv->slaveAssigner = &Vthread__schedule_slaveVP;
135 //create the semantic layer's environment (all its data) and add to
136 // the master environment
137 semanticEnv = VMS_WL__malloc( sizeof( VthdSemEnv ) );
138 _VMSMasterEnv->semanticEnv = semanticEnv;
140 //create the ready queue
141 readySlvQs = VMS_WL__malloc( NUM_CORES * sizeof(PrivQueueStruc *) );
143 for( coreIdx = 0; coreIdx < NUM_CORES; coreIdx++ )
144 {
145 readySlvQs[ coreIdx ] = makeVMSQ();
146 }
148 semanticEnv->readySlvQs = readySlvQs;
150 semanticEnv->nextCoreToGetNewSlv = 0;
152 semanticEnv->mutexDynArrayInfo =
153 makePrivDynArrayOfSize( (void*)&(semanticEnv->mutexDynArray), INIT_NUM_MUTEX );
155 semanticEnv->condDynArrayInfo =
156 makePrivDynArrayOfSize( (void*)&(semanticEnv->condDynArray), INIT_NUM_COND );
158 //TODO: bug -- turn these arrays into dyn arrays to eliminate limit
159 //semanticEnv->singletonHasBeenExecutedFlags = makeDynArrayInfo( );
160 //semanticEnv->transactionStrucs = makeDynArrayInfo( );
161 for( i = 0; i < NUM_STRUCS_IN_SEM_ENV; i++ )
162 {
163 semanticEnv->fnSingletons[i].savedRetAddr = NULL;
164 semanticEnv->fnSingletons[i].hasBeenStarted = FALSE;
165 semanticEnv->fnSingletons[i].hasFinished = FALSE;
166 semanticEnv->fnSingletons[i].waitQ = makeVMSQ();
167 semanticEnv->transactionStrucs[i].waitingSlvQ = makeVMSQ();
168 }
169 }
172 /*Frees any memory allocated by Vthread__init() then calls VMS__shutdown
173 */
174 void
175 Vthread__cleanup_after_shutdown()
176 { /*VthdSemEnv *semEnv;
177 int32 coreIdx, idx, highestIdx;
178 VthdMutex **mutexArray, *mutex;
179 VthdCond **condArray, *cond; */
181 /* It's all allocated inside VMS's big chunk -- that's about to be freed, so
182 * nothing to do here
183 semEnv = _VMSMasterEnv->semanticEnv;
185 //TODO: double check that all sem env locations freed
187 for( coreIdx = 0; coreIdx < NUM_CORES; coreIdx++ )
188 {
189 free( semEnv->readySlvQs[coreIdx]->startOfData );
190 free( semEnv->readySlvQs[coreIdx] );
191 }
193 free( semEnv->readySlvQs );
196 //==== Free mutexes and mutex array ====
197 mutexArray = semEnv->mutexDynArray->array;
198 highestIdx = semEnv->mutexDynArray->highestIdxInArray;
199 for( idx=0; idx < highestIdx; idx++ )
200 { mutex = mutexArray[ idx ];
201 if( mutex == NULL ) continue;
202 free( mutex );
203 }
204 free( mutexArray );
205 free( semEnv->mutexDynArray );
206 //======================================
209 //==== Free conds and cond array ====
210 condArray = semEnv->condDynArray->array;
211 highestIdx = semEnv->condDynArray->highestIdxInArray;
212 for( idx=0; idx < highestIdx; idx++ )
213 { cond = condArray[ idx ];
214 if( cond == NULL ) continue;
215 free( cond );
216 }
217 free( condArray );
218 free( semEnv->condDynArray );
219 //===================================
222 free( _VMSMasterEnv->semanticEnv );
223 */
224 VMS_SS__cleanup_at_end_of_shutdown();
225 }
228 //===========================================================================