1 /*
2 * rand-lognormal.c
3 *
4 * Custom variable implementation that returns Log-Normally distributed random
5 * numbers.
6 *
7 * Author: Santhosh Kumar Koundinya (santhosh@fsl.cs.sunysb.edu)
8 */
9
10 #include <stdio.h>
11 #include "mtwist/mtwist.h"
12 #include "mtwist/randistrs.h"
13 #include "cvar.h"
14 #include "cvar_trace.h"
15 #include "cvar_tokens.h"
16 #include "cvar-lognormal.h"
17
cvar_alloc_handle(const char * cvar_parameters,void * (* cvar_malloc)(size_t size),void (* cvar_free)(void * cvar_ptr))18 void *cvar_alloc_handle(const char *cvar_parameters,
19 void *(*cvar_malloc)(size_t size), void (*cvar_free)(void *cvar_ptr))
20 {
21 cvar_token_t *list_head;;
22 cvar_token_t *t;
23 handle_t handle;
24 handle_t *state = NULL;
25 int ret = 0;
26
27 cvar_trace("entry");
28
29 /* Tokenize parameters supplied by filebench. */
30 list_head = NULL;
31 ret = tokenize(cvar_parameters, DEFAULT_PARAMETER_DELIMITER,
32 DEFAULT_KEY_VALUE_DELIMITER, &list_head);
33 if (ret)
34 goto out;
35
36 /* Get the value of shape and scale. */
37 t = find_token(list_head, RLN_SHAPE);
38 if (t && t->value) {
39 t->used = 1;
40 handle.shape = atof(t->value);
41 } else
42 handle.shape = RLN_SHAPE_DEFAULT;
43
44 t = find_token(list_head, RLN_SCALE);
45 if (t && t->value) {
46 t->used = 1;
47 handle.scale = atof(t->value);
48 } else
49 handle.scale = RLN_SCALE_DEFAULT;
50
51 cvar_trace("shape = %lf, scale = %lf", handle.shape, handle.scale);
52
53 if (handle.shape < 0) {
54 cvar_log_error("Invalid parameter value: shape = %lf. shape is a "
55 "non-zero, positive rational number", handle.shape);
56 goto out;
57 }
58
59 if (handle.scale < 0) {
60 cvar_log_error("Invalid parameter value: scale = %lf. scale is a "
61 "non-zero, positive rational number", handle.scale);
62 goto out;
63 }
64
65 t = unused_tokens(list_head);
66 if (t) {
67 cvar_log_error("Unsupported parameter %s", t->key);
68 goto out;
69 }
70
71 /* Seed the state. */
72 mts_goodseed(&handle.state);
73
74 /* All set. Now allocate space for the handle in the shared segment and
75 * copy the state over. */
76 state = (handle_t *) cvar_malloc(sizeof(handle_t));
77 if (!state) {
78 cvar_log_error("Out of memory");
79 goto out;
80 }
81
82 *state = handle;
83
84 out:
85 free_tokens(list_head);
86
87 cvar_trace("exit");
88 return state;
89 }
90
cvar_revalidate_handle(void * cvar_handle)91 int cvar_revalidate_handle(void *cvar_handle)
92 {
93 handle_t *h = (handle_t *) cvar_handle;
94
95 mts_mark_initialized(&h->state);
96
97 return 0;
98 }
99
cvar_next_value(void * cvar_handle,double * value)100 int cvar_next_value(void *cvar_handle, double *value)
101 {
102 handle_t *h = (handle_t *) cvar_handle;
103
104 if (!h) {
105 cvar_trace("NULL cvar_handle");
106 return -1;
107 }
108
109 if (!value) {
110 cvar_trace("NULL value");
111 return -1;
112 }
113
114 *value = rds_lognormal(&h->state, h->shape, h->scale);
115
116 return 0;
117 }
118
cvar_free_handle(void * handle,void (* cvar_free)(void * ptr))119 void cvar_free_handle(void *handle, void (*cvar_free)(void *ptr))
120 {
121 cvar_free(handle);
122 }
123
cvar_usage()124 const char *cvar_usage()
125 {
126 int offset;
127
128 if (usage[0])
129 return usage;
130
131 offset = 0;
132
133 offset += snprintf(usage + offset, USAGE_LEN - offset,
134 "\tparameter\tdefault\n");
135 offset += snprintf(usage + offset, USAGE_LEN - offset,
136 "\t---------\t-------\n");
137
138 offset += snprintf(usage + offset, USAGE_LEN - offset,
139 "\t%s\t\t%.1f\n", RLN_SHAPE, RLN_SHAPE_DEFAULT);
140 offset += snprintf(usage + offset, USAGE_LEN - offset,
141 "\t%s\t\t%.1f\n", RLN_SCALE, RLN_SCALE_DEFAULT);
142
143 offset += snprintf(usage + offset, USAGE_LEN - offset,
144 "Use '%c' to delimit parameters and '%c' to delimit key-value "
145 "pairs.\n", DEFAULT_PARAMETER_DELIMITER,
146 DEFAULT_KEY_VALUE_DELIMITER);
147
148 offset += snprintf(usage + offset, USAGE_LEN - offset,
149 "Example: '%s%c%.1f%c%s%c%.1f'",
150 RLN_SHAPE, DEFAULT_KEY_VALUE_DELIMITER, RLN_SHAPE_DEFAULT,
151 DEFAULT_PARAMETER_DELIMITER,
152 RLN_SCALE, DEFAULT_KEY_VALUE_DELIMITER, RLN_SCALE_DEFAULT);
153
154 return usage;
155 }
156
cvar_version()157 const char *cvar_version()
158 {
159 return VERSION;
160 }
161