реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> порт х86, rdtsc
Drozd2
сообщение Mar 30 2016, 18:27
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 97
Регистрация: 19-11-09
Пользователь №: 53 743



Использую порт MSVC-MingW. Пытаюсь приподнять точность таймера с помощью функции rdtsc вместо Sleep. Текст оригинальный, только закомментированы Sleep в бесконечном цикле и добавлен вызов wait_ms.

CODE
void wait_ms(unsigned long ms)
{
unsigned long long t2 = _rdtsc() + (unsigned long long)ms * 3000000;
while (_rdtsc() < t2);
}


/*-----------------------------------------------------------*/

static DWORD WINAPI prvSimulatedPeripheralTimer( LPVOID lpParameter )
{
TickType_t xMinimumWindowsBlockTime;
TIMECAPS xTimeCaps;

/* Set the timer resolution to the maximum possible. */
if( timeGetDevCaps( &xTimeCaps, sizeof( xTimeCaps ) ) == MMSYSERR_NOERROR )
{
xMinimumWindowsBlockTime = ( TickType_t ) xTimeCaps.wPeriodMin;
timeBeginPeriod( xTimeCaps.wPeriodMin );

/* Register an exit handler so the timeBeginPeriod() function can be
matched with a timeEndPeriod() when the application exits. */
SetConsoleCtrlHandler( prvEndProcess, TRUE );
}
else
{
xMinimumWindowsBlockTime = ( TickType_t ) 20;
}

/* Just to prevent compiler warnings. */
( void ) lpParameter;
//Sleep(1);

for( ;; )
{
/* Wait until the timer expires and we can access the simulated interrupt
variables. *NOTE* this is not a 'real time' way of generating tick
events as the next wake time should be relative to the previous wake
time, not the time that Sleep() is called. It is done this way to
prevent overruns in this very non real time simulated/emulated
environment. */
/*if( portTICK_PERIOD_MS < xMinimumWindowsBlockTime )
{
Sleep( xMinimumWindowsBlockTime );
}
else
{
Sleep( portTICK_PERIOD_MS );
}*/
wait_ms(portTICK_PERIOD_MS);

configASSERT( xPortRunning );

WaitForSingleObject( pvInterruptEventMutex, INFINITE );

/* The timer has expired, generate the simulated tick event. */
ulPendingInterrupts |= ( 1 << portINTERRUPT_TICK );

/* The interrupt is now pending - notify the simulated interrupt
handler thread. */
if( ulCriticalNesting == 0 )
{
SetEvent( pvInterruptEvent );
}

/* Give back the mutex so the simulated interrupt handler unblocks
and can access the interrupt handler variables. */
ReleaseMutex( pvInterruptEventMutex );
}

#ifdef __GNUC__
/* Should never reach here - MingW complains if you leave this line out,
MSVC complains if you put it in. */
return 0;
#endif
}


Программа зависает намертво. Причем если в wait_ms добавить Sleep, то начинает работать. Или хотя бы закомментированный Sleep перед for(;;) раскомментировать, то один раз выводится Task 1 is running. И тоже зависает. Как починить?

Сообщение отредактировал Drozd2 - Mar 30 2016, 18:40
Go to the top of the page
 
+Quote Post
Drozd2
сообщение Mar 31 2016, 12:01
Сообщение #2


Частый гость
**

Группа: Участник
Сообщений: 97
Регистрация: 19-11-09
Пользователь №: 53 743



Изучение матчасти помогло. Так работает:

Код
void wait_ms(unsigned long ms)
{
    unsigned long long t2 = _rdtsc() + (unsigned long long)ms * 3000000;
    while (_rdtsc() < t2)
        Sleep(0);
}


Только ускорения не вышло.
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 4th September 2025 - 07:55
Рейтинг@Mail.ru


Страница сгенерированна за 0.03635 секунд с 7
ELECTRONIX ©2004-2016