コード例 #1
0
ファイル: mlog_test.c プロジェクト: github188/grpc
// Tests scenario where block being read is detached from a core and put on the
// dirty list.
void test_detached_while_reading(void) {
  printf("Starting test: detached while reading\n");
  setup_test(0);
  // Start a write.
  static const size_t DWR_RECORD_SIZE = 10;
  void* record_written = census_log_start_write(DWR_RECORD_SIZE);
  GPR_ASSERT(record_written != NULL);
  census_log_end_write(record_written, DWR_RECORD_SIZE);
  // Read this record.
  census_log_init_reader();
  size_t bytes_available;
  const void* record_read = census_log_read_next(&bytes_available);
  GPR_ASSERT(record_read != NULL);
  GPR_ASSERT(DWR_RECORD_SIZE == bytes_available);
  // Now fill the log. This will move the block being read from core-local
  // array to the dirty list.
  while ((record_written = census_log_start_write(DWR_RECORD_SIZE))) {
    census_log_end_write(record_written, DWR_RECORD_SIZE);
  }

  // In this iteration, read_next() should only traverse blocks in the
  // core-local array. Therefore, we expect at most gpr_cpu_num_cores() more
  // blocks. As log is full, if read_next() is traversing the dirty list, we
  // will get more than gpr_cpu_num_cores() blocks.
  int block_read = 0;
  while ((record_read = census_log_read_next(&bytes_available))) {
    ++block_read;
    GPR_ASSERT(block_read <= (int)gpr_cpu_num_cores());
  }
  census_log_shutdown();
}
コード例 #2
0
ファイル: mlog_test.c プロジェクト: github188/grpc
// Tries reading beyond pending write.
void test_read_beyond_pending_record(void) {
  printf("Starting test: read beyond pending record\n");
  setup_test(0);
  // Start a write.
  const size_t incomplete_record_size = 10;
  void* incomplete_record = census_log_start_write(incomplete_record_size);
  GPR_ASSERT(incomplete_record != NULL);
  const size_t complete_record_size = 20;
  void* complete_record = census_log_start_write(complete_record_size);
  GPR_ASSERT(complete_record != NULL);
  GPR_ASSERT(complete_record != incomplete_record);
  census_log_end_write(complete_record, complete_record_size);
  // Now iterate over blocks to read completed records.
  census_log_init_reader();
  size_t bytes_available;
  const void* record_read = census_log_read_next(&bytes_available);
  GPR_ASSERT(complete_record == record_read);
  GPR_ASSERT(complete_record_size == bytes_available);
  // Complete first record.
  census_log_end_write(incomplete_record, incomplete_record_size);
  // Have read past the incomplete record, so read_next() should return NULL.
  // NB: this test also assumes our thread did not get switched to a different
  // CPU between the two start_write calls
  record_read = census_log_read_next(&bytes_available);
  GPR_ASSERT(record_read == NULL);
  // Reset reader to get the newly completed record.
  census_log_init_reader();
  record_read = census_log_read_next(&bytes_available);
  GPR_ASSERT(incomplete_record == record_read);
  GPR_ASSERT(incomplete_record_size == bytes_available);
  assert_log_empty();
  census_log_shutdown();
}
コード例 #3
0
ファイル: mlog_test.c プロジェクト: github188/grpc
void test_performance(void) {
  for (size_t write_size = 1; write_size < CENSUS_LOG_MAX_RECORD_SIZE;
       write_size *= 2) {
    setup_test(0);
    gpr_timespec start_time = gpr_now(GPR_CLOCK_REALTIME);
    int nrecords = 0;
    while (1) {
      void* record = census_log_start_write(write_size);
      if (record == NULL) {
        break;
      }
      census_log_end_write(record, write_size);
      nrecords++;
    }
    gpr_timespec write_time =
        gpr_time_sub(gpr_now(GPR_CLOCK_REALTIME), start_time);
    double write_time_micro =
        (double)write_time.tv_sec * 1000000 + (double)write_time.tv_nsec / 1000;
    census_log_shutdown();
    printf(
        "Wrote %d %d byte records in %.3g microseconds: %g records/us "
        "(%g ns/record), %g gigabytes/s\n",
        nrecords, (int)write_size, write_time_micro,
        nrecords / write_time_micro, 1000 * write_time_micro / nrecords,
        (double)((int)write_size * nrecords) / write_time_micro / 1000);
  }
}
コード例 #4
0
ファイル: census_log_tests.c プロジェクト: An-mol/grpc
/* Tries to write the specified number of records. Stops when the log gets
   full. Returns the number of records written. Spins for random
   number of times, up to 'max_spin_count', between writes. */
static size_t write_records_to_log(int writer_id, int32_t record_size,
                                   int32_t num_records,
                                   int32_t max_spin_count) {
  int32_t ix;
  int counter = 0;
  for (ix = 0; ix < num_records; ++ix) {
    int32_t jx;
    int32_t spin_count = max_spin_count ? rand() % max_spin_count : 0;
    char *record;
    if (counter++ == num_records / 10) {
      printf("   Writer %d: %d out of %d written\n", writer_id, ix,
             num_records);
      counter = 0;
    }
    record = (char *)(census_log_start_write(record_size));
    if (record == NULL) {
      return ix;
    }
    write_record(record, record_size);
    census_log_end_write(record, record_size);
    for (jx = 0; jx < spin_count; ++jx) {
      GPR_ASSERT(jx >= 0);
    }
  }
  return num_records;
}
コード例 #5
0
ファイル: mlog_test.c プロジェクト: github188/grpc
// Attempts to create a record of invalid size (size >
// CENSUS_LOG_MAX_RECORD_SIZE).
void test_invalid_record_size(void) {
  static const size_t INVALID_SIZE = CENSUS_LOG_MAX_RECORD_SIZE + 1;
  static const size_t VALID_SIZE = 1;
  printf("Starting test: invalid record size\n");
  setup_test(0);
  void* record = census_log_start_write(INVALID_SIZE);
  GPR_ASSERT(record == NULL);
  // Now try writing a valid record.
  record = census_log_start_write(VALID_SIZE);
  GPR_ASSERT(record != NULL);
  census_log_end_write(record, VALID_SIZE);
  // Verifies that available space went down by one block. In theory, this
  // check can fail if the thread is context switched to a new CPU during the
  // start_write execution (multiple blocks get allocated), but this has not
  // been observed in practice.
  //  GPR_ASSERT(LOG_SIZE_IN_BYTES - CENSUS_LOG_MAX_RECORD_SIZE ==
  //             census_log_remaining_space());
  census_log_shutdown();
}
コード例 #6
0
ファイル: mlog_test.c プロジェクト: github188/grpc
// Tests end_write() with a different size than what was specified in
// start_write().
void test_end_write_with_different_size(void) {
  static const size_t START_WRITE_SIZE = 10;
  static const size_t END_WRITE_SIZE = 7;
  printf("Starting test: end write with different size\n");
  setup_test(0);
  void* record_written = census_log_start_write(START_WRITE_SIZE);
  GPR_ASSERT(record_written != NULL);
  census_log_end_write(record_written, END_WRITE_SIZE);
  census_log_init_reader();
  size_t bytes_available;
  const void* record_read = census_log_read_next(&bytes_available);
  GPR_ASSERT(record_written == record_read);
  GPR_ASSERT(END_WRITE_SIZE == bytes_available);
  assert_log_empty();
  census_log_shutdown();
}
コード例 #7
0
ファイル: mlog_test.c プロジェクト: github188/grpc
// Tries to write the specified number of records. Stops when the log gets
// full. Returns the number of records written. Spins for random
// number of times, up to 'max_spin_count', between writes.
static int write_records_to_log(int writer_id, size_t record_size,
                                int num_records, int max_spin_count) {
  int counter = 0;
  for (int i = 0; i < num_records; ++i) {
    int spin_count = max_spin_count ? rand() % max_spin_count : 0;
    if (VERBOSE && (counter++ == num_records / 10)) {
      printf("   Writer %d: %d out of %d written\n", writer_id, i, num_records);
      counter = 0;
    }
    char* record = (char*)(census_log_start_write(record_size));
    if (record == NULL) {
      return i;
    }
    write_record(record, record_size);
    census_log_end_write(record, record_size);
    for (int j = 0; j < spin_count; ++j) {
      GPR_ASSERT(j >= 0);
    }
  }
  return num_records;
}
コード例 #8
0
ファイル: mlog_test.c プロジェクト: github188/grpc
// Verifies that pending records are not available via read_next().
void test_read_pending_record(void) {
  static const size_t PR_RECORD_SIZE = 1024;
  printf("Starting test: read pending record\n");
  setup_test(0);
  // Start a write.
  void* record_written = census_log_start_write(PR_RECORD_SIZE);
  GPR_ASSERT(record_written != NULL);
  // As write is pending, read should fail.
  census_log_init_reader();
  size_t bytes_available;
  const void* record_read = census_log_read_next(&bytes_available);
  GPR_ASSERT(record_read == NULL);
  // A read followed by end_write() should succeed.
  census_log_end_write(record_written, PR_RECORD_SIZE);
  census_log_init_reader();
  record_read = census_log_read_next(&bytes_available);
  GPR_ASSERT(record_written == record_read);
  GPR_ASSERT(PR_RECORD_SIZE == bytes_available);
  assert_log_empty();
  census_log_shutdown();
}