static void switch_log(char* file, FILE **f, int32_t (*pfinit)(void)) { if(cfg.max_log_size && file) //only 1 thread needs to switch the log; even if anticasc, statistics and normal log are running //at the same time, it is ok to have the other logs switching 1 entry later { if(*f != NULL && ftell(*f) >= cfg.max_log_size*1024) { int32_t rc; char prev_log[strlen(file) + 6]; snprintf(prev_log, sizeof(prev_log), "%s-prev", file); fprintf(*f, "switch log file\n"); fflush(*f); fclose(*f); *f = (FILE *)0; rc = rename(file, prev_log); if( rc!=0 ) { fprintf(stderr, "rename(%s, %s) failed (errno=%d %s)\n", file, prev_log, errno, strerror(errno)); } else if( pfinit()){ fprintf(stderr, "Initialisation of log file failed, continuing without logging thread %8X. Log will be output to stdout!", (unsigned int)pthread_self()); cfg.logtostdout = 1; } } } }
void gameoflife() { DEBUG_BYTE(0,0); // set debug bytes to zero DEBUG_BYTE(1,0); field_t pf1, pf2; field_t ldbuf[LOOP_DETECT_BUFFER_SIZE] = {{{0}}}; // loop detect buffer uint8_t ldbuf_idx = 0; uint16_t cycle; #ifdef GLIDER_TEST /* initialize with glider */ coord_t x,y; for(y = YSIZE; y--;) { for(x = XSIZE; x--;) { setcell(pf1, x, y, dead); } } insertglider(pf1); #else /* initialize the field with random */ pfinit(pf1); #endif /* the main part */ pfprint(pf1); for (cycle = 1; cycle < GOL_CYCLES; ++cycle) { DEBUG_BYTE(0, (uint8_t)(GOL_CYCLES-cycle) & 0xff); DEBUG_BYTE(1, SREG); wait(GOL_DELAY); pfcopy(pf2, pf1); nextiteration(pf1, pf2); pfprint(pf1); /* loop detection */ if (!pfcmp(pf1, pf2)) { insertglider(pf1); // cycle = 1; } if (pfempty(pf1)) { /* kill game */ return; } /* */ uint8_t i; for (i = 0; i < LOOP_DETECT_BUFFER_SIZE; ++i) { if (!pfcmp(pf1, ldbuf[i])) { insertglider(pf1); // cycle = 1; } } pfcopy(ldbuf[ldbuf_idx], pf1); ldbuf_idx = (ldbuf_idx + 1u) % LOOP_DETECT_BUFFER_SIZE; } }