0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023 #include <stdio.h>
0024 #include <stdlib.h>
0025 #include <time.h>
0026 #include <sys/time.h>
0027 #include <sys/timex.h>
0028 #include <string.h>
0029 #include <signal.h>
0030 #include <errno.h>
0031 #include <mqueue.h>
0032 #include "../kselftest.h"
0033
0034 #define NSEC_PER_SEC 1000000000ULL
0035
0036 #define TARGET_TIMEOUT 100000000
0037 #define UNRESONABLE_LATENCY 40000000
0038
0039
0040 long long timespec_sub(struct timespec a, struct timespec b)
0041 {
0042 long long ret = NSEC_PER_SEC * b.tv_sec + b.tv_nsec;
0043
0044 ret -= NSEC_PER_SEC * a.tv_sec + a.tv_nsec;
0045 return ret;
0046 }
0047
0048 struct timespec timespec_add(struct timespec ts, unsigned long long ns)
0049 {
0050 ts.tv_nsec += ns;
0051 while (ts.tv_nsec >= NSEC_PER_SEC) {
0052 ts.tv_nsec -= NSEC_PER_SEC;
0053 ts.tv_sec++;
0054 }
0055 return ts;
0056 }
0057
0058 int mqueue_lat_test(void)
0059 {
0060
0061 mqd_t q;
0062 struct mq_attr attr;
0063 struct timespec start, end, now, target;
0064 int i, count, ret;
0065
0066 q = mq_open("/foo", O_CREAT | O_RDONLY, 0666, NULL);
0067 if (q < 0) {
0068 perror("mq_open");
0069 return -1;
0070 }
0071 mq_getattr(q, &attr);
0072
0073
0074 count = 100;
0075 clock_gettime(CLOCK_MONOTONIC, &start);
0076
0077 for (i = 0; i < count; i++) {
0078 char buf[attr.mq_msgsize];
0079
0080 clock_gettime(CLOCK_REALTIME, &now);
0081 target = now;
0082 target = timespec_add(now, TARGET_TIMEOUT);
0083
0084 ret = mq_timedreceive(q, buf, sizeof(buf), NULL, &target);
0085 if (ret < 0 && errno != ETIMEDOUT) {
0086 perror("mq_timedreceive");
0087 return -1;
0088 }
0089 }
0090 clock_gettime(CLOCK_MONOTONIC, &end);
0091
0092 mq_close(q);
0093
0094 if ((timespec_sub(start, end)/count) > TARGET_TIMEOUT + UNRESONABLE_LATENCY)
0095 return -1;
0096
0097 return 0;
0098 }
0099
0100 int main(int argc, char **argv)
0101 {
0102 int ret;
0103
0104 printf("Mqueue latency : ");
0105 fflush(stdout);
0106
0107 ret = mqueue_lat_test();
0108 if (ret < 0) {
0109 printf("[FAILED]\n");
0110 return ksft_exit_fail();
0111 }
0112 printf("[OK]\n");
0113 return ksft_exit_pass();
0114 }