« 自民大躍進! | トップページ | なんとなくプラモデルメイク!(ケロロ軍曹の場合…) »

2005年9月12日 (月)

「Sleep」の代替え処理は…

どうやったら…
「Sleep」の代替え処理が組めるかな~
と、考えながら幾年月…。

と言うほど日は経っていないが、
多分こうしたら同等品か?
と思えるものを組んでみました…。

多分大丈夫でしょう…。

多分…ですよ…。

動けばいいんです!

断っておきますが…
ボケプログラマーですから!
処理は、ボケボケです!

#pragma comment( lib, "WinMm.lib" )
//--------------------------------------
#include    <Windows.h>
#include    <StdIo.h>
//--------------------------------------
#define        WAIT_TIME        1
#define        LIST_MAX        1001
//--------------------------------------
HANDLE            TimerHandle;
DWORD            TimerID;
DWORD            TimerWait;
//--------------------------------------
//    ※解除するだけです。
static void CALLBACK TimerProc( UINT uTimerID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2 )
{
    if( TimerWait != 0 )
        if( --TimerWait == 0 )
            ResumeThread( TimerHandle );
}
//--------------------------------------
void TimerInitial( void )
{
    OSVERSIONINFO    OsVersionInfo;
    HANDLE            Process;
    HANDLE            Thread;

    // マルチメディアタイマーとやらを起動します。
    TimerID    = timeSetEvent( 1, 1, TimerProc, 0, TIME_PERIODIC );

    // 自分のスレッドハンドルを取得します。
    Process    = GetCurrentProcess( );
    Thread    = GetCurrentThread( );
    DuplicateHandle( Process, Thread, Process, &TimerHandle, 0, FALSE, DUPLICATE_SAME_ACCESS );
}
//--------------------------------------
BOOL TimerRelease( void )
{
    timeKillEvent( TimerID );
    CloseHandle( TimerHandle );
    return TRUE;
}
//--------------------------------------
void TimerSleep( DWORD Wait )
{
#if 0    // セーフティ?
    if( Wait < 2 )
        Wait    = 2;
#endif

    TimerWait    = Wait;
    SuspendThread( TimerHandle );
}
//--------------------------------------
void main( void )
{
    LARGE_INTEGER    Frequency;
    int                i;
    double            Value;
    DWORD            List[LIST_MAX];
    LARGE_INTEGER    PerformanceCount;

    QueryPerformanceFrequency( &Frequency );
    Value    = ( double )Frequency.QuadPart / 1000.0;
    TimerInitial( );

    for( i = 0 ; i < LIST_MAX ; i++ )
    {
        TimerSleep( WAIT_TIME );

        QueryPerformanceCounter( &PerformanceCount );
        List[i]    = ( DWORD )( PerformanceCount.QuadPart / Value );
    }

    TimerRelease( );
    for( i = 0 ; i < LIST_MAX - 1 ; i++ )
        printf( "%4d\n", List[i + 1] - List[i] );
}

一応、らしく動くのですが…。

一つ大きな落とし穴が…。

それは!!

To Be Continued!

…。

嘘です。

やってみたかっただけです…。

実は…

「TimerSleep」の中身に問題が…。

メインの処理が重くなった時に…
たまたま…
「TimerWait」に1をセットした直後に
「TimerProc」が割り込むと
処理が破綻しちゃいます…。

「TimerWait」をセットした直後にタイマースレッドを
立ち上げるのも考えたんですが…。
(※あんまりお勧めできない方法ですが…。)

処理の設定のためか最初の400回ぐらいは、
ノーウエイトで実行されてしまいます…。
と言うことで、タイミングが安定しません。

それもこれも、「TimerWait」に1を
設定するのが問題なのです!
つまり「TimerWait」に「2」以上を
セットすればOKなのです!

と言う訳でセーフティを付けて解決!

…と言うことにしよう!

では、お休みなさい…。

|

« 自民大躍進! | トップページ | なんとなくプラモデルメイク!(ケロロ軍曹の場合…) »

コメント

コメントを書く



(ウェブ上には掲載しません)




トラックバック


この記事へのトラックバック一覧です: 「Sleep」の代替え処理は…:

« 自民大躍進! | トップページ | なんとなくプラモデルメイク!(ケロロ軍曹の場合…) »