void sanity_checks() { NBDEBUG("sanity_checks()...\n"); NBLassert(control::control_connected == 1); NBLassert(control::fileio == 2); NBLassert(!log_running); //... /* SExpr aString("thisstring"); printf("%s\n", aString.serialize().c_str()); */ NBDEBUG("sane.\n"); }
void log_serverio_init() { NBDEBUG("log_serverio_init()\n"); NBLassert(!STARTED); STARTED = true; pthread_create(&(log_main.log_serverio_thread), NULL, &server_io_loop, NULL); pthread_detach(log_main.log_serverio_thread); }
void releaseWrapper(int bi, Log * lg, bool lock) { NBLassert(bi >= 0 && bi < NUM_LOG_BUFFERS); NBLassert(lg); if (lock) pthread_mutex_lock(&(log_main.buffers[bi].lock)); if (lg->release()) { total[bi].l_freed += 1; if (!lg->written()) { total[bi].l_lost += 1; total[bi].b_lost += lg->fullSize(); } --nlog_assoc[bi]; NBLassert(nlog_assoc[bi] >= 0); delete lg; } if (lock) pthread_mutex_unlock(&(log_main.buffers[bi].lock)); }
void NBLog(int buffer_index, Log * log) { NBDEBUGs(SECTION_LOGM, "NBlog(buffer_index=%i)\n", buffer_index); NBLassert(buffer_index < NUM_LOG_BUFFERS); //Can't log if the server's not running... if (!log_running) { NBDEBUG("NBlog returning because !log_running\n"); delete log; return; } if (buffer_index >= NUM_LOG_BUFFERS || buffer_index < 0) { printf("ERROR: NBlog(...) called with INVALID buffer index! Deleting log and returning...\n"); delete log; return; } pthread_mutex_lock(&(log_main.buffers[buffer_index].lock)); put(log, buffer_index); pthread_mutex_unlock(&(log_main.buffers[buffer_index].lock)); }
void put(Log * nstored, int bi) { NBLassert(nstored); log_buffer_t& buf = log_main.buffers[bi]; NBDEBUGs(SECTION_LOGM, "put(%i):\tfilenr=%i servnr=%i nextw=%i\n", bi, buf.fileio_nextr, buf.servio_nextr, buf.next_write); total[bi].l_given += 1; total[bi].b_given += nstored->fullSize(); nstored->acquire(); //One reference for the buffer. uint32_t old_i = buf.next_write; Log * old = buf.objects[old_i % LOG_BUFFER_SIZES[bi]]; if (old) { releaseWrapper(bi, old, false); } buf.objects[(old_i % LOG_BUFFER_SIZES[bi])] = nstored; /*If IO is very slow, we need to update IO 'next_*' */ //fileio NBLassert(buf.fileio_nextr <= buf.next_write); uint32_t dif = buf.next_write - buf.fileio_nextr; NBLassert(dif <= LOG_BUFFER_SIZES[bi]); if (dif == LOG_BUFFER_SIZES[bi]) { ++(buf.fileio_nextr); } //servio NBLassert(buf.servio_nextr <= buf.next_write); dif = buf.next_write - buf.servio_nextr; NBLassert(dif <= LOG_BUFFER_SIZES[bi]); if (dif == LOG_BUFFER_SIZES[bi]) { ++(buf.servio_nextr); } ++(buf.next_write); ++nlog_assoc[bi]; //1 log could possibly be in the hands of each io. NBLassert(nlog_assoc[bi] <= LOG_BUFFER_SIZES[bi] + 2); NBDEBUGs(SECTION_LOGM, "\t\tfilenr=%i servnr=%i nextw=%i\n", buf.fileio_nextr, buf.servio_nextr, buf.next_write); }
void * log_main_loop(void * context) { log_serverio_init(); log_fileio_init(); log_cnc_init(); bzero(zero_state, sizeof(nbsf::io_state_t) * NUM_LOG_BUFFERS); while (1) { sleep(1); if (nbsf::flags[nbsf::STATS]) { /* We're sending this over the network to a (presumably) java program. So if the compiler puts padding in, it will screw up our parsing. __packed__ *should* prevent the compiler from putting padding/alignment stuff in. But a thought-out size check after is still a good idea. */ struct __attribute__((__packed__)) { uint64_t fio_upstart; uint64_t sio_upstart; uint64_t cio_upstart; uint64_t cnc_upstart; uint64_t main_upstart; nbsf::io_state_t fio_start[NUM_LOG_BUFFERS]; nbsf::io_state_t cio_start[NUM_LOG_BUFFERS]; nbsf::io_state_t total[NUM_LOG_BUFFERS]; nbsf::buf_state_t state[NUM_LOG_BUFFERS]; uint32_t ratio[NUM_LOG_BUFFERS]; uint32_t size[NUM_LOG_BUFFERS]; uint32_t cores; uint8_t flags[nbsf::num_flags]; } contig; // 40 + (3 * n * 40) + (n * 12) + (2 * n * 4) + 4 + (nbsf::num_flags) int packed_size = 40 + (3 * NUM_LOG_BUFFERS * 40) + (NUM_LOG_BUFFERS * 12) + (2 * NUM_LOG_BUFFERS * 4) + 4 + (nbsf::num_flags); NBLassert(sizeof(contig) == packed_size); LOGDEBUG(7, "stat struct size: %i\n", packed_size); const time_t CURRENT = time(NULL); //Copy volatile items as close to simultaneously as possible to minimize drift contig.fio_upstart = nbsf::fio_upstart; contig.sio_upstart = nbsf::sio_upstart; contig.cio_upstart = nbsf::cio_upstart; contig.cnc_upstart = nbsf::cnc_upstart; contig.main_upstart = nbsf::main_upstart; memcpy(contig.fio_start, nbsf::fio_start, sizeof(nbsf::io_state_t) * NUM_LOG_BUFFERS); memcpy(contig.cio_start, nbsf::cio_start, sizeof(nbsf::io_state_t) * NUM_LOG_BUFFERS); memcpy(contig.total, nbsf::total, sizeof(nbsf::io_state_t) * NUM_LOG_BUFFERS); for (int i = 0; i < NUM_LOG_BUFFERS; ++i) { //memcpy(contig.state + i, log_main->buffers[i], sizeof(nbsf::buf_state_t)); log_buffer_t * buf = log_main->buffers[i]; contig.state[i].filenr = buf->fileio_nextr; contig.state[i].servnr = buf->servio_nextr; contig.state[i].nextw = buf->next_write; contig.ratio[i] = LOG_RATIO[i]; contig.size[i] = LOG_BUFFER_SIZES[i]; } memcpy( contig.flags, (uint8_t *) nbsf::flags, nbsf::num_flags); //Set non-volatile items, convert everything to network order. contig.cores = htonl(nbsf::NUM_CORES); if (contig.flags[nbsf::fileio]) { neterize(contig.fio_start, contig.fio_start, contig.total); contig.fio_upstart = net_time(contig.fio_upstart, CURRENT); } else { bzero(contig.fio_start, sizeof(nbsf::io_state_t) * NUM_LOG_BUFFERS); contig.fio_upstart = 0; } if (contig.flags[nbsf::serv_connected]) { neterize(contig.cio_start, contig.cio_start, contig.total); contig.cio_upstart = net_time(contig.cio_upstart, CURRENT); } else { bzero(contig.cio_start, sizeof(nbsf::io_state_t) * NUM_LOG_BUFFERS); contig.cio_upstart = 0; } neterize(contig.total, zero_state, contig.total); for (int i = 0; i < NUM_LOG_BUFFERS; ++i) { LOGDEBUG(6, "\t\tstat(%i): filenr=%i servnr=%i nextw=%i\n", i, contig.state[i].filenr, contig.state[i].servnr, contig.state[i].nextw); contig.state[i].filenr = htonl(contig.state[i].filenr); contig.state[i].servnr = htonl(contig.state[i].servnr); contig.state[i].nextw = htonl(contig.state[i].nextw); contig.size[i] = htonl(contig.size[i]); contig.ratio[i] = htonl(contig.ratio[i]); } contig.sio_upstart = (contig.flags[nbsf::servio]) ? net_time(contig.sio_upstart, CURRENT) : 0; contig.cnc_upstart = (contig.flags[nbsf::cnc_connected]) ? net_time(contig.cnc_upstart, CURRENT) : 0; contig.main_upstart = net_time(contig.main_upstart, CURRENT); char cbuf[100]; snprintf(cbuf, 100, "stats nbuffers=%i", NUM_LOG_BUFFERS); NBlog(NBL_SMALL_BUFFER, 0, clock(), cbuf, packed_size, (uint8_t *) &contig); } }