00001 #define QOS_DEBUG_LEVEL QOS_LEVEL_DEBUG
00002 #include <linux/aquosa/qos_debug.h>
00003 #include <aquosa/qres_lib.h>
00004
00005 #include <assert.h>
00006 #include <unistd.h>
00007 #include <stdio.h>
00008 #include <sys/time.h>
00009 #include <math.h>
00010 #include <pthread.h>
00011
00013 #define ORIG_Q 20000L
00014 #define ORIG_P 100000L
00015
00018 static double target_ratios[] = {
00019 0.5, 0.3, 0.1
00020 };
00021
00023 #define RATIO_TOLERANCE 0.15
00024
00027 long count_and_wait() {
00028 unsigned long counted_sheeps = 0;
00029 unsigned long elapsed_usecs;
00030 struct timeval tv1, tv2;
00031
00032 qos_log_debug("Counting sheeps for 2 seconds ...");
00033 gettimeofday(&tv1, NULL);
00034 do {
00035 gettimeofday(&tv2, NULL);
00036 elapsed_usecs = tv2.tv_usec - tv1.tv_usec + (tv2.tv_sec - tv1.tv_sec) * 1000000;
00037 counted_sheeps++;
00038 } while (elapsed_usecs < 2000000);
00039 qos_log_debug("Counted %lu sheeps in 2 seconds", counted_sheeps);
00040 return counted_sheeps;
00041 }
00042
00043 void *main_loop(void *ptr) {
00044 int i;
00045 int rv = 0;
00046 unsigned long long cnt1, cnt2;
00047 qres_sid_t sid;
00048
00049 qres_params_t *params = (qres_params_t *) ptr;
00050
00051 qos_log_debug("Creating QRES Server with Q=" QRES_TIME_FMT
00052 ", P=" QRES_TIME_FMT, params->Q, params->P);
00053 qos_chk_ok_exit(qres_create_server(params, &sid));
00054 qos_chk_ok_exit(qres_attach_thread(sid, 0, 0));
00055
00056 cnt1 = count_and_wait();
00057
00058 for (i = 0; i < (int) (sizeof(target_ratios) / sizeof(*target_ratios)); i++) {
00059 double target_ratio = target_ratios[i];
00060 double cnt2_exp, reldiff;
00061 params->Q = (qres_time_t) ((double) ORIG_Q * target_ratio);
00062 qos_log_debug("Changing QRES Parameters to Q=" QRES_TIME_FMT
00063 ", P=" QRES_TIME_FMT, params->Q, params->P);
00064 qos_chk_ok_exit(qres_set_params(sid, params));
00065
00066 cnt2_exp = target_ratio * cnt1;
00067 cnt2 = count_and_wait();
00068
00069 reldiff = (((double) cnt2) - cnt2_exp) / cnt2_exp;
00070 qos_log_debug("%d: reldiff=%02.2g%% / 100.00%%", i, reldiff*100);
00071 if (fabs(reldiff) > RATIO_TOLERANCE) {
00072 qos_log_err("Expecting to count %g while counted %llu (reldiff=%g)",
00073 cnt2_exp, cnt2, reldiff);
00074 qos_log_err("This is outside defined tolerance of %g",
00075 RATIO_TOLERANCE);
00076 rv = -1;
00077 }
00078 }
00079
00080 qos_log_debug("Destroying QRES Server");
00081 qos_chk_ok_exit(qres_destroy_server(sid));
00082
00083 pthread_exit((void *) (intptr_t) rv);
00084 }
00085
00086 qres_params_t params = {
00087 .Q = ORIG_Q,
00088 .Q_min = 0,
00089 .P = ORIG_P,
00090 .flags = 0,
00091 };
00092
00093 int main() {
00094 int rv = 0;
00095
00096 qos_log_debug("Initializing qres library");
00097 qos_chk_ok_exit(qres_init());
00098
00099 pthread_t child_tid;
00100 void *child_rv;
00101 qos_chk_exit(pthread_create(&child_tid, NULL, main_loop, (void *) ¶ms) == 0);
00102
00103 main_loop(¶ms);
00104
00105 pthread_join(child_tid, &child_rv);
00106
00107 qos_log_debug("Finalizing QRES library");
00108 qos_chk_ok_exit(qres_cleanup());
00109
00110
00111 return rv | (int) (long) child_rv;
00112 }