int main() { boost::mpi::environment env; boost::mpi::communicator world; if( world.rank() == 0 ) { master_loop(world); } else { slave_loop(world); } }
/* Thread sending gtp commands to one slave machine, and * reading replies. If a slave machine dies, this thread waits * for a connection from another slave. * The large buffers are allocated only once we get a first * connection, to avoid wasting memory if max_slaves is too large. * We do not invalidate the received buffers if a slave disconnects; * they are still useful for other slaves. */ static void * slave_thread(void *arg) { struct slave_state sstate = default_sstate; sstate.thread_id = (long)arg; assert(sstate.slave_sock >= 0); char reply_buf[CMDS_SIZE]; bool resend = false; for (;;) { /* Wait for a connection from any slave. */ struct in_addr client; int conn = open_server_connection(sstate.slave_sock, &client); FILE *f = fdopen(conn, "r+"); if (DEBUGL(2)) { snprintf(reply_buf, sizeof(reply_buf), "new slave, id %d\n", sstate.thread_id); logline(&client, "= ", reply_buf); } if (!is_pachi_slave(f, &client)) continue; if (!resend) slave_state_alloc(&sstate); sstate.client = client; pthread_mutex_lock(&slave_lock); active_slaves++; slave_loop(f, reply_buf, &sstate, resend); assert(active_slaves > 0); active_slaves--; // Unblock main thread if it was waiting for this slave. pthread_cond_signal(&reply_cond); pthread_mutex_unlock(&slave_lock); resend = true; if (DEBUGL(2)) logline(&client, "= ", "lost slave\n"); fclose(f); } }
int main(void) { static unsigned int tmp = 0; SET_OUTPUT(LED_R); SET_OUTPUT(LED_G); SET_OUTPUT(LED_B); RESET_LED(LED_R); RESET_LED(LED_G); RESET_LED(LED_B); #ifdef DCDCCTRL SET_OUTPUT(DCDCCTRL); RESET(DCDCCTRL); #endif battery_state = 0; slave_init(); //uart_init(); timer_init(); mcan_init(); spi_init(); spi_adc_init(); relai_init(); adc_init(); sei(); if( (GPIOR0 & (1<<WDRF)) == (1<<WDRF) ) { status("WDTRST "); } else if( (GPIOR0 & (1<<BORF)) == (1<<BORF) ) { status("BORRST "); } else if( (GPIOR0 & (1<<EXTRF)) == (1<<EXTRF) ) { status("START EX"); } else if( (GPIOR0 & (1<<PORF)) == (1<<PORF) ) { status("START PO"); } else if( (GPIOR0 & (1<<JTRF)) == (1<<JTRF) ) { status("START JT"); } else { status("START "); } WDTCR = (1<<WDCE) | (1<<WDE); WDTCR = (1<<WDE) | (1<<WDP2) | (1<<WDP1) | (1<<WDP0); SET_LED(LED_G); while (1) { __asm__ __volatile__ ("wdr"); if( battery_state & STATE_INTERMEDIATE ) { intermediate_loop(); } else if( battery_state & STATE_TRACTIVE ) { tractive_loop(); } else if( battery_state & STATE_CHARGING ) { charge_loop(); } else if( battery_state & STATE_BALANCING ) { balancing_loop(); } else { // standby mode if( (tmp = mcan_check()) && !(battery_state & STATE_ERROR) ) { switch(tmp) { case CAN_TRACTIVE_ENABLE: // CAN_TRACTIVE_ENABLE == 0x2F0 { if( relai_volt < VCC_RELAI_MIN || vcc_volt < VCC_MIN ) { status("NO VCC"); break; } // enable hv intermediate_init(); dspace_heartbeat = 0; battery_state |= STATE_TRACTIVE; } break; case CAN_CHARGE_ENABLE: // CAN_CHARGE_ENABLE == 0x2FA { if( relai_volt < VCC_RELAI_MIN || vcc_volt < VCC_MIN ) { status("NO VCC"); break; } // start charging intermediate_init(); battery_state |= STATE_CHARGING; } break; case CAN_BALANCING_ENABLE: { balancing_start(); battery_state |= STATE_BALANCING; } break; } } } slave_loop(); mcan_send_loop(); adc_loop(); } return 0; }