int main() {
 TEST_STRT(2);
 TEST_DIAG("This test may fail due to an unavoidable race condition");
 int f = fork();
 if (f < 0) {
   TEST_EXIT("Fork failed");
 } else if (f == 0) {
   TEST_FINI("child"); /* success 1 */
 } else {
   sleep(20);
   TEST_FINI("parent"); /* success 2 */
 }
 exit();
}
int main() {
  int i, pid;
  void *s;
  int guard = 1;
  TEST_STRT(1);
  TEST_DIAG("WARNING: this test will fail if run with more than two existing processes");
  int parent_pid = getpid();
  pid = fork();
  TEST_EXIT_IF(pid < 0, "Fork failed.\n");
  if (pid == 0) {
     for(i = 0; i < LOTS; i++) {
        TEST_DIAG("spawned %d", i + 5);
        TEST_EXIT_IF((s = malloc(STKSIZE)) == 0, "oom");
        s += STKSIZE;
        TEST_EXIT_IF(tspawn(s, spawnee, (void *) parent_pid) < 0, 
          "spawn fail before full at i=%d", i);
     }
     // inherently racy - if mkrun happens before desch, we'll never wake up
     // not too likely, esp since every thread is yielding to the parent
     mkrun(parent_pid);
     while(1);
  }
  desch(&guard);
  TEST_EXIT_IF(fork() > 0, "Fork succeeded even though there were no "
    "more threads available.");
  kill(pid);
  wait();
  TEST_FINI();
  exit();
}
int
main(void)
{
  TEST_STRT(1);
  TEST_FINI("no panics on boot, shell, or fork/exec. Good job!");

  exit();
}
void
thread_func(void *a)
{
  desch(&guard); // sleeps here because guard is always non-zero

  TEST_FAIL_IF(!has_mkran[(int) a], "came out of desch before mkrun");
  TEST_FINI("iteration %d", (int) a);
  texit();
}
int main() {
    TEST_STRT(2);
    int i;
    int parent_tid = gettid();
    int f = fork();
    if (f < 0) {
        TEST_EXIT("Fork failed");
    } else if (f == 0) {
        for (i = 0; i < 1000; i++) {
            yield(parent_tid);
        }
        TEST_FINI("child"); /* success 1 */
    } else {
        for (i = 0; i < 1000; i++) {
            yield(f);
        }
        TEST_FINI("parent"); /* success 2 */
    }
    exit();
}
int main() {
  TEST_STRT(1);

  if(fork() == 0) {
    sleep(10); //Make sure the parent made it to wait();
    texit();
  } else {
    wait();
    TEST_FINI();
  }
  exit();
}
int main() {
  int i;
  void *s;
  TEST_STRT(1);
  for (i = 0; i < 10; i++) {
    TEST_EXIT_IF((s = malloc(STKSIZE)) == 0, "oom");
    s += STKSIZE;
    if (i == 0) {
      TEST_EXIT_IF(tspawn(s, baddie, ARG) < 0, 
        "spawn fail at %d", i);
    } else {
      TEST_EXIT_IF(tspawn(s, goodie, ARG) < 0, "spawn fail at %d", i);
    }
    sleep(10);
  }
  TEST_DIAG("You can see the thread being killed well"\
  " before this test finishes.");
  TEST_FINI();
  exit();
}
Exemplo n.º 8
0
int main(void)
{
    plan_tests(1);

    if (getenv("SHF_PERFORMANCE_TEST_ENABLE") && atoi(getenv("SHF_PERFORMANCE_TEST_ENABLE"))) {
    }
    else {
        fprintf(stderr, "NOTE: prefix make with SHF_PERFORMANCE_TEST_ENABLE=1 ?\n");
        goto EARLY_EXIT;
    }

    uint32_t cpu_count_desired = getenv("SHF_PERFORMANCE_TEST_CPUS") ? atoi(getenv("SHF_PERFORMANCE_TEST_CPUS")) : 0;
    uint32_t test_keys_desired = getenv("SHF_PERFORMANCE_TEST_KEYS") ? atoi(getenv("SHF_PERFORMANCE_TEST_KEYS")) : 0;

    TEST_INIT();

#define TEST_MAX_PROCESSES (16)

#ifdef TEST_LMDB
             uint32_t   test_keys_default = 100 * 1000000; /* assume enough RAM is available for LMDB */
#else
             uint64_t   vfs_available_md  = shf_get_vfs_available(shf) / 1024 / 1024;
             uint32_t   test_keys_10m     = vfs_available_md / 436 * 10; /* 10M keys is about 436MB */
             uint32_t   test_keys_default = test_keys_10m > 100 ? 100 * 1000000 : test_keys_10m * 1000000; SHF_ASSERT(test_keys_default > 0, "ERROR: only %luMB available on /dev/shm but 10M keys takes at least 436MB for SharedHashFile", vfs_available_md);
#endif
             uint32_t   test_keys         = test_keys_desired ? test_keys_desired : test_keys_default;
             uint32_t   cpu_count         = cpu_count_desired ? cpu_count_desired : test_get_cpu_count();
             uint32_t   process;
             uint32_t   processes = cpu_count > TEST_MAX_PROCESSES ? TEST_MAX_PROCESSES : cpu_count;
             uint32_t   counts_old[TEST_MAX_PROCESSES] = { 0 };
    volatile uint32_t * put_counts = mmap(NULL, SHF_MOD_PAGE(TEST_MAX_PROCESSES*sizeof(uint32_t)), PROT_READ|PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED | MAP_NORESERVE, -1, 0); SHF_ASSERT(MAP_FAILED != put_counts, "mmap(): %u: ", errno);
    volatile uint32_t * get_counts = mmap(NULL, SHF_MOD_PAGE(TEST_MAX_PROCESSES*sizeof(uint32_t)), PROT_READ|PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED | MAP_NORESERVE, -1, 0); SHF_ASSERT(MAP_FAILED != get_counts, "mmap(): %u: ", errno);
    volatile uint32_t * mix_counts = mmap(NULL, SHF_MOD_PAGE(TEST_MAX_PROCESSES*sizeof(uint32_t)), PROT_READ|PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED | MAP_NORESERVE, -1, 0); SHF_ASSERT(MAP_FAILED != mix_counts, "mmap(): %u: ", errno);
    volatile uint64_t * start_line = mmap(NULL, SHF_MOD_PAGE(                 3*sizeof(uint64_t)), PROT_READ|PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED | MAP_NORESERVE, -1, 0); SHF_ASSERT(MAP_FAILED != mix_counts, "mmap(): %u: ", errno);
    SHF_ASSERT(sizeof(uint64_t) == sizeof(long), "INTERNAL: expected sizeof(uint64_t) == sizeof(long), but got %lu == %lu", sizeof(uint64_t), sizeof(long));
    start_line[0] = 0;
    start_line[1] = 0;
    start_line[2] = 0;
    for (process = 0; process < processes; process++) {
        pid_t fork_pid = fork();
        if (fork_pid == 0) {     /*child*/
            SHF_DEBUG("test process #%u with pid %5u\n", process, getpid());
            {
                long previous_long_value;
                SHF_UNUSE(previous_long_value);

                previous_long_value = InterlockedExchangeAdd((long volatile *) &start_line[0], 1);
                while (processes != start_line[0]) { SHF_YIELD(); }
                TEST_INIT_CHILD();
                for (uint32_t i = 0; i < (1 + (test_keys / processes)); i++) {
                    uint32_t key = test_keys / processes * process + i;
                    put_counts[process] ++;
                    TEST_PUT();
                }
                TEST_PUT_POST();
                TEST_MIX_PRE();
                usleep(2000000); /* 2 seconds */
                previous_long_value = InterlockedExchangeAdd((long volatile *) &start_line[1], 1);
                while (processes != start_line[1]) { SHF_YIELD(); }
                for (uint32_t i = 0; i < (1 + (test_keys / processes)); i++) {
                    uint32_t key = test_keys / processes * process + i;
                    TEST_MIX();
                }
                TEST_MIX_POST();
                TEST_GET_PRE();
                usleep(2000000); /* 2 seconds */
                previous_long_value = InterlockedExchangeAdd((long volatile *) &start_line[2], 1);
                while (processes != start_line[2]) { SHF_YIELD(); }
                for (uint32_t i = 0; i < (1 + (test_keys / processes)); i++) {
                    uint32_t key = test_keys / processes * process + i;
                    TEST_GET();
                }
                TEST_GET_POST();
                TEST_FINI();
                exit(0);
            }
            break;
        }
        else if (fork_pid > 0) { /*parent*/
            /* loop again */
        }
    }

    /* parent monitors & reports on forked children */
    uint32_t seconds            = 0;
    uint32_t key_total;
    uint32_t key_total_old      = 0;
    uint64_t tabs_mmaps_old     = 0;
    uint64_t tabs_mremaps_old   = 0;
    uint64_t tabs_shrunk_old    = 0;
    uint64_t tabs_parted_old    = 0;
    uint32_t message            = 0;
    const char * message_text = "PUT";
#ifdef SHF_DEBUG_VERSION
    uint64_t lock_conflicts_old = 0;
#endif
    char graph_100[] = "----------------------------------------------------------------------------------------------------";
    fprintf(stderr, "perf testing: " TEST_WHAT "\n");
    fprintf(stderr, "running tests on: via command: '%s'\n",               "cat /proc/cpuinfo | egrep 'model name' | head -n 1" );
    fprintf(stderr, "running tests on: `%s`\n"             , shf_backticks("cat /proc/cpuinfo | egrep 'model name' | head -n 1"));
    do {
        if (0 == seconds % 50) {
#ifdef SHF_DEBUG_VERSION
            fprintf(stderr, "-LOCKC ");
#endif
            fprintf(stderr, "-OP MMAP REMAP SHRK PART TOTAL ------PERCENT OPERATIONS PER PROCESS PER SECOND -OPS\n");
#ifdef SHF_DEBUG_VERSION
            fprintf(stderr, "------ ");
#endif
            fprintf(stderr, "--- -k/s --k/s --/s --/s M-OPS 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 -M/s\n");
        }
        seconds ++;
        // todo: add % system CPU time to per second summary line; why does put require so much system?
#ifdef SHF_DEBUG_VERSION
        {
            uint64_t lock_conflicts = 0;
            for (uint32_t win = 0; win < SHF_WINS_PER_SHF; win++) {
                lock_conflicts += shf->shf_mmap->wins[win].lock.conflicts;
            }
            fprintf(stderr, "%6lu ", lock_conflicts - lock_conflicts_old);
            lock_conflicts_old = lock_conflicts;
        }
#endif
        fprintf(stderr, "%s", message_text);
        {
            uint64_t tabs_mmaps   = 0;
            uint64_t tabs_mremaps = 0;
            uint64_t tabs_shrunk  = 0;
            uint64_t tabs_parted  = 0;
#ifdef TEST_SHF
            for (uint32_t win = 0; win < SHF_WINS_PER_SHF; win++) {
                tabs_mmaps   += shf->shf_mmap->wins[win].tabs_mmaps  ;
                tabs_mremaps += shf->shf_mmap->wins[win].tabs_mremaps;
                tabs_shrunk  += shf->shf_mmap->wins[win].tabs_shrunk ;
                tabs_parted  += shf->shf_mmap->wins[win].tabs_parted ;
            }
#endif
            fprintf(stderr, "%5.1f %5.1f %4llu %4llu",
                (tabs_mmaps   - tabs_mmaps_old  ) / 1000.0,
                (tabs_mremaps - tabs_mremaps_old) / 1000.0,
                (tabs_shrunk  - tabs_shrunk_old )         ,
                (tabs_parted  - tabs_parted_old )         );
            tabs_mmaps_old   = tabs_mmaps  ;
            tabs_mremaps_old = tabs_mremaps;
            tabs_shrunk_old  = tabs_shrunk ;
            tabs_parted_old  = tabs_parted ;
        }
        {
            key_total = 0;
            uint32_t key_total_this_second = 0;
            for (process = 0; process < TEST_MAX_PROCESSES; process++) {
                key_total             += put_counts[process] + get_counts[process] + mix_counts[process];
                key_total_this_second += put_counts[process] + get_counts[process] + mix_counts[process] - counts_old[process];
            }
            fprintf(stderr, " %5.1f", key_total / 1000.0 / 1000.0);
            for (process = 0; process < TEST_MAX_PROCESSES; process++) {
                fprintf(stderr, "%3.0f", (put_counts[process] + get_counts[process] + mix_counts[process] - counts_old[process]) * 100.0 / (0 == key_total_this_second ? 1 : key_total_this_second));
                counts_old[process] = put_counts[process] + get_counts[process] + mix_counts[process];
            }
            uint32_t key_total_per_second = key_total - key_total_old;
            fprintf(stderr, "%5.1f %s\n", key_total_per_second / 1000.0 / 1000.0, &graph_100[100 - (key_total_per_second / 750000)]);
            if      (0 == message && key_total >= (1 * test_keys)) { message ++; message_text = "MIX"; }
            else if (1 == message && key_total >= (2 * test_keys)) { message ++; message_text = "GET"; }
            key_total_old = key_total;
        }
        usleep(1000000); /* one second */
    } while (key_total < (3 * test_keys));
    fprintf(stderr, "* MIX is 2%% (%u) del/put, 98%% (%u) get\n", test_keys * 2 / 100, test_keys * 98 / 100);

    TEST_FINI_MASTER();

EARLY_EXIT:;

    ok(1, "test still alive");
    return exit_status();
} /* main() */