cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

mqueue-lat.c (2642B)


      1/* Measure mqueue timeout latency
      2 *              by: john stultz (john.stultz@linaro.org)
      3 *		(C) Copyright Linaro 2013
      4 *
      5 *		Inspired with permission from example test by:
      6 *			Romain Francoise <romain@orebokech.com>
      7 *              Licensed under the GPLv2
      8 *
      9 *  To build:
     10 *	$ gcc mqueue-lat.c -o mqueue-lat -lrt
     11 *
     12 *   This program is free software: you can redistribute it and/or modify
     13 *   it under the terms of the GNU General Public License as published by
     14 *   the Free Software Foundation, either version 2 of the License, or
     15 *   (at your option) any later version.
     16 *
     17 *   This program is distributed in the hope that it will be useful,
     18 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
     19 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     20 *   GNU General Public License for more details.
     21 */
     22
     23#include <stdio.h>
     24#include <stdlib.h>
     25#include <time.h>
     26#include <sys/time.h>
     27#include <sys/timex.h>
     28#include <string.h>
     29#include <signal.h>
     30#include <errno.h>
     31#include <mqueue.h>
     32#include "../kselftest.h"
     33
     34#define NSEC_PER_SEC 1000000000ULL
     35
     36#define TARGET_TIMEOUT		100000000	/* 100ms in nanoseconds */
     37#define UNRESONABLE_LATENCY	40000000	/* 40ms in nanosecs */
     38
     39
     40long long timespec_sub(struct timespec a, struct timespec b)
     41{
     42	long long ret = NSEC_PER_SEC * b.tv_sec + b.tv_nsec;
     43
     44	ret -= NSEC_PER_SEC * a.tv_sec + a.tv_nsec;
     45	return ret;
     46}
     47
     48struct timespec timespec_add(struct timespec ts, unsigned long long ns)
     49{
     50	ts.tv_nsec += ns;
     51	while (ts.tv_nsec >= NSEC_PER_SEC) {
     52		ts.tv_nsec -= NSEC_PER_SEC;
     53		ts.tv_sec++;
     54	}
     55	return ts;
     56}
     57
     58int mqueue_lat_test(void)
     59{
     60
     61	mqd_t q;
     62	struct mq_attr attr;
     63	struct timespec start, end, now, target;
     64	int i, count, ret;
     65
     66	q = mq_open("/foo", O_CREAT | O_RDONLY, 0666, NULL);
     67	if (q < 0) {
     68		perror("mq_open");
     69		return -1;
     70	}
     71	mq_getattr(q, &attr);
     72
     73
     74	count = 100;
     75	clock_gettime(CLOCK_MONOTONIC, &start);
     76
     77	for (i = 0; i < count; i++) {
     78		char buf[attr.mq_msgsize];
     79
     80		clock_gettime(CLOCK_REALTIME, &now);
     81		target = now;
     82		target = timespec_add(now, TARGET_TIMEOUT); /* 100ms */
     83
     84		ret = mq_timedreceive(q, buf, sizeof(buf), NULL, &target);
     85		if (ret < 0 && errno != ETIMEDOUT) {
     86			perror("mq_timedreceive");
     87			return -1;
     88		}
     89	}
     90	clock_gettime(CLOCK_MONOTONIC, &end);
     91
     92	mq_close(q);
     93
     94	if ((timespec_sub(start, end)/count) > TARGET_TIMEOUT + UNRESONABLE_LATENCY)
     95		return -1;
     96
     97	return 0;
     98}
     99
    100int main(int argc, char **argv)
    101{
    102	int ret;
    103
    104	printf("Mqueue latency :                          ");
    105	fflush(stdout);
    106
    107	ret = mqueue_lat_test();
    108	if (ret < 0) {
    109		printf("[FAILED]\n");
    110		return ksft_exit_fail();
    111	}
    112	printf("[OK]\n");
    113	return ksft_exit_pass();
    114}