예제 #1
0
static int PaHost_CanaryProc( PaHostSoundControl   *pahsc )
{
    int   result = 0;

#ifdef GNUSTEP
    GSRegisterCurrentThread(); /* SB20010904 */
#endif

    while( pahsc->pahsc_CanaryRun) {
      usleep( WATCHDOG_INTERVAL_USEC );
      gettimeofday( &pahsc->pahsc_CanaryTime, NULL );
    }

    DBUG(("PaHost_CanaryProc: exiting.\n"));

#ifdef GNUSTEP
    GSUnregisterCurrentThread();  /* SB20010904 */
#endif

    return result;
}
예제 #2
0
static PaError Pa_AudioThreadProc( internalPortAudioStream   *past )
{
    PaError      result;
    PaHostSoundControl             *pahsc;
    ssize_t      bytes_read, bytes_written;

    pahsc = (PaHostSoundControl *) past->past_DeviceData;
    if( pahsc == NULL ) return paInternalError;

#ifdef GNUSTEP
    GSRegisterCurrentThread(); /* SB20010904 */
#endif

    result = PaHost_BoostPriority( past );
    if( result < 0 ) goto error;

    past->past_IsActive = 1;
    DBUG(("entering thread.\n"));

    while( (past->past_StopNow == 0) && (past->past_StopSoon == 0) )
    {
        /* Read data from device */
        if(pahsc->pahsc_NativeInputBuffer)
        {
            unsigned int totalread = 0;
            DBUG(("Pa_AudioThreadProc: attempt to read %d bytes\n", pahsc->pahsc_BytesPerInputBuffer));
            do
            {
                bytes_read = read(pahsc->pahsc_InputHandle,
                    (char *)pahsc->pahsc_NativeInputBuffer + totalread,
                    pahsc->pahsc_BytesPerInputBuffer - totalread);

                if (bytes_read < 0)
                {
                    ERR_RPT(("PortAudio: read interrupted!\n"));
                    break;
                }

                totalread += bytes_read;
            } while( totalread < pahsc->pahsc_BytesPerInputBuffer);
        }

        /* Convert 16 bit native data to user data and call user routine. */
        DBUG(("converting...\n"));
        Pa_StartUsageCalculation( past );
        result = Pa_CallConvertInt16( past,
                                      pahsc->pahsc_NativeInputBuffer,
                                      pahsc->pahsc_NativeOutputBuffer );
        Pa_EndUsageCalculation( past );
        if( result != 0)
        {
            DBUG(("hmm, Pa_CallConvertInt16() says: %d. i'm bailing.\n",
                  result));
            break;
        }

        /* Write data to device. */
        if( pahsc->pahsc_NativeOutputBuffer )
        {
            unsigned int totalwritten = 0;
            do
            {
                bytes_written = write(pahsc->pahsc_OutputHandle,
                    (void *)pahsc->pahsc_NativeOutputBuffer,
                    pahsc->pahsc_BytesPerOutputBuffer);
                if( bytes_written < 0 )
                {
                    ERR_RPT(("PortAudio: write interrupted!"));
                    break;
                }

                totalwritten += bytes_written;
            } while( totalwritten < pahsc->pahsc_BytesPerOutputBuffer);
        }

        Pa_UpdateStreamTime(pahsc);
    }
    DBUG(("Pa_AudioThreadProc: left audio loop.\n"));

    past->past_IsActive = 0;
    PaHost_StopWatchDog( pahsc );

error:
    DBUG(("leaving audio thread.\n"));
#ifdef GNUSTEP
    GSUnregisterCurrentThread();  /* SB20010904 */
#endif
    return result;
}
예제 #3
0
static PaError PaHost_WatchDogProc( PaHostSoundControl   *pahsc )
{
    struct sched_param    schp = { 0 };
    int                   maxPri;

#ifdef GNUSTEP
    GSRegisterCurrentThread(); /* SB20010904 */
#endif

/* Run at a priority level above audio thread so we can still run if it hangs. */
/* Rise more than 1 because of rumored off-by-one scheduler bugs. */
    schp.sched_priority = pahsc->pahsc_AudioPriority + 4;
    maxPri = sched_get_priority_max(SCHEDULER_POLICY);
    if( schp.sched_priority > maxPri ) schp.sched_priority = maxPri;

    if (sched_setscheduler(0, SCHEDULER_POLICY, &schp) != 0)
    {
        ERR_RPT(("PaHost_WatchDogProc: cannot set watch dog priority!\n"));
        goto killAudio;
    }

    /* Compare watchdog time with audio and canary thread times. */
    /* Sleep for a while or until thread cancelled. */
    while( pahsc->pahsc_WatchDogRun )
    {

        int              delta;
        struct timeval   currentTime;

        usleep( WATCHDOG_INTERVAL_USEC );
        gettimeofday( &currentTime, NULL );

        /* If audio thread is not advancing, then it must be hung so kill it. */
        delta = currentTime.tv_sec - pahsc->pahsc_EntryTime.tv_sec;
        DBUG(("PaHost_WatchDogProc: audio delta = %d\n", delta ));
        if( delta > WATCHDOG_MAX_SECONDS )
        {
            goto killAudio;
        }

        /* If canary died, then lower audio priority and halt canary. */
        delta = currentTime.tv_sec - pahsc->pahsc_CanaryTime.tv_sec;
        if( delta > WATCHDOG_MAX_SECONDS )
        {
            ERR_RPT(("PaHost_WatchDogProc: canary died!\n"));
            goto lowerAudio;
        }
    }

    DBUG(("PaHost_WatchDogProc: exiting.\n"));
#ifdef GNUSTEP
    GSUnregisterCurrentThread();  /* SB20010904 */
#endif
    return 0;

lowerAudio:
    {
        struct sched_param    schat = { 0 };
        if( sched_setscheduler(pahsc->pahsc_AudioThreadPID, SCHED_OTHER, &schat) != 0)
        {
            ERR_RPT(("PaHost_WatchDogProc: failed to lower audio priority. errno = %d\n", errno ));
            /* Fall through into killing audio thread. */
        }
        else
        {
            ERR_RPT(("PaHost_WatchDogProc: lowered audio priority to prevent hogging of CPU.\n"));
            goto cleanup;
        }
    }

killAudio:
    ERR_RPT(("PaHost_WatchDogProc: killing hung audio thread!\n"));
    pthread_kill( pahsc->pahsc_AudioThread, SIGKILL );

cleanup:
    pahsc->pahsc_CanaryRun = 0;
    DBUG(("PaHost_WatchDogProc: cancel Canary\n"));
    pthread_cancel( pahsc->pahsc_CanaryThread );
    DBUG(("PaHost_WatchDogProc: join Canary\n"));
    pthread_join( pahsc->pahsc_CanaryThread, NULL );
    DBUG(("PaHost_WatchDogProc: forget Canary\n"));
    pahsc->pahsc_IsCanaryThreadValid = 0;

#ifdef GNUSTEP
    GSUnregisterCurrentThread();  /* SB20010904 */
#endif
    return 0;
}
예제 #4
0
파일: unixfuncs.c 프로젝트: Garalv/miumiu
static int WatchDogProc( prioboost *b )
{
	struct sched_param    schp = { 0 };
	int                   maxPri;

	/* Run at a priority level above main thread so we can still run if it hangs. */
	/* Rise more than 1 because of rumored off-by-one scheduler bugs. */
	schp.sched_priority = b->priority + 4;
	maxPri = sched_get_priority_max(SCHEDULER_POLICY);
	if( schp.sched_priority > maxPri ) schp.sched_priority = maxPri;

	if (pthread_setschedparam(pthread_self(), SCHEDULER_POLICY, &schp) != 0)
	{
		ERR_RPT("WatchDogProc: cannot set watch dog priority!\n");
		goto killAudio;
	}

	DBUG("prioboost: WatchDog priority set to level %d!\n", schp.sched_priority);

	/* Compare watchdog time with audio and canary thread times. */
	/* Sleep for a while or until thread cancelled. */
	while( b->WatchDogRun )
	{

		int              delta;
		struct timeval   currentTime;

		usleep( WATCHDOG_INTERVAL_USEC );
		gettimeofday( &currentTime, NULL );

#if 0
		/* If audio thread is not advancing, then it must be hung so kill it. */
		delta = currentTime.tv_sec - b->EntryTime.tv_sec;
		DBUG(("WatchDogProc: audio delta = %d\n", delta ));
		if( delta > WATCHDOG_MAX_SECONDS )
		{
			goto killAudio;
		}
#endif

		/* If canary died, then lower audio priority and halt canary. */
		delta = currentTime.tv_sec - b->CanaryTime.tv_sec;
		DBUG("WatchDogProc: dogging, delta = %ld, mysec=%d\n", delta, currentTime.tv_sec);
		if( delta > WATCHDOG_MAX_SECONDS )
		{
			ERR_RPT("WatchDogProc: canary died!\n");
			goto lowerAudio;
		}
	}

	DBUG("WatchDogProc: exiting.\n");
	return 0;

lowerAudio:
	{
		struct sched_param    schat = { 0 };
		if( pthread_setschedparam(b->ThreadID, SCHED_OTHER, &schat) != 0)
		{
			ERR_RPT("WatchDogProc: failed to lower audio priority. errno = %d\n", errno );
			/* Fall through into killing audio thread. */
		}
		else
		{
			ERR_RPT("WatchDogProc: lowered audio priority to prevent hogging of CPU.\n");
			goto cleanup;
		}
	}

killAudio:
	ERR_RPT("WatchDogProc: killing hung audio thread!\n");
	//pthread_cancel( b->ThreadID);
	//pthread_join( b->ThreadID);
	exit(1);

cleanup:
	b->CanaryRun = 0;
	DBUG("WatchDogProc: cancel Canary\n");
	pthread_cancel( b->CanaryThread );
	DBUG("WatchDogProc: join Canary\n");
	pthread_join( b->CanaryThread, NULL );
	DBUG("WatchDogProc: forget Canary\n");
	b->IsCanaryThreadValid = 0;

#ifdef GNUSTEP
	GSUnregisterCurrentThread();  /* SB20010904 */
#endif
	return 0;
}