const vector<__u32>& weight) const {
Mutex::Locker l(mapper_lock);
int rawout[maxout];
- int scratch[maxout * 3];
- char work[crush->working_size];
+ char work[crush_work_size(crush, maxout)];
crush_init_workspace(crush, work);
int numrep = crush_do_rule(crush, rule, x, rawout, maxout, &weight[0],
- weight.size(), work, scratch);
+ weight.size(), work);
if (numrep < 0)
numrep = 0;
out.resize(numrep);
# include "hash.h"
#endif
#include "crush_ln_table.h"
+#include "mapper.h"
#define dprintk(args...) /* printf(args) */
* @weight: weight vector (for map leaves)
* @weight_max: size of weight vector
* @cwin: Pointer to at least map->working_size bytes of memory or NULL.
- * @scratch: scratch vector for private use; must be >= 3 * result_max
*/
int crush_do_rule(const struct crush_map *map,
int ruleno, int x, int *result, int result_max,
const __u32 *weight, int weight_max,
- void *cwin, int *scratch)
+ void *cwin)
{
int result_len;
struct crush_work *cw = cwin;
- int *a = scratch;
- int *b = scratch + result_max;
- int *c = scratch + result_max*2;
+ int *a = (int *)((char *)cw + map->working_size);
+ int *b = a + result_max;
+ int *c = b + result_max;
+ int *w = a;
+ int *o = b;
int recurse_to_leaf;
- int *w;
int wsize = 0;
- int *o;
int osize;
int *tmp;
const struct crush_rule *rule;
rule = map->rules[ruleno];
result_len = 0;
- w = a;
- o = b;
-
for (step = 0; step < rule->len; step++) {
int firstn = 0;
int ruleno,
int x, int *result, int result_max,
const __u32 *weights, int weight_max,
- void *cwin, int *scratch);
+ void *cwin);
+
+/* Returns the exact amount of workspace that will need to be used
+ for a given combination of crush_map and result_max. The caller can
+ then allocate this much on its own, either on the stack, in a
+ per-thread long-lived buffer, or however it likes. */
+
+static inline size_t crush_work_size(const struct crush_map *map,
+ int result_max) {
+ return map->working_size + result_max * 3 * sizeof(__u32);
+}
extern void crush_init_workspace(const struct crush_map *m, void *v);