Цитата(sensor_ua @ Sep 8 2010, 00:49)

Вот выдрал простой кусочек из реального старинного проекта "выходного дня" - всего-лишь блинк, который пришлось вставлять в программку вместо обычного ожидающего
Жуть :-)
На тредах это было бы просто
Код
while ( timeout--)
{
timeout & 1 ? LED_ON() : LED_OFF();
kernel_sleep(delay);
}
Но речь не столько об этом, сколько о том, что написание и отладка более-менее сложной логики превращается в ад - представьте что у вас там пара десятков состояний, причем переключаемых не по "switch ( g_state )", а по битовым флажкам, условиям нулевости некоторых указателей и так далее. Нет, адекватно перенумеровать их все можно далеко не всегда, да и что толку с того, что если мне надо будет постоянно помнить, что в state1 у меня p_queue должен быть NULL, а в state2 взведен флаг F_NEW_MESSAGE и сброшен F_RESYNC - не проще ли сразу их и проверять? Это раз.
Второе, даже если я успешно построил свою машину с двумя десятками состояний, я не смогу написать код в виде:
Код
void serial_console_thread(void) {
for(;;) {
print("What's your name?");
readline(buf);
print("Hello, "); print(buf);
}
void gui_thread(void)
{
for(;;) {
key = readkey();
if ( key == KEY_RIGHT )
menu_move_right();
....
else
beep(); // wrong key pressed
display_update();
}
}
как это позволила бы сделать система с передачей управления через сохранение контекста (неважно, с вытеснением или без оного - я же могу просто в ключевых местах yield() расставить).
Я буду вынужден _весь_ код, с самого нижнего до самого верхнего уровня порезать кровавыми ножницами на мелкие кусочки в асинхронном стиле и переключать их по тем же флагам, т.е. что-то вроде:
Код
while ( (msg=get_message())!=0 ) {
switch ( msg )
{
case SERIAL_TX_COMPLETE:
case SERIAL_RX_COMPLETE:
console_update(&console, msg);
break;
case DISPLAY_UPDATE_COMPLETE:
...
break;
case KEY_PRESSED:
...
break;
}
}
void console_update(struct console *pc, int msg)
{
switch ( pc->state )
{
case START:
serial_send_async("What's your name?");
pc->state = QUESTION_SENT;
break;
case QUESTION_SENT:
switch ( msg )
{
case SERIAL_TX_COMPLETE:
serial_receive_async(buf);
break;
case SERIAL_RX_COMPLETE:
pc->state = GREETING_SENT;
struct vector v[] = { "Hello, ", buf, "!"};
serial_send_async_vector(v, 3);
break;
}
break;
case GREETING_SENT:
if ( msg == SERIAL_TX_COMPLETE ) pc->state = START;
break;
}
}
Теперь попробуйте вообразить в таком стиле не "Hello, Vasya!", а что-то вроде
SMTP, или, скажем, веб-панель управления... а светодиодами помигать - это не показатель.