comparison VMS.c @ 70:f9b60012fd74

working ucontext version
author Merten Sach <msach@mailbox.tu-berlin.de>
date Fri, 27 May 2011 12:35:40 +0200
parents 11bfe9d136ed
children efb55f1b5fb9
comparison
equal deleted inserted replaced
36:053256974df1 37:2ff095bb79c5
259 //NOTE: do not clean up VMS env here -- semantic layer has to have 259 //NOTE: do not clean up VMS env here -- semantic layer has to have
260 // a chance to clean up its environment first, then do a call to free 260 // a chance to clean up its environment first, then do a call to free
261 // the Master env and rest of VMS locations 261 // the Master env and rest of VMS locations
262 } 262 }
263 263
264 #ifdef SEQUENTIAL
264 /*Only difference between version with an OS thread pinned to each core and 265 /*Only difference between version with an OS thread pinned to each core and
265 * the sequential version of VMS is VMS__init_Seq, this, and coreLoop_Seq. 266 * the sequential version of VMS is VMS__init_Seq, this, and coreLoop_Seq.
266 */ 267 */
267 void 268 void
268 VMS__start_the_work_then_wait_until_done_Seq() 269 VMS__start_the_work_then_wait_until_done_Seq()
270 //Instead of un-suspending threads, just call the one and only 271 //Instead of un-suspending threads, just call the one and only
271 // core loop (sequential version), in the main thread. 272 // core loop (sequential version), in the main thread.
272 coreLoop_Seq( NULL ); 273 coreLoop_Seq( NULL );
273 274
274 } 275 }
276 #endif
275 277
276 278
277 279
278 /*Create stack, then create __cdecl structure on it and put initialData and 280 /*Create stack, then create __cdecl structure on it and put initialData and
279 * pointer to the new structure instance into the parameter positions on 281 * pointer to the new structure instance into the parameter positions on
285 * animator state to return to -- 287 * animator state to return to --
286 * 288 *
287 */ 289 */
288 inline VirtProcr * 290 inline VirtProcr *
289 create_procr_helper( VirtProcr *newPr, VirtProcrFnPtr fnPtr, 291 create_procr_helper( VirtProcr *newPr, VirtProcrFnPtr fnPtr,
290 void *initialData, char *stackLocs ) 292 void *initialData, char *stackLocs,
291 { 293 ucontext_t *contextBuf)
292 char *stackPtr; 294 {
293 295 char *stackPtr = ( (char *)stackLocs + VIRT_PROCR_STACK_SIZE - 0x4);
296
297 getcontext(contextBuf);
298 contextBuf->uc_stack.ss_sp=stackLocs;
299 contextBuf->uc_stack.ss_size=VIRT_PROCR_STACK_SIZE;
300 contextBuf->uc_stack.ss_flags=0;
301 makecontext(contextBuf, fnPtr, 2, initialData, newPr);
302 contextBuf->uc_link=NULL;
303
304 newPr->procrID = _VMSMasterEnv->numProcrsCreated++;
305 newPr->savedVPStatus = contextBuf;
306 newPr->initialData = initialData;
294 newPr->startOfStack = stackLocs; 307 newPr->startOfStack = stackLocs;
295 newPr->procrID = _VMSMasterEnv->numProcrsCreated++;
296 newPr->nextInstrPt = fnPtr;
297 newPr->initialData = initialData;
298 newPr->requests = NULL; 308 newPr->requests = NULL;
299 newPr->schedSlot = NULL; 309 newPr->schedSlot = NULL;
300
301 //fnPtr takes two params -- void *initData & void *animProcr
302 //alloc stack locations, make stackPtr be the highest addr minus room
303 // for 2 params + return addr. Return addr (NULL) is in loc pointed to
304 // by stackPtr, initData at stackPtr + 4 bytes, animatingPr just above
305 stackPtr = ( (char *)stackLocs + VIRT_PROCR_STACK_SIZE - 0x10 );
306 310
307 //setup __cdecl on stack -- coreloop will switch to stackPtr before jmp 311 //setup __cdecl on stack -- coreloop will switch to stackPtr before jmp
308 *( (int *)stackPtr + 2 ) = (int) newPr; //rightmost param -- 32bit pointer 312 //*( (int *)stackPtr + 2 ) = (int) newPr; //rightmost param -- 32bit pointer
309 *( (int *)stackPtr + 1 ) = (int) initialData; //next param to left 313 //*( (int *)stackPtr + 1 ) = (int) initialData; //next param to left
310 newPr->stackPtr = stackPtr; //core loop will switch to this, then 314 //newPr->stackPtr = stackPtr; //core loop will switch to this, then
311 newPr->framePtr = stackPtr; //suspend loop will save new stack & frame ptr 315 //newPr->framePtr = stackPtr; //suspend loop will save new stack & frame ptr
312 316
313 //============================= MEASUREMENT STUFF ======================== 317 //============================= MEASUREMENT STUFF ========================
314 #ifdef STATS__TURN_ON_PROBES 318 #ifdef STATS__TURN_ON_PROBES
315 struct timeval timeStamp; 319 struct timeval timeStamp;
316 gettimeofday( &(timeStamp), NULL); 320 gettimeofday( &(timeStamp), NULL);
324 328
325 inline VirtProcr * 329 inline VirtProcr *
326 VMS__create_procr( VirtProcrFnPtr fnPtr, void *initialData ) 330 VMS__create_procr( VirtProcrFnPtr fnPtr, void *initialData )
327 { VirtProcr *newPr; 331 { VirtProcr *newPr;
328 char *stackLocs; 332 char *stackLocs;
333 ucontext_t *contextBuffer;
329 334
330 newPr = VMS__malloc( sizeof(VirtProcr) ); 335 newPr = VMS__malloc( sizeof(VirtProcr) );
331 stackLocs = VMS__malloc( VIRT_PROCR_STACK_SIZE ); 336 stackLocs = VMS__malloc( VIRT_PROCR_STACK_SIZE );
337 contextBuffer = VMS__malloc(sizeof(ucontext_t));
338
332 if( stackLocs == 0 ) 339 if( stackLocs == 0 )
333 { perror("VMS__malloc stack"); exit(1); } 340 { perror("VMS__malloc stack"); exit(1); }
334 341
335 return create_procr_helper( newPr, fnPtr, initialData, stackLocs ); 342 return create_procr_helper( newPr, fnPtr, initialData, stackLocs, contextBuffer );
336 } 343 }
337 344
338 /* "ext" designates that it's for use outside the VMS system -- should only 345 /* "ext" designates that it's for use outside the VMS system -- should only
339 * be called from main thread or other thread -- never from code animated by 346 * be called from main thread or other thread -- never from code animated by
340 * a VMS virtual processor. 347 * a VMS virtual processor.
341 */ 348 */
342 inline VirtProcr * 349 inline VirtProcr *
343 VMS_ext__create_procr( VirtProcrFnPtr fnPtr, void *initialData ) 350 VMS_ext__create_procr( VirtProcrFnPtr fnPtr, void *initialData )
344 { VirtProcr *newPr; 351 { VirtProcr *newPr;
345 char *stackLocs; 352 char *stackLocs;
353 ucontext_t *contextBuffer;
346 354
347 newPr = malloc( sizeof(VirtProcr) ); 355 newPr = malloc( sizeof(VirtProcr) );
348 stackLocs = malloc( VIRT_PROCR_STACK_SIZE ); 356 stackLocs = malloc( VIRT_PROCR_STACK_SIZE );
357 contextBuffer = VMS__malloc(sizeof(ucontext_t));
358
349 if( stackLocs == 0 ) 359 if( stackLocs == 0 )
350 { perror("malloc stack"); exit(1); } 360 { perror("malloc stack"); exit(1); }
351 361
352 return create_procr_helper( newPr, fnPtr, initialData, stackLocs ); 362 return create_procr_helper( newPr, fnPtr, initialData, stackLocs, contextBuffer );
353 } 363 }
354 364
355 365
356 /*Anticipating multi-tasking 366 /*Anticipating multi-tasking
357 */ 367 */
371 * next work-unit for that procr. 381 * next work-unit for that procr.
372 */ 382 */
373 void 383 void
374 VMS__suspend_procr( VirtProcr *animatingPr ) 384 VMS__suspend_procr( VirtProcr *animatingPr )
375 { 385 {
376 386 //return ownership of the virt procr and sched slot to Master virt pr
377 //The request to master will cause this suspended virt procr to get
378 // scheduled again at some future point -- to resume, core loop jumps
379 // to the resume point (below), which causes restore of saved regs and
380 // "return" from this call.
381 animatingPr->nextInstrPt = &&ResumePt;
382
383 //return ownership of the virt procr and sched slot to Master virt pr
384 animatingPr->schedSlot->workIsDone = TRUE; 387 animatingPr->schedSlot->workIsDone = TRUE;
385 388
386 //=========================== Measurement stuff ======================== 389 //=========================== Measurement stuff ========================
387 #ifdef MEAS__TIME_STAMP_SUSP 390 #ifdef MEAS__TIME_STAMP_SUSP
388 //record time stamp: compare to time-stamp recorded below 391 //record time stamp: compare to time-stamp recorded below
389 saveLowTimeStampCountInto( animatingPr->preSuspTSCLow ); 392 saveLowTimeStampCountInto( animatingPr->preSuspTSCLow );
390 #endif 393 #endif
391 //======================================================================= 394 //=======================================================================
392 395
393 /* VirtProcr offsets: 396 swapcontext(animatingPr->savedVPStatus,animatingPr->savedCoreLoopStatus);
394 * 0xc stackPtr
395 * 0x10 framePtr
396 * 0x14 nextInstrPt
397 * 0x1c coreLoopFramePtr
398 * 0x20 coreLoopStackPtr
399 *
400 * _VMSMasterEnv offsets:
401 * 0x24 coreLoopStartPt
402 * 0x28 coreLoopEndPt
403 * 0x30 masterLock
404 */
405 // SwitchToCoreLoop( animatingPr )
406 asm volatile("movl %0, %%ebx; \
407 movl %1, %%ecx; \
408 movl %%esp, 0x0c(%%ecx); \
409 movl %%ebp, 0x10(%%ecx); \
410 movl 0x24(%%ebx), %%eax; \
411 movl 0x20(%%ecx), %%esp; \
412 movl 0x1c(%%ecx), %%ebp; \
413 jmp %%eax" \
414 /* outputs */ : \
415 /* inputs */ : "g"(_VMSMasterEnv), "g"(animatingPr) \
416 /* clobber */ : "memory", "%eax", "%ebx", "%ecx", "%edx", "%edi", "%esi" \
417 );
418
419 // asm volatile("mov %0,%%ebx; \
420 mov %%ebx, %%eax; \
421 add $0xc, %%eax; \
422 movl %%esp, (%%eax); \
423 mov %%ebx, %%eax; \
424 add $0x10, %%eax; \
425 movl %%ebp, (%%eax); \
426 movl %1, %%eax; \
427 movl %2, %%esp; \
428 movl %3, %%ebp; \
429 jmp %%eax" \
430 /* outputs */ : \
431 /* inputs */ : "g"(animatingPr), "g" (jmpPt), "g" (coreLoopStackPtr), \
432 "g" (coreLoopFramePtr) \
433 /* clobber */ : "memory", "%eax", "%ebx", "%ecx", "%edx", "%edi", "%esi" \
434 );
435 397
436 //======================================================================= 398 //=======================================================================
437 ResumePt:
438 #ifdef MEAS__TIME_STAMP_SUSP 399 #ifdef MEAS__TIME_STAMP_SUSP
439 //NOTE: only take low part of count -- do sanity check when take diff 400 //NOTE: only take low part of count -- do sanity check when take diff
440 saveLowTimeStampCountInto( animatingPr->postSuspTSCLow ); 401 saveLowTimeStampCountInto( animatingPr->postSuspTSCLow );
441 #endif 402 #endif
442
443 return; 403 return;
444 } 404 }
445 405
446 406
447 407
737 * processors). 697 * processors).
738 */ 698 */
739 void 699 void
740 endOSThreadFn( void *initData, VirtProcr *animatingPr ) 700 endOSThreadFn( void *initData, VirtProcr *animatingPr )
741 { void *jmpPt, *coreLoopStackPtr, *coreLoopFramePtr; 701 { void *jmpPt, *coreLoopStackPtr, *coreLoopFramePtr;
742 702 ucontext_t* contextBuf = animatingPr->savedCoreLoopStatus;
743 jmpPt = _VMSMasterEnv->coreLoopEndPt; 703 void *stackPtr = contextBuf->uc_mcontext.gregs[REG_ESP];
744 coreLoopStackPtr = animatingPr->coreLoopStackPtr; 704
745 coreLoopFramePtr = animatingPr->coreLoopFramePtr; 705 getcontext(contextBuf);
746 706 contextBuf->uc_stack.ss_sp=stackPtr;
747 707 makecontext(contextBuf,&terminateCoreLoop,1,animatingPr);
748 asm volatile("movl %0, %%eax; \ 708 contextBuf->uc_link=NULL;
749 movl %1, %%esp; \ 709 swapcontext(animatingPr->savedVPStatus,contextBuf);
750 movl %2, %%ebp; \ 710 }
751 jmp %%eax " \
752 /* outputs */ : \
753 /* inputs */ : "m" (jmpPt), "m"(coreLoopStackPtr), "m"(coreLoopFramePtr)\
754 /* clobber */ : "memory", "%eax", "%ebx", "%ecx", "%edx", "%edi","%esi" \
755 );
756 }
757 711
758 712
759 /*This is called from the startup & shutdown 713 /*This is called from the startup & shutdown
760 */ 714 */
761 void 715 void