| 1411 | } |
| 1412 | |
| 1413 | static bool run_bench(const test_t *test, const uint32_t cnt) |
| 1414 | { |
| 1415 | uint32_t i; |
| 1416 | bool ret = true; |
| 1417 | uint64_t ucycles, kcycles; |
| 1418 | char usuffix, ksuffix; |
| 1419 | |
| 1420 | if (cnt < 1) |
| 1421 | return true; |
| 1422 | |
| 1423 | uint64_t *data = (uint64_t *) malloc(sizeof(uint64_t) * cnt); |
| 1424 | if (data == NULL) { |
| 1425 | printf("Error allocating memory for statistics\n"); |
| 1426 | return false; |
| 1427 | } |
| 1428 | |
| 1429 | for (i = 0; i < cnt; i++) { |
| 1430 | printf("%s (%u/%u) ... ", test->name, i + 1, cnt); |
| 1431 | |
| 1432 | /* |
| 1433 | * Update and read thread accounting |
| 1434 | * for benchmarking |
| 1435 | */ |
| 1436 | irq_spinlock_lock(&TASK->lock, true); |
| 1437 | uint64_t ucycles0, kcycles0; |
| 1438 | task_get_accounting(TASK, &ucycles0, &kcycles0); |
| 1439 | irq_spinlock_unlock(&TASK->lock, true); |
| 1440 | |
| 1441 | /* Execute the test */ |
| 1442 | test_quiet = true; |
| 1443 | const char *test_ret = test->entry(); |
| 1444 | |
| 1445 | /* Update and read thread accounting */ |
| 1446 | irq_spinlock_lock(&TASK->lock, true); |
| 1447 | uint64_t ucycles1, kcycles1; |
| 1448 | task_get_accounting(TASK, &ucycles1, &kcycles1); |
| 1449 | irq_spinlock_unlock(&TASK->lock, true); |
| 1450 | |
| 1451 | if (test_ret != NULL) { |
| 1452 | printf("%s\n", test_ret); |
| 1453 | ret = false; |
| 1454 | break; |
| 1455 | } |
| 1456 | |
| 1457 | data[i] = ucycles1 - ucycles0 + kcycles1 - kcycles0; |
| 1458 | order_suffix(ucycles1 - ucycles0, &ucycles, &usuffix); |
| 1459 | order_suffix(kcycles1 - kcycles0, &kcycles, &ksuffix); |
| 1460 | printf("OK (%" PRIu64 "%c user cycles, %" PRIu64 "%c kernel cycles)\n", |
| 1461 | ucycles, usuffix, kcycles, ksuffix); |
| 1462 | } |
| 1463 | |
| 1464 | if (ret) { |
| 1465 | printf("\n"); |
| 1466 | |
| 1467 | uint64_t sum = 0; |
| 1468 | |
| 1469 | for (i = 0; i < cnt; i++) { |
| 1470 | sum += data[i]; |
no test coverage detected