Changeset 398
- Timestamp:
- 02/17/07 01:57:53 (16 years ago)
- Files:
-
- branches/streaming-rework/src/libstreaming/AmdtpStreamProcessor.cpp (modified) (4 diffs)
- branches/streaming-rework/src/libstreaming/IsoHandler.cpp (modified) (10 diffs)
- branches/streaming-rework/src/libstreaming/IsoHandler.h (modified) (7 diffs)
- branches/streaming-rework/src/libstreaming/IsoHandlerManager.cpp (modified) (1 diff)
- branches/streaming-rework/src/libstreaming/IsoHandlerManager.h (modified) (1 diff)
- branches/streaming-rework/src/libstreaming/StreamProcessorManager.cpp (modified) (11 diffs)
- branches/streaming-rework/src/libstreaming/StreamProcessorManager.h (modified) (3 diffs)
- branches/streaming-rework/tests/test-sytmonitor.cpp (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
branches/streaming-rework/src/libstreaming/AmdtpStreamProcessor.cpp
r397 r398 368 368 int64_t until_next=substractTicks(time_at_period,cycle_timer); 369 369 370 debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "=> TAP=%11llu, CTR=%11llu, UTN=%11lld , TPUS=%f\n",371 time_at_period, cycle_timer, until_next , m_handler->getTicksPerUsec()370 debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "=> TAP=%11llu, CTR=%11llu, UTN=%11lld\n", 371 time_at_period, cycle_timer, until_next 372 372 ); 373 373 … … 376 376 // for absolute times, not the relative time we are 377 377 // using here (which can also be negative). 378 return (int64_t)(((float)until_next) / m_handler->getTicksPerUsec());378 return (int64_t)(((float)until_next) / TICKS_PER_USEC); 379 379 } 380 380 381 381 uint64_t AmdtpTransmitStreamProcessor::getTimeAtPeriodUsecs() { 382 382 // then we should convert this into usecs 383 // FIXME: we assume that the TimeSource of the IsoHandler is 384 // in usecs. 385 return m_handler->mapToTimeSource(getTimeAtPeriod()); 383 return (uint64_t)((float)getTimeAtPeriod() * TICKS_PER_USEC); 386 384 } 387 385 … … 1098 1096 int64_t until_next=substractTicks(time_at_period,cycle_timer); 1099 1097 1100 debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "=> TAP=%11llu, CTR=%11llu, UTN=%11lld , TPUS=%f\n",1101 time_at_period, cycle_timer, until_next , m_handler->getTicksPerUsec()1098 debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "=> TAP=%11llu, CTR=%11llu, UTN=%11lld\n", 1099 time_at_period, cycle_timer, until_next 1102 1100 ); 1103 1101 … … 1106 1104 // for absolute times, not the relative time we are 1107 1105 // using here (which can also be negative). 1108 return (int64_t)(((float)until_next) / m_handler->getTicksPerUsec());1106 return (int64_t)(((float)until_next) / TICKS_PER_USEC); 1109 1107 } 1110 1108 1111 1109 uint64_t AmdtpReceiveStreamProcessor::getTimeAtPeriodUsecs() { 1112 1110 // then we should convert this into usecs 1113 // FIXME: we assume that the TimeSource of the IsoHandler is 1114 // in usecs. 1115 return m_handler->mapToTimeSource(getTimeAtPeriod()); 1111 return (uint64_t)((float)getTimeAtPeriod()*TICKS_PER_USEC); 1116 1112 } 1117 1113 branches/streaming-rework/src/libstreaming/IsoHandler.cpp
r397 r398 93 93 /* Base class implementation */ 94 94 IsoHandler::IsoHandler(int port) 95 : TimeSource(),m_handle(0), m_handle_util(0), m_port(port),95 : m_handle(0), m_handle_util(0), m_port(port), 96 96 m_buf_packets(400), m_max_packet_size(1024), m_irq_interval(-1), 97 m_cycletimer_ticks(0), m_lastmeas_usecs(0), m_ticks_per_usec(24.576),98 m_ticks_per_usec_dll_err2(0),99 97 m_packetcount(0), m_dropped(0), m_Client(0), 100 m_State(E_Created), m_TimeSource_LastSecs(0),m_TimeSource_NbCycleWraps(0) 101 { 102 m_TimeSource=new FreebobUtil::SystemTimeSource(); 98 m_State(E_Created) 99 { 103 100 } 104 101 105 102 IsoHandler::IsoHandler(int port, unsigned int buf_packets, unsigned int max_packet_size, int irq) 106 : TimeSource(),m_handle(0), m_port(port),103 : m_handle(0), m_port(port), 107 104 m_buf_packets(buf_packets), m_max_packet_size( max_packet_size), 108 105 m_irq_interval(irq), 109 m_cycletimer_ticks(0), m_lastmeas_usecs(0), m_ticks_per_usec(24.576),110 m_ticks_per_usec_dll_err2(0),111 106 m_packetcount(0), m_dropped(0), m_Client(0), 112 m_State(E_Created), m_TimeSource_LastSecs(0),m_TimeSource_NbCycleWraps(0) 113 { 114 m_TimeSource=new FreebobUtil::SystemTimeSource(); 107 m_State(E_Created) 108 { 115 109 } 116 110 … … 132 126 133 127 if(m_handle_util) raw1394_destroy_handle(m_handle_util); 134 135 if (m_TimeSource) delete m_TimeSource; 128 136 129 } 137 130 … … 202 195 } 203 196 204 // initialize the local timesource 205 m_TimeSource_NbCycleWraps=0; 206 unsigned int new_timer; 207 208 #ifdef LIBRAW1394_USE_CTRREAD_API 209 struct raw1394_cycle_timer ctr; 197 // test the cycle timer read function 210 198 int err; 211 err=raw1394_read_cycle_timer(m_handle_util, &ctr); 199 uint32_t cycle_timer; 200 uint64_t local_time; 201 err=raw1394_read_cycle_timer(m_handle_util, &cycle_timer, &local_time); 212 202 if(err) { 213 203 debugError("raw1394_read_cycle_timer failed.\n"); … … 216 206 return false; 217 207 } 218 new_timer=ctr.cycle_timer;219 #else220 // normally we should be able to use the same handle221 // because it is not iterated on by any other stuff222 // but I'm not sure223 quadlet_t buf=0;224 raw1394_read(m_handle_util, raw1394_get_local_id(m_handle_util),225 CSR_REGISTER_BASE | CSR_CYCLE_TIME, 4, &buf);226 new_timer= ntohl(buf) & 0xFFFFFFFF;227 #endif228 229 m_TimeSource_LastSecs=CYCLE_TIMER_GET_SECS(new_timer);230 231 // update the cycle timer value for initial value232 initCycleTimer();233 208 234 209 // update the internal state … … 292 267 293 268 m_State=E_Prepared; 294 295 return true;296 }297 298 bool299 IsoHandler::setSyncMaster(FreebobUtil::TimeSource *t)300 {301 m_TimeSource=t;302 303 // update the cycle timer value for initial value304 initCycleTimer();305 269 306 270 return true; … … 316 280 debugOutput( DEBUG_LEVEL_VERBOSE, "bus reset...\n"); 317 281 318 // as busreset can elect a new cycle master,319 // we need to re-initialize our timing code320 initCycleTimer();321 282 322 283 return 0; … … 330 291 331 292 unsigned int IsoHandler::getCycleTimerTicks() { 332 333 #ifdef LIBRAW1394_USE_CTRREAD_API334 293 // the new api should be realtime safe. 335 294 // it might cause a reschedule when turning preemption, 336 295 // back on but that won't hurt us if we have sufficient 337 296 // priority 338 struct raw1394_cycle_timer ctr;339 297 int err; 340 err=raw1394_read_cycle_timer(m_handle_util, &ctr); 298 uint32_t cycle_timer; 299 uint64_t local_time; 300 err=raw1394_read_cycle_timer(m_handle_util, &cycle_timer, &local_time); 341 301 if(err) { 342 302 debugWarning("raw1394_read_cycle_timer: %s\n", strerror(err)); 343 303 } 344 return CYCLE_TIMER_TO_TICKS((uint32_t)ctr.cycle_timer); 345 346 #else 347 // use the estimated version 348 freebob_microsecs_t now; 349 now=m_TimeSource->getCurrentTimeAsUsecs(); 350 return mapToCycleTimer(now); 351 #endif 352 304 return CYCLE_TIMER_TO_TICKS(cycle_timer); 353 305 } 354 306 … … 360 312 361 313 unsigned int IsoHandler::getCycleTimer() { 362 363 #ifdef LIBRAW1394_USE_CTRREAD_API364 314 // the new api should be realtime safe. 365 315 // it might cause a reschedule when turning preemption, 366 316 // back on but that won't hurt us if we have sufficient 367 317 // priority 368 struct raw1394_cycle_timer ctr;369 318 int err; 370 err=raw1394_read_cycle_timer(m_handle_util, &ctr); 319 uint32_t cycle_timer; 320 uint64_t local_time; 321 err=raw1394_read_cycle_timer(m_handle_util, &cycle_timer, &local_time); 371 322 if(err) { 372 323 debugWarning("raw1394_read_cycle_timer: %s\n", strerror(err)); 373 324 } 374 return ctr.cycle_timer; 375 376 #else 377 // use the estimated version 378 freebob_microsecs_t now; 379 now=m_TimeSource->getCurrentTimeAsUsecs(); 380 return TICKS_TO_CYCLE_TIMER(mapToCycleTimer(now)); 381 #endif 382 383 } 384 /** 385 * Maps a value of the active TimeSource to a Cycle Timer value. 386 * 387 * This is usefull if you know a time value and want the corresponding 388 * Cycle Timer value. Note that the value shouldn't be too far off 389 * the current time, because then the mapping can be bad. 390 * 391 * @return the value of the cycle timer (in ticks) 392 */ 393 394 unsigned int IsoHandler::mapToCycleTimer(freebob_microsecs_t now) { 395 396 // linear interpolation 397 int delta_usecs=now-m_lastmeas_usecs; 398 399 float offset=m_ticks_per_usec * ((float)delta_usecs); 400 401 int64_t pred_ticks=(int64_t)m_cycletimer_ticks+(int64_t)offset; 402 403 if (pred_ticks < 0) { 404 debugWarning("Predicted ticks < 0\n"); 405 } 406 debugOutput(DEBUG_LEVEL_VERBOSE,"now=%llu, m_lastmeas_usec=%llu, delta_usec=%d\n", 407 now, m_lastmeas_usecs, delta_usecs); 408 debugOutput(DEBUG_LEVEL_VERBOSE,"t/usec=%f, offset=%f, m_cc_t=%llu, pred_ticks=%lld\n", 409 m_ticks_per_usec, offset, m_cycletimer_ticks, pred_ticks); 410 411 // if we need to wrap, do it 412 if (pred_ticks > TICKS_PER_SECOND * 128L) { 413 pred_ticks -= TICKS_PER_SECOND * 128L; 414 } 415 416 return pred_ticks; 417 } 418 419 /** 420 * Maps a Cycle Timer value (in ticks) of the active TimeSource's unit. 421 * 422 * This is usefull if you know a Cycle Timer value and want the corresponding 423 * timesource value. Note that the value shouldn't be too far off 424 * the current cycle timer, because then the mapping can be bad. 425 * 426 * @return the mapped value 427 */ 428 429 freebob_microsecs_t IsoHandler::mapToTimeSource(unsigned int cc) { 430 431 // linear interpolation 432 int delta_cc=cc-m_cycletimer_ticks; 433 434 float offset= ((float)delta_cc) / m_ticks_per_usec; 435 436 int64_t pred_time=(int64_t)m_lastmeas_usecs+(int64_t)offset; 437 438 if (pred_time < 0) { 439 debugWarning("Predicted time < 0\n"); 440 debugOutput(DEBUG_LEVEL_VERBOSE,"cc=%u, m_cycletimer_ticks=%llu, delta_cc=%d\n", 441 cc, m_cycletimer_ticks, delta_cc); 442 debugOutput(DEBUG_LEVEL_VERBOSE,"t/usec=%f, offset=%f, m_lastmeas_usecs=%llu, pred_time=%lld\n", 443 m_ticks_per_usec, offset, m_lastmeas_usecs, pred_time); 444 } 445 446 447 return pred_time; 448 } 449 450 bool IsoHandler::updateCycleTimer() { 451 freebob_microsecs_t prev_usecs=m_lastmeas_usecs; 452 uint64_t prev_ticks=m_cycletimer_ticks; 453 454 freebob_microsecs_t new_usecs; 455 uint64_t new_ticks; 456 unsigned int new_timer; 457 458 /* To estimate the cycle timer, we implement a 459 DLL based routine, that maps the cycle timer 460 on the system clock. 461 462 For more info, refer to: 463 "Using a DLL to filter time" 464 Fons Adriaensen 465 466 Can be found at: 467 http://users.skynet.be/solaris/linuxaudio/downloads/usingdll.pdf 468 or maybe at: 469 http://www.kokkinizita.net/linuxaudio 470 471 Basically what we do is estimate the next point (T1,CC1_est) 472 based upon the previous point (T0, CC0) and the estimated rate (R). 473 Then we compare our estimation with the measured cycle timer 474 at T1 (=CC1_meas). We then calculate the estimation error on R: 475 err=(CC1_meas-CC0)/(T1-T2) - (CC1_est-CC0)/(T1-T2) 476 and try to minimize this on average (DLL) 477 478 Note that in order to have a contignous mapping, we should 479 update CC0<=CC1_est instead of CC0<=CC1_meas. The measurement 480 serves only to correct the error 'on average'. 481 482 In the code, the following variable names are used: 483 T0=prev_usecs 484 T1=next_usecs 485 486 CC0=prev_ticks 487 CC1_est=est_ticks 488 CC1_meas=meas_ticks 489 490 */ 491 #ifdef LIBRAW1394_USE_CTRREAD_API 492 struct raw1394_cycle_timer ctr; 493 int err; 494 err=raw1394_read_cycle_timer(m_handle_util, &ctr); 495 if(err) { 496 debugWarning("raw1394_read_cycle_timer: %s\n", strerror(err)); 497 } 498 new_usecs=(freebob_microsecs_t)ctr.local_time; 499 new_timer=ctr.cycle_timer; 500 #else 501 // normally we should be able to use the same handle 502 // because it is not iterated on by any other stuff 503 // but I'm not sure 504 quadlet_t buf=0; 505 raw1394_read(m_handle_util, raw1394_get_local_id(m_handle_util), 506 CSR_REGISTER_BASE | CSR_CYCLE_TIME, 4, &buf); 507 new_usecs=m_TimeSource->getCurrentTimeAsUsecs(); 508 new_timer= ntohl(buf) & 0xFFFFFFFF; 509 #endif 510 511 new_ticks=CYCLE_TIMER_TO_TICKS(new_timer); 512 513 // the difference in system time 514 int64_t delta_usecs=new_usecs-prev_usecs; 515 // this cannot be 0, because m_TimeSource->getCurrentTimeAsUsecs should 516 // never return the same value (maybe in future terrahz processors?) 517 assert(delta_usecs); 518 519 // the measured cycle timer difference 520 int64_t delta_ticks_meas; 521 if (new_ticks >= prev_ticks) { 522 delta_ticks_meas=new_ticks - prev_ticks; 523 } else { // wraparound 524 delta_ticks_meas=CYCLE_TIMER_UNWRAP_TICKS(new_ticks) - prev_ticks; 525 } 526 527 // the estimated cycle timer difference 528 int64_t delta_ticks_est=(int64_t)(m_ticks_per_usec * ((float)delta_usecs)); 529 530 // the measured & estimated rate 531 float rate_meas=((double)delta_ticks_meas/(double)delta_usecs); 532 float rate_est=((float)m_ticks_per_usec); 533 534 // these make sure we don't update when the measurement is 535 // bad. We know the nominal rate, and it can't be that far 536 // off. The thing is that there is a problem in measuring 537 // both usecs and ticks at the same time (no provision in 538 // the kernel. 539 // We know that there are some tolerances on both 540 // the system clock and the firewire clock such that the 541 // actual difference is rather small. So we discard values 542 // that are too far from the nominal rate. 543 // Otherwise the DLL has to have a very low bandwidth, in 544 // order not to be desturbed too much by these bad measurements 545 // resulting in very slow locking. 546 547 if ( (rate_meas < 24.576*(1.0+CC_MAX_RATE_ERROR)) 548 && (rate_meas > 24.576*(1.0-CC_MAX_RATE_ERROR))) { 549 550 #ifdef DEBUG 551 552 int64_t diff=(int64_t)delta_ticks_est; 553 554 // calculate the difference in predicted ticks and 555 // measured ticks 556 diff -= delta_ticks_meas; 557 558 559 if (diff > 24000L || diff < -24000L) { // approx +/-1 msec error 560 debugOutput(DEBUG_LEVEL_VERBOSE,"Bad pred (%p): diff=%lld, dt_est=%lld, dt_meas=%lld, d=%lldus, err=%fus\n", this, 561 diff, delta_ticks_est, delta_ticks_meas, delta_usecs, (((float)diff)/24.576) 562 ); 563 } else { 564 debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Good pred: diff=%lld, dt_est=%lld, dt_meas=%lld, d=%lldus, err=%fus\n", 565 diff, delta_ticks_est, delta_ticks_meas, delta_usecs, (((float)diff)/24.576) 566 ); 567 } 568 #endif 569 // DLL the error to obtain the rate. 570 // (note: the DLL makes the error=0) 571 // only update the DLL if the rate is within 10% of the expected 572 // rate 573 float err=rate_meas-rate_est; 574 575 // 2nd order DLL update 576 // const float w=6.28*0.0001; 577 // const float b=w*1.45; 578 // const float c=w*w; 579 // 580 // m_ticks_per_usec += b*err + m_ticks_per_usec_dll_err2; 581 // m_ticks_per_usec_dll_err2 += c * err; 582 583 // first order DLL update 584 m_ticks_per_usec += CC_DLL_COEFF*err; 585 586 if ( (m_ticks_per_usec > 24.576*(1.0+CC_MAX_RATE_ERROR)) 587 || (m_ticks_per_usec < 24.576*(1.0-CC_MAX_RATE_ERROR))) { 588 debugOutput(DEBUG_LEVEL_VERBOSE, "Warning: DLL ticks/usec near clipping (%8.4f)\n", 589 m_ticks_per_usec); 590 } 591 592 // update the internal values 593 // note: the next cycletimer point is 594 // the estimated one, not the measured one! 595 m_cycletimer_ticks += delta_ticks_est; 596 // if we need to wrap, do it 597 if (m_cycletimer_ticks > TICKS_PER_SECOND * 128L) { 598 m_cycletimer_ticks -= TICKS_PER_SECOND * 128L; 599 } 600 601 m_lastmeas_usecs = new_usecs; 602 603 debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"U TS: %10llu -> %10llu, d=%7lldus, dt_est=%7lld, dt_meas=%7lld, erate=%6.4f, mrate=%6f\n", 604 prev_ticks, m_cycletimer_ticks, delta_usecs, 605 delta_ticks_est, delta_ticks_meas, m_ticks_per_usec, rate_meas 606 ); 607 608 // the estimate is good 609 return true; 610 } else { 611 debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"U TS: Not updating, rate out of range (%6.4f)\n", 612 rate_meas 613 ); 614 return false; 615 616 } 617 } 618 619 void IsoHandler::initCycleTimer() { 620 freebob_microsecs_t prev_usecs; 621 unsigned int prev_ticks; 622 unsigned int prev_timer; 623 624 freebob_microsecs_t new_usecs; 625 unsigned int new_ticks; 626 unsigned int new_timer; 627 628 float rate=0.0; 629 630 unsigned int try_cnt=0; 631 632 // make sure that we start with a decent rate, 633 // meaning that we want two successive (usecs,ticks) 634 // points that make sense. 635 636 while ( (try_cnt++ < CC_INIT_MAX_TRIES) && 637 ( (rate > 24.576*(1.0+CC_MAX_RATE_ERROR)) 638 || (rate < 24.576*(1.0-CC_MAX_RATE_ERROR)))) { 639 640 #ifdef LIBRAW1394_USE_CTRREAD_API 641 struct raw1394_cycle_timer ctr; 642 int err; 643 err=raw1394_read_cycle_timer(m_handle_util, &ctr); 644 if(err) { 645 debugWarning("raw1394_read_cycle_timer: %s\n", strerror(err)); 646 } 647 prev_usecs=(freebob_microsecs_t)ctr.local_time; 648 prev_timer=ctr.cycle_timer; 649 #else 650 // normally we should be able to use the same handle 651 // because it is not iterated on by any other stuff 652 // but I'm not sure 653 quadlet_t buf=0; 654 raw1394_read(m_handle_util, raw1394_get_local_id(m_handle_util), 655 CSR_REGISTER_BASE | CSR_CYCLE_TIME, 4, &buf); 656 prev_usecs=m_TimeSource->getCurrentTimeAsUsecs(); 657 prev_timer= ntohl(buf) & 0xFFFFFFFF; 658 #endif 659 prev_ticks=CYCLE_TIMER_TO_TICKS(prev_timer); 660 661 usleep(CC_SLEEP_TIME_AFTER_UPDATE); 662 663 664 #ifdef LIBRAW1394_USE_CTRREAD_API 665 err=raw1394_read_cycle_timer(m_handle_util, &ctr); 666 if(err) { 667 debugWarning("raw1394_read_cycle_timer: %s\n", strerror(err)); 668 } 669 new_usecs=(freebob_microsecs_t)ctr.local_time; 670 new_timer=ctr.cycle_timer; 671 #else 672 // normally we should be able to use the same handle 673 // because it is not iterated on by any other stuff 674 // but I'm not sure 675 raw1394_read(m_handle_util, raw1394_get_local_id(m_handle_util), 676 CSR_REGISTER_BASE | CSR_CYCLE_TIME, 4, &buf); 677 new_usecs=m_TimeSource->getCurrentTimeAsUsecs(); 678 new_timer= ntohl(buf) & 0xFFFFFFFF; 679 #endif 680 681 new_ticks=CYCLE_TIMER_TO_TICKS(new_timer); 682 683 unsigned int delta_ticks; 684 685 if (new_ticks > prev_ticks) { 686 delta_ticks=new_ticks - prev_ticks; 687 } else { // wraparound 688 delta_ticks=CYCLE_TIMER_UNWRAP_TICKS(new_ticks) - prev_ticks; 689 } 690 691 int delta_usecs=new_usecs-prev_usecs; 692 693 // this cannot be 0, because m_TimeSource->getCurrentTimeAsUsecs should 694 // never return the same value (maybe in future terrahz processors?) 695 assert(delta_usecs); 696 697 rate=((float)delta_ticks/(float)delta_usecs); 698 699 // update the internal values 700 m_cycletimer_ticks=new_ticks; 701 m_lastmeas_usecs=new_usecs; 702 703 debugOutput(DEBUG_LEVEL_VERBOSE,"Try %d: rate=%6.4f\n", 704 try_cnt,rate 705 ); 706 707 } 708 709 // this is not fatal, the DLL will eventually correct this 710 if(try_cnt == CC_INIT_MAX_TRIES) { 711 debugWarning("Failed to properly initialize cycle timer...\n"); 712 } 713 714 // initialize this to the nominal value 715 m_ticks_per_usec = 24.576; 716 m_ticks_per_usec_dll_err2 = 0; 717 325 return cycle_timer; 718 326 } 719 327 … … 730 338 debugOutputShort( DEBUG_LEVEL_NORMAL, " Packet count : %10d (%5d dropped)\n", 731 339 this->getPacketCount(), this->getDroppedCount()); 732 733 #ifdef DEBUG 734 unsigned int cc=this->getCycleTimerTicks(); 735 debugOutputShort( DEBUG_LEVEL_NORMAL, " Cycle timer : %10lu (%03us, %04ucycles, %04uticks)\n", 736 cc,TICKS_TO_SECS(cc),TICKS_TO_CYCLES(cc),TICKS_TO_OFFSET(cc)); 737 738 /* freebob_microsecs_t now=m_TimeSource->getCurrentTimeAsUsecs(); 739 cc=mapToCycleTimer(now); 740 freebob_microsecs_t now_mapped=mapToTimeSource(cc); 741 742 debugOutputShort( DEBUG_LEVEL_NORMAL, " Mapping test : now: %14llu, cc: %10lu, mapped now: %14llu\n", 743 now,cc,now_mapped);*/ 744 #endif 745 debugOutputShort( DEBUG_LEVEL_NORMAL, " Ticks/usec : %8.6f (dll2: %8.6e)\n\n", 746 this->getTicksPerUsec(), m_ticks_per_usec_dll_err2); 747 748 }; 340 } 749 341 750 342 void IsoHandler::setVerboseLevel(int l) … … 787 379 788 380 } 789 790 /* The timesource interface */791 freebob_microsecs_t IsoHandler::getCurrentTime() {792 unsigned int new_timer;793 794 new_timer= getCycleTimerTicks();795 796 // this assumes that it never happens that there are more than 2797 // minutes between calls798 if (CYCLE_TIMER_GET_SECS(new_timer) < m_TimeSource_LastSecs) {799 m_TimeSource_NbCycleWraps++;800 }801 802 freebob_microsecs_t ticks=m_TimeSource_NbCycleWraps * 128L * TICKS_PER_SECOND803 + CYCLE_TIMER_TO_TICKS(new_timer);804 805 m_TimeSource_LastSecs=CYCLE_TIMER_GET_SECS(new_timer);806 807 debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Wraps=%4u, LastSecs=%3u, nowSecs=%3u, ticks=%10u\n",808 m_TimeSource_NbCycleWraps, m_TimeSource_LastSecs,809 CYCLE_TIMER_GET_SECS(new_timer), ticks810 );811 812 return ticks;813 }814 815 freebob_microsecs_t IsoHandler::unWrapTime(freebob_microsecs_t t) {816 return CYCLE_TIMER_UNWRAP_TICKS(t);817 }818 819 freebob_microsecs_t IsoHandler::wrapTime(freebob_microsecs_t t) {820 return CYCLE_TIMER_WRAP_TICKS(t);821 }822 823 freebob_microsecs_t IsoHandler::getCurrentTimeAsUsecs() {824 float tmp=getCurrentTime();825 float tmp2 = tmp * USECS_PER_TICK;826 freebob_microsecs_t retval=(freebob_microsecs_t)tmp2;827 828 debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"tmp=%f, tmp2=%f, retval=%u\n",829 tmp, tmp2,retval830 );831 832 return retval;833 }834 835 836 381 837 382 /* Child class implementations */ branches/streaming-rework/src/libstreaming/IsoHandler.h
r391 r398 31 31 #include "../debugmodule/debugmodule.h" 32 32 33 #include "libutil/TimeSource.h"34 35 33 #include <libraw1394/raw1394.h> 36 34 … … 50 48 */ 51 49 52 class IsoHandler : public FreebobUtil::TimeSource50 class IsoHandler 53 51 { 54 52 protected: … … 106 104 /// get the most recent cycle timer value (as is) 107 105 unsigned int getCycleTimer(); 108 /// Maps a value of the active TimeSource to a Cycle Timer value. 109 unsigned int mapToCycleTimer(freebob_microsecs_t now); 110 /// Maps a Cycle Timer value to the active TimeSource's unit. 111 freebob_microsecs_t mapToTimeSource(unsigned int cc); 112 /// update the cycle timer cache 113 bool updateCycleTimer(); 114 float getTicksPerUsec() {return m_ticks_per_usec;}; 115 116 // register a master timing source 117 bool setSyncMaster(FreebobUtil::TimeSource *t); 118 106 119 107 protected: 120 108 raw1394handle_t m_handle; … … 125 113 int m_irq_interval; 126 114 127 uint64_t m_cycletimer_ticks;128 uint64_t m_lastmeas_usecs;129 float m_ticks_per_usec;130 float m_ticks_per_usec_dll_err2;131 132 115 int m_packetcount; 133 116 int m_dropped; … … 135 118 IsoStream *m_Client; 136 119 137 FreebobUtil::TimeSource *m_TimeSource;138 139 120 virtual int handleBusReset(unsigned int generation); 140 121 … … 144 125 private: 145 126 static int busreset_handler(raw1394handle_t handle, unsigned int generation); 146 147 void initCycleTimer();148 127 149 128 // the state machine … … 158 137 159 138 enum EHandlerStates m_State; 160 161 // implement the TimeSource interface162 public:163 freebob_microsecs_t getCurrentTime();164 freebob_microsecs_t getCurrentTimeAsUsecs();165 inline freebob_microsecs_t unWrapTime(freebob_microsecs_t t);166 inline freebob_microsecs_t wrapTime(freebob_microsecs_t t);167 168 private:169 // to cope with wraparound170 unsigned int m_TimeSource_LastSecs;171 unsigned int m_TimeSource_NbCycleWraps;172 139 173 140 }; branches/streaming-rework/src/libstreaming/IsoHandlerManager.cpp
r397 r398 161 161 return true; 162 162 163 }164 165 // updates the internal cycle timer caches of the handlers166 void IsoHandlerManager::updateCycleTimers() {167 debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "enter...\n");168 169 for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin();170 it != m_IsoHandlers.end();171 ++it )172 {173 int cnt=0;174 while (!(*it)->updateCycleTimer() && (cnt++ < MAX_UPDATE_TRIES)) {175 usleep(USLEEP_AFTER_UPDATE_FAILURE);176 }177 }178 179 163 } 180 164 branches/streaming-rework/src/libstreaming/IsoHandlerManager.h
r390 r398 121 121 /// iterate all child handlers 122 122 bool iterate(); 123 public: // FIXME: just so that SPM can do this (temp solution) 124 /// updates the cycle timer caches of all child handlers 125 void updateCycleTimers(); 123 126 124 private: 127 125 // note: there is a disctinction between streams and handlers branches/streaming-rework/src/libstreaming/StreamProcessorManager.cpp
r396 r398 33 33 #include <assert.h> 34 34 35 #include "../libutil/PosixThread.h"36 37 35 #include "libstreaming/cycletimer.h" 38 36 39 37 #define CYCLES_TO_SLEEP_AFTER_RUN_SIGNAL 50 38 39 #define RUNNING_TIMEOUT_MSEC 4000 40 #define PREPARE_TIMEOUT_MSEC 4000 41 #define ENABLE_TIMEOUT_MSEC 4000 40 42 41 43 namespace FreebobStreaming { … … 165 167 debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n"); 166 168 167 // the tread that runs the StreamProcessor168 // checking the period boundaries169 int prio=m_thread_priority+5;170 if (prio>98) prio=98;171 172 m_streamingThread=new FreebobUtil::PosixThread(this,173 m_thread_realtime, prio,174 PTHREAD_CANCEL_DEFERRED);175 176 if(!m_streamingThread) {177 debugFatal("Could not create streaming thread\n");178 return false;179 }180 181 169 m_isoManager=new IsoHandlerManager(m_thread_realtime, m_thread_priority); 182 170 … … 197 185 198 186 return true; 199 }200 201 bool StreamProcessorManager::Init()202 {203 debugOutput( DEBUG_LEVEL_VERBOSE, "Initializing runner...\n");204 205 // no xrun has occurred (yet)206 207 return true;208 187 } 209 188 … … 275 254 } 276 255 277 // FIXME: this can be removed278 bool StreamProcessorManager::Execute()279 {280 // temp measure, polling281 usleep(1000);282 283 // FIXME: move this to an IsoHandlerManager sub-thread284 // and make this private again in IHM285 m_isoManager->updateCycleTimers();286 287 return true;288 }289 256 290 257 bool StreamProcessorManager::syncStartAll() { … … 293 260 // we have to wait until all streamprocessors indicate that they are running 294 261 // i.e. that there is actually some data stream flowing 295 int wait_cycles= 2000; // two seconds262 int wait_cycles=RUNNING_TIMEOUT_MSEC; // two seconds 296 263 bool notRunning=true; 297 264 while (notRunning && wait_cycles) { … … 453 420 return false; 454 421 } 455 456 debugOutput( DEBUG_LEVEL_VERBOSE, "Starting streaming threads...\n");457 458 // start the runner thread459 // FIXME: not used anymore (for updatecycletimers ATM, but that's not good)460 m_streamingThread->Start();461 422 462 423 // start all SP's synchonized … … 478 439 debugOutput( DEBUG_LEVEL_VERBOSE, "Stopping...\n"); 479 440 assert(m_isoManager); 480 assert(m_streamingThread);481 441 482 442 debugOutput( DEBUG_LEVEL_VERBOSE, "Waiting for all StreamProcessors to prepare to stop...\n"); … … 484 444 // (like the MOTU) need to do a few things before it's safe to turn off the iso 485 445 // handling. 486 int wait_cycles= 2000; // two seconds ought to be sufficient446 int wait_cycles=PREPARE_TIMEOUT_MSEC; // two seconds ought to be sufficient 487 447 bool allReady = false; 488 448 while (!allReady && wait_cycles) { … … 504 464 } 505 465 506 507 debugOutput( DEBUG_LEVEL_VERBOSE, "Stopping threads...\n");508 509 m_streamingThread->Stop();510 466 511 467 debugOutput( DEBUG_LEVEL_VERBOSE, "Stopping handlers...\n"); … … 604 560 // we have to wait until all streamprocessors indicate that they are running 605 561 // i.e. that there is actually some data stream flowing 606 int wait_cycles= 2000; // two seconds562 int wait_cycles=ENABLE_TIMEOUT_MSEC; // two seconds 607 563 bool notEnabled=true; 608 564 while (notEnabled && wait_cycles) { … … 689 645 // we have to wait until all streamprocessors indicate that they are running 690 646 // i.e. that there is actually some data stream flowing 691 int wait_cycles= 2000; // two seconds647 int wait_cycles=ENABLE_TIMEOUT_MSEC; // two seconds 692 648 bool enabled=true; 693 649 while (enabled && wait_cycles) { branches/streaming-rework/src/libstreaming/StreamProcessorManager.h
r396 r398 50 50 51 51 */ 52 class StreamProcessorManager : 53 public FreebobUtil::RunnableInterface { 52 class StreamProcessorManager { 54 53 55 54 public: … … 121 120 122 121 protected: 123 int signalWaiters(); // call this to signal a period boundary124 // RunnableInterface interface125 bool Execute(); // note that this is called in we while(running) loop126 bool Init();127 128 122 // thread sync primitives 129 sem_t m_period_semaphore;130 131 123 bool m_xrun_happened; 132 124 … … 144 136 IsoHandlerManager *m_isoManager; 145 137 146 FreebobUtil::PosixThread *m_streamingThread;147 148 138 unsigned int m_nbperiods; 149 139 branches/streaming-rework/tests/test-sytmonitor.cpp
r393 r398 241 241 goto finish; 242 242 } 243 244 if (!masterTimeSource.registerSlave(monitors[i]->getHandler())) { 245 debugOutput(DEBUG_LEVEL_NORMAL, "Could not register SytMonitor %d's IsoHandler with masterTimeSource\n", i); 246 goto finish; 247 248 } 243 249 244 } 250 245