Changeset 127 for portaudio/trunk/pa_unix_oss
- Timestamp:
- 02/25/02 12:20:39 (9 years ago)
- File:
-
- 1 edited
-
portaudio/trunk/pa_unix_oss/pa_unix_oss.c (modified) (17 diffs)
Legend:
- Unmodified
- Added
- Removed
-
portaudio/trunk/pa_unix_oss/pa_unix_oss.c
r124 r127 99 99 #include <memory.h> 100 100 #include <math.h> 101 #include "portaudio.h"102 #include "pa_host.h"103 #include "pa_trace.h"104 105 101 #include <sys/ioctl.h> 106 102 #include <sys/time.h> … … 108 104 #include <unistd.h> 109 105 #include <signal.h> 110 #include <stdio.h> 111 #include <stdlib.h> 106 #include <sched.h> 107 #include <pthread.h> 108 #include <errno.h> 112 109 113 110 #ifdef __linux__ … … 117 114 #endif 118 115 119 #include <sched.h>120 #include <pthread.h>121 116 #include "portaudio.h" 117 #include "pa_host.h" 118 #include "pa_trace.h" 122 119 123 120 #define PRINT(x) { printf x; fflush(stdout); } … … 160 157 int pahsc_AudioPriority; /* priority of background audio thread */ 161 158 pthread_t pahsc_AudioThread; /* background audio thread */ 159 pid_t pahsc_AudioThreadPID; /* background audio thread */ 162 160 pthread_t pahsc_WatchDogThread; /* highest priority thread that protects system */ 161 int pahsc_WatchDogRun; /* Ask WatchDog to stop. */ 163 162 pthread_t pahsc_CanaryThread; /* low priority thread that detects abuse by audio */ 164 163 struct timeval pahsc_CanaryTime; 164 int pahsc_CanaryRun; /* Ask Canary to stop. */ 165 165 short *pahsc_NativeInputBuffer; 166 166 short *pahsc_NativeOutputBuffer; … … 543 543 static int PaHost_CanaryProc( PaHostSoundControl *pahsc ) 544 544 { 545 int result ;545 int result = 0; 546 546 547 547 #ifdef GNUSTEP … … 549 549 #endif 550 550 551 while( (result = usleep( WATCHDOG_INTERVAL_USEC )) == 0)551 while( pahsc->pahsc_CanaryRun && ((result = usleep( WATCHDOG_INTERVAL_USEC )) == 0) ) 552 552 { 553 553 gettimeofday( &pahsc->pahsc_CanaryTime, NULL ); … … 564 564 565 565 /******************************************************************************************* 566 * Monitor audio thread and killit if it hogs the CPU.566 * Monitor audio thread and lower its it if it hogs the CPU. 567 567 * To prevent getting killed, the audio thread must update a 568 568 * variable with a timer value. … … 595 595 /* Compare watchdog time with audio and canary thread times. */ 596 596 /* Sleep for a while or until thread cancelled. */ 597 while( (result = usleep( WATCHDOG_INTERVAL_USEC )) == 0)597 while( pahsc->pahsc_WatchDogRun && ((result = usleep( WATCHDOG_INTERVAL_USEC )) == 0) ) 598 598 { 599 599 int delta; … … 602 602 gettimeofday( ¤tTime, NULL ); 603 603 604 /* If audio thread is not advancing, then kill it. */604 /* If audio thread is not advancing, then lower its priority. */ 605 605 delta = currentTime.tv_sec - pahsc->pahsc_EntryTime.tv_sec; 606 606 DBUG(("PaHost_WatchDogProc: audio delta = %d\n", delta )); 607 607 if( delta > WATCHDOG_MAX_SECONDS ) 608 608 { 609 ERR_RPT(("PaHost_WatchDogProc: killing hung audio thread!\n"));610 609 goto killAudio; 611 610 } … … 615 614 if( delta > WATCHDOG_MAX_SECONDS ) 616 615 { 617 ERR_RPT(("PaHost_WatchDogProc: canary died! Killing runaway audio thread!\n"));618 goto killAudio;616 ERR_RPT(("PaHost_WatchDogProc: canary died!\n")); 617 goto lowerAudio; 619 618 } 620 619 } … … 626 625 return 0; 627 626 627 lowerAudio: 628 { 629 struct sched_param schat = { 0 }; 630 if( sched_setscheduler(pahsc->pahsc_AudioThreadPID, SCHED_OTHER, &schat) != 0) 631 { 632 ERR_RPT(("PaHost_WatchDogProc: failed to lower audio priority. errno = %d\n", errno )); 633 /* Fall through into killing audio thread. */ 634 } 635 else 636 { 637 ERR_RPT(("PaHost_WatchDogProc: lowered audio priority to prevent hogging of CPU.\n")); 638 goto cleanup; 639 } 640 } 641 628 642 killAudio: 643 ERR_RPT(("PaHost_WatchDogProc: killing hung audio thread!\n")); 629 644 pthread_kill( pahsc->pahsc_AudioThread, SIGKILL ); 645 646 cleanup: 647 pahsc->pahsc_CanaryRun = 0; 648 DBUG(("PaHost_WatchDogProc: cancel Canary\n")); 630 649 pthread_cancel( pahsc->pahsc_CanaryThread ); 650 DBUG(("PaHost_WatchDogProc: join Canary\n")); 631 651 pthread_join( pahsc->pahsc_CanaryThread, NULL ); 652 DBUG(("PaHost_WatchDogProc: forget Canary\n")); 632 653 pahsc->pahsc_CanaryThread = INVALID_THREAD; 633 pahsc->pahsc_WatchDogThread = INVALID_THREAD;634 654 635 655 #ifdef GNUSTEP … … 645 665 if( pahsc->pahsc_WatchDogThread != INVALID_THREAD ) 646 666 { 667 pahsc->pahsc_WatchDogRun = 0; 668 DBUG(("PaHost_StopWatchDog: cancel WatchDog\n")); 647 669 pthread_cancel( pahsc->pahsc_WatchDogThread ); 648 670 pthread_join( pahsc->pahsc_WatchDogThread, NULL ); … … 652 674 if( pahsc->pahsc_CanaryThread != INVALID_THREAD ) 653 675 { 676 pahsc->pahsc_CanaryRun = 0; 677 DBUG(("PaHost_StopWatchDog: cancel Canary\n")); 654 678 pthread_cancel( pahsc->pahsc_CanaryThread ); 679 DBUG(("PaHost_StopWatchDog: join Canary\n")); 655 680 pthread_join( pahsc->pahsc_CanaryThread, NULL ); 656 681 pahsc->pahsc_CanaryThread = INVALID_THREAD; … … 669 694 670 695 /* Launch a canary thread to detect priority abuse. */ 696 pahsc->pahsc_CanaryRun = 1; 671 697 hres = pthread_create(&(pahsc->pahsc_CanaryThread), 672 698 NULL /*pthread_attr_t * attr*/, … … 681 707 682 708 /* Launch a watchdog thread to prevent runaway audio thread. */ 709 pahsc->pahsc_WatchDogRun = 1; 683 710 hres = pthread_create(&(pahsc->pahsc_WatchDogThread), 684 711 NULL /*pthread_attr_t * attr*/, … … 711 738 if( pahsc == NULL ) return paInternalError; 712 739 740 pahsc->pahsc_AudioThreadPID = getpid(); 741 DBUG(("PaHost_BoostPriority: audio PID = %d\n", pahsc->pahsc_AudioThreadPID )); 742 713 743 /* Choose a priority in the middle of the range. */ 714 744 pahsc->pahsc_AudioPriority = (sched_get_priority_max(SCHEDULER_POLICY) - … … 807 837 pahsc->pahsc_LastPosPtr = info.bytes; 808 838 } 809 839 DBUG(("Pa_AudioThreadProc: left audio loop.\n")); 840 810 841 past->past_IsActive = 0; 811 812 842 PaHost_StopWatchDog( pahsc ); 813 843 844 error: 814 845 DBUG(("leaving audio thread.\n")); 815 error:816 846 #ifdef GNUSTEP 817 847 GSUnregisterCurrentThread(); /* SB20010904 */
Note: See TracChangeset
for help on using the changeset viewer.
