Mercurial > cgi-bin > hgwebdir.cgi > VMS > VMS_Implementations > VMS_impls > VMS__MC_shared_impl
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 |
