diff VMS.c @ 29:0e008278fe3c

Works Sequentially -- took out all threads and debugged -- works
author Me
date Wed, 28 Jul 2010 13:12:10 -0700
parents 8b9e4c333fe6
children c8823e0bb2b4
line diff
     1.1 --- a/VMS.c	Mon Jul 26 16:42:59 2010 -0700
     1.2 +++ b/VMS.c	Wed Jul 28 13:12:10 2010 -0700
     1.3 @@ -389,8 +389,9 @@
     1.4   { VMSReqst *req;
     1.5  
     1.6     req = procrWithReq->requests;
     1.7 +   if( req == NULL ) return;
     1.8     procrWithReq->requests = procrWithReq->requests->nextReqst;
     1.9 -   free( req );
    1.10 +   VMS__free_request( req );
    1.11   }
    1.12  
    1.13  
    1.14 @@ -455,34 +456,6 @@
    1.15   }
    1.16  
    1.17  
    1.18 -/*The semantic layer figures out when the work is done ( perhaps by a call
    1.19 - * in the application to "work all done", or perhaps all the virtual
    1.20 - * processors have dissipated.. a.s.o. )
    1.21 - *
    1.22 - *The semantic layer is responsible for making sure all work has fully
    1.23 - * completed before using this to shutdown the VMS system.
    1.24 - *
    1.25 - *After the semantic layer has determined it wants to shut down, the
    1.26 - * next time the Master Loop calls the scheduler plug-in, the scheduler
    1.27 - * then calls this function and returns the virtual processor it gets back.
    1.28 - *
    1.29 - *When the shut-down processor runs, it first frees all locations malloc'd to
    1.30 - * the VMS system (that wasn't
    1.31 - * specified as return-locations).  Then it creates one core-loop shut-down
    1.32 - * processor for each core loop and puts them all into the workQ.  When a
    1.33 - * core loop animates a core loop shut-down processor, it causes exit-thread
    1.34 - * to run, and when all core loop threads have exited, then the "wait for
    1.35 - * work to finish" in the main thread is woken, and the function-call that
    1.36 - * started all the work returns.
    1.37 - *
    1.38 - *The function animated by this processor performs the shut-down work.
    1.39 - */
    1.40 -VirtProcr *
    1.41 -VMS__create_the_shutdown_procr()
    1.42 - {
    1.43 -   return VMS__create_procr( &shutdownFn, NULL );
    1.44 - }
    1.45 -
    1.46  
    1.47  /*This must be called by the request handler plugin -- it cannot be called
    1.48   * from the semantic library "dissipate processor" function -- instead, the
    1.49 @@ -502,15 +475,14 @@
    1.50   * of dis-owning it.
    1.51   */
    1.52  void
    1.53 -VMS__free_procr_locs( VirtProcr *animatingPr )
    1.54 +VMS__handle_dissipate_reqst( VirtProcr *animatingPr )
    1.55   {
    1.56        //dis-own all locations owned by this processor, causing to be freed
    1.57        // any locations that it is (was) sole owner of
    1.58 -   //TODO: implement VMS__malloc system, including "give up ownership"
    1.59 +//TODO: implement VMS__malloc system, including "give up ownership"
    1.60  
    1.61        //The dissipate request might still be attached, so remove and free it
    1.62     VMS__remove_and_free_top_request( animatingPr );
    1.63 -   free( animatingPr->startOfStack );
    1.64  
    1.65        //NOTE: initialData was given to the processor, so should either have
    1.66        // been alloc'd with VMS__malloc, or freed by the level above animPr.
    1.67 @@ -521,54 +493,98 @@
    1.68   }
    1.69  
    1.70  
    1.71 +//TODO: re-architect so that have clean separation between request handler
    1.72 +// and master loop, for dissipate, create, shutdown, and other non-semantic
    1.73 +// requests.  Issue is chain: one removes requests from AppVP, one dispatches
    1.74 +// on type of request, and one handles each type..  but some types require
    1.75 +// action from both request handler and master loop -- maybe just give the
    1.76 +// request handler calls like:  VMS__handle_X_request_type
    1.77  
    1.78 -/*This is the function run by the special "shut-down" processor
    1.79 +void
    1.80 +endOSThreadFn( void *initData, VirtProcr *animatingPr );
    1.81 +
    1.82 +/*This is called by the semantic layer's request handler when it decides its
    1.83 + * time to shut down the VMS system.  Calling this causes the core loop OS
    1.84 + * threads to exit, which unblocks the entry-point function that started up
    1.85 + * VMS, and allows it to grab the result and return to the original single-
    1.86 + * threaded application.
    1.87   * 
    1.88 - *The _VMSMasterEnv is needed by this shut down function, so the "wait"
    1.89 - * function run in the main loop has to free it, and the thread-related
    1.90 - * locations (coreLoopThdParams a.s.o.).
    1.91 - *However, the semantic environment and all data malloc'd to VMS can be
    1.92 - * freed here.
    1.93 + *The _VMSMasterEnv is needed by this shut down function, so the create-seed-
    1.94 + * and-wait function has to free a bunch of stuff after it detects the
    1.95 + * threads have all died: the masterEnv, the thread-related locations,
    1.96 + * masterVP any AppVPs that might still be allocated and sitting in the
    1.97 + * semantic environment, or have been orphaned in the _VMSWorkQ.
    1.98 + * 
    1.99 + *NOTE: the semantic plug-in is expected to use VMS__malloc_to to get all the
   1.100 + * locations it needs, and give ownership to masterVP.  Then, they will be
   1.101 + * automatically freed when the masterVP is dissipated.  (This happens after
   1.102 + * the core loop threads have all exited)
   1.103   *
   1.104 - *NOTE: the semantic plug-in is expected to use VMS__malloc to get all the
   1.105 - * locations it needs -- they will be automatically freed by the standard
   1.106 - * "free all owned locations"
   1.107 - *
   1.108 - *Free any locations malloc'd to the VMS system (that weren't
   1.109 - * specified as return-locations).
   1.110 - *Then create one core-loop shut-down processor for each core loop and puts
   1.111 - * them all into the workQ.
   1.112 + *In here,create one core-loop shut-down processor for each core loop and put
   1.113 + * them all directly into the workQ.
   1.114 + *Note, this function can ONLY be called after the semantic environment no
   1.115 + * longer cares if AppVPs get animated after the point this is called.  In
   1.116 + * other words, this can be used as an abort, or else it should only be
   1.117 + * called when all AppVPs have finished dissipate requests -- only at that
   1.118 + * point is it sure that all results have completed.
   1.119   */
   1.120  void
   1.121 -shutdownFn( void *dummy, VirtProcr *animatingPr )
   1.122 +VMS__handle_shutdown_reqst( void *dummy, VirtProcr *animatingPr )
   1.123   { int coreIdx;
   1.124     VirtProcr *shutDownPr;
   1.125     VMSQueueStruc *workQ = _VMSWorkQ;
   1.126  
   1.127 -      //free all the locations owned within the VMS system
   1.128 -   //TODO: write VMS__malloc and free.. -- take the DKU malloc as starting pt
   1.129 -
   1.130 -      //make the core loop shut-down processors and put them into the workQ
   1.131 +      //create the shutdown processors, one for each core loop -- put them
   1.132 +      // directly into _VMSWorkQ -- each core will die when gets one, so
   1.133 +      // the system distributes them evenly itself.
   1.134     for( coreIdx=0; coreIdx < NUM_CORES; coreIdx++ )
   1.135      {
   1.136 -      shutDownPr = VMS__create_procr( NULL, NULL );
   1.137 -      shutDownPr->nextInstrPt = _VMSMasterEnv->coreLoopShutDownPt;
   1.138 +      shutDownPr = VMS__create_procr( &endOSThreadFn, NULL );
   1.139        writeVMSQ( shutDownPr, workQ );
   1.140      }
   1.141  
   1.142 -      //This is an issue: the animating processor of this function may not
   1.143 -      // get its request handled before all the cores have shutdown.
   1.144 -      //TODO: after all the threads stop, clean out the MasterEnv, the
   1.145 -      // SemanticEnv, and the workQ before returning.
   1.146 -   VMS__dissipate_procr( animatingPr );  //will never come back from this
   1.147   }
   1.148  
   1.149  
   1.150 -/*This has to free anything allocated during VMS_init, and any other alloc'd
   1.151 +/*Am trying to be cute, avoiding IF statement in coreLoop that checks for
   1.152 + * a special shutdown procr.  Ended up with extra-complex shutdown sequence.
   1.153 + *This function has the sole purpose of setting the stack and framePtr
   1.154 + * to the coreLoop's stack and framePtr.. it does that then jumps to the
   1.155 + * core loop's shutdown point -- might be able to just call Pthread_exit
   1.156 + * from here, but going back to the pthread's stack and setting everything
   1.157 + * up just as if it never jumped out, before calling pthread_exit.
   1.158 + *The end-point of core loop will free the stack and so forth of the
   1.159 + * processor that animates this function, (this fn is transfering the
   1.160 + * animator of the AppVP that is in turn animating this function over
   1.161 + * to core loop function -- note that this slices out a level of virtual
   1.162 + * processors).
   1.163 + */
   1.164 +void
   1.165 +endOSThreadFn( void *initData, VirtProcr *animatingPr )
   1.166 + { void *jmpPt, *coreLoopStackPtr, *coreLoopFramePtr;
   1.167 +
   1.168 +   jmpPt             = _VMSMasterEnv->coreLoopEndPt;
   1.169 +   coreLoopStackPtr  = animatingPr->coreLoopStackPtr;
   1.170 +   coreLoopFramePtr  = animatingPr->coreLoopFramePtr;
   1.171 +
   1.172 +
   1.173 +   asm volatile("movl %0, %%eax;      \
   1.174 +                 movl %1, %%esp;      \
   1.175 +                 movl %2, %%ebp;      \
   1.176 +                 jmp  %%eax    "      \
   1.177 +   /* outputs */ :                    \
   1.178 +   /* inputs  */ : "m" (jmpPt), "m"(coreLoopStackPtr), "m"(coreLoopFramePtr)\
   1.179 +   /* clobber */ : "memory", "%eax", "%ebx", "%ecx", "%edx", "%edi","%esi"  \
   1.180 +                );
   1.181 + }
   1.182 +
   1.183 +
   1.184 +
   1.185 +/*This is called has to free anything allocated during VMS_init, and any other alloc'd
   1.186   * locations that might be left over.
   1.187   */
   1.188  void
   1.189 -VMS__shutdown()
   1.190 +VMS__cleanup_after_shutdown()
   1.191   { int i;
   1.192   
   1.193     free( _VMSWorkQ );
   1.194 @@ -579,7 +595,7 @@
   1.195      }
   1.196  
   1.197     free( _VMSMasterEnv->schedSlots);
   1.198 -   VMS__free_procr_locs( _VMSMasterEnv->masterVirtPr );
   1.199 +   VMS__handle_dissipate_reqst( _VMSMasterEnv->masterVirtPr );
   1.200     
   1.201     free( _VMSMasterEnv );
   1.202   }