int _print_job_job_id(job_info_t * job, int width, bool right, char* suffix) { if (job == NULL) { /* Print the Header instead */ _print_str("JOBID", width, right, true); } else if ((job->array_task_id != NO_VAL) && !params.array_flag && IS_JOB_PENDING(job) && job->node_inx) { uint32_t i, max_task_id = 0; char id[FORMAT_STRING_SIZE], task_str[FORMAT_STRING_SIZE]; bitstr_t *task_bits; for (i = 1; i <= job->node_inx[0]; i++) max_task_id = MAX(max_task_id, job->node_inx[i]); task_bits = bit_alloc(max_task_id + 1); for (i = 1; i <= job->node_inx[0]; i++) bit_set(task_bits, job->node_inx[i]); bit_fmt(task_str, sizeof(task_str), task_bits); snprintf(id, FORMAT_STRING_SIZE, "%u_[%s]", job->array_job_id, task_str); _print_str(id, width, right, true); bit_free(task_bits); } else if (job->array_task_id != NO_VAL) { char id[FORMAT_STRING_SIZE]; snprintf(id, FORMAT_STRING_SIZE, "%u_%u", job->array_job_id, job->array_task_id); _print_str(id, width, right, true); } else { char id[FORMAT_STRING_SIZE]; snprintf(id, FORMAT_STRING_SIZE, "%u", job->job_id); _print_str(id, width, right, true); } if (suffix) printf("%s", suffix); return SLURM_SUCCESS; }
void buf_free(struct buffer* buf) { volatile uint32_t* bitmap = NULL; ptrdiff_t bufferIndex = 0; switch (buf->capacity) { case BUF_SMALL_BUF_SIZE: bitmap = &smallBufferBitmap; bufferIndex = (((uint8_t*) buf) - smallBufferPool) / BUF_SMALL_BUF_SIZE; assert(BUF_SMALL_BUF_COUNT > bufferIndex); break; case BUF_MEDIUM_BUF_SIZE: bitmap = &mediumBufferBitmap; bufferIndex = (((uint8_t*) buf) - mediumBufferPool) / BUF_MEDIUM_BUF_SIZE; assert(BUF_MEDIUM_BUF_COUNT > bufferIndex); break; case BUF_LARGE_BUF_SIZE: bitmap = &largeBufferBitmap; bufferIndex = (((uint8_t*) buf) - largeBufferPool) / BUF_LARGE_BUF_SIZE; assert(BUF_LARGE_BUF_COUNT > bufferIndex); break; default: assert(false); } if (bitmap) { bit_free(bitmap, (uint32_t) bufferIndex); } }
uint32_t powercap_get_node_bitmap_maxwatts(bitstr_t *idle_bitmap) { uint32_t max_watts = 0, val; struct node_record *node_ptr; int i; bitstr_t *tmp_bitmap = NULL; if (!_powercap_enabled()) return 0; if (!power_layout_ready()) return 0; /* if no input bitmap, consider the current idle nodes * bitmap as the input bitmap tagging nodes to consider * as idle while computing the max watts of the cluster */ if (idle_bitmap == NULL) { tmp_bitmap = bit_copy(idle_node_bitmap); idle_bitmap = tmp_bitmap; } for (i = 0, node_ptr = node_record_table_ptr; i < node_record_count; i++, node_ptr++) { /* non reserved node, evaluate the different cases */ if (bit_test(idle_bitmap, i)) { /* idle nodes, 2 cases : power save or not */ if (bit_test(power_node_bitmap, i)) { layouts_entity_pullget_kv(L_NAME, node_ptr->name, L_NODE_SAVE, &val, L_T_UINT32); } else { layouts_entity_pullget_kv(L_NAME, node_ptr->name, L_NODE_IDLE, &val, L_T_UINT32); } } else { /* non idle nodes, 2 cases : down or not */ if (!bit_test(up_node_bitmap, i)) { layouts_entity_pullget_kv(L_NAME, node_ptr->name, L_NODE_DOWN, &val, L_T_UINT32); } else { layouts_entity_pullget_kv(L_NAME, node_ptr->name, L_NODE_MAX, &val, L_T_UINT32); } } max_watts += val; } if (tmp_bitmap) bit_free(tmp_bitmap); return max_watts; }
/* Convert node name string to equivalent nid string */ static char *_node_names_2_nid_list(char *node_names) { char *nid_list = NULL; int i, last_nid_index = -1; bool is_dash = false; bitstr_t *node_bitmap; node_bitmap = bit_alloc(100000); for (i = 0; node_names[i]; i++) { int nid_index = 0; /* skip "nid[" */ if ((node_names[i] < '0') || (node_names[i] > '9')) continue; /* skip leading zeros */ while (node_names[i] == '0') i++; if (node_names[i] == '[') i++; while ((node_names[i] >= '0') && (node_names[i] <= '9')) { nid_index *= 10; nid_index += (node_names[i++] - '0'); } if (is_dash && (nid_index >= last_nid_index)) { bit_nset(node_bitmap, last_nid_index, nid_index); } else { bit_set(node_bitmap, nid_index); } if ((is_dash = (node_names[i] == '-'))) last_nid_index = nid_index; else if (node_names[i] == '\0') break; } i = strlen(node_names) + 1; nid_list = xmalloc(i); bit_fmt(nid_list, i, node_bitmap); bit_free(node_bitmap); return nid_list; }
uint32_t powercap_get_node_bitmap_maxwatts_dvfs(bitstr_t *idle_bitmap, bitstr_t *select_bitmap, uint32_t *max_watts_dvfs, int* allowed_freqs, uint32_t num_cpus) { uint32_t max_watts = 0, tmp_max_watts = 0, val = 0; uint32_t *tmp_max_watts_dvfs = NULL; struct node_record *node_ptr; int i, p; char ename[128], keyname[128]; bitstr_t *tmp_bitmap = NULL; uint32_t data[5], core_data[4]; if (!_powercap_enabled()) return 0; if (max_watts_dvfs != NULL) { tmp_max_watts_dvfs = xmalloc(sizeof(uint32_t)*(allowed_freqs[0]+1)); } /* if no input bitmap, consider the current idle nodes * bitmap as the input bitmap tagging nodes to consider * as idle while computing the max watts of the cluster */ if (idle_bitmap == NULL && select_bitmap == NULL) { tmp_bitmap = bit_copy(idle_node_bitmap); idle_bitmap = tmp_bitmap; select_bitmap = tmp_bitmap; } for (i = 0, node_ptr = node_record_table_ptr; i < node_record_count; i++, node_ptr++) { if (bit_test(idle_bitmap, i)) { /* idle nodes, 2 cases : power save or not */ if (bit_test(power_node_bitmap, i)) { layouts_entity_pullget_kv(L_NAME, node_ptr->name, L_NODE_SAVE, &val, L_T_UINT32); } else { layouts_entity_pullget_kv(L_NAME, node_ptr->name, L_NODE_IDLE, &val, L_T_UINT32); } } else if (bit_test(select_bitmap, i)) { layouts_entity_get_mkv(L_NAME, node_ptr->name, "IdleWatts,MaxWatts,CoresCount,LastCore,CurrentPower", data, (sizeof(uint32_t) * 5), L_T_UINT32); /* tmp_max_watts = IdleWatts - cpus*IdleCoreWatts * + cpus*MaxCoreWatts */ sprintf(ename, "virtualcore%u", data[3]); if (num_cpus == 0) num_cpus = data[2]; layouts_entity_get_mkv(L_NAME, ename, "IdleCoreWatts,MaxCoreWatts", core_data, (sizeof(uint32_t) * 2), L_T_UINT32); if (data[4] == 0) { tmp_max_watts += data[0] - num_cpus*core_data[0] + num_cpus*core_data[1]; } else if (data[4] > 0) { tmp_max_watts += data[4] - num_cpus*core_data[0] + num_cpus*core_data[1]; } else if (num_cpus == data[2]) tmp_max_watts += data[1]; if (!tmp_max_watts_dvfs) goto skip_dvfs; for (p = 1; p < (allowed_freqs[0] + 1); p++) { sprintf(keyname, "IdleCoreWatts,MaxCoreWatts," "Cpufreq%dWatts,CurrentCorePower", allowed_freqs[p]); layouts_entity_get_mkv(L_NAME, ename, keyname, core_data, (sizeof(uint32_t) * 4), L_T_UINT32); if (num_cpus == data[2]) { tmp_max_watts_dvfs[p] += num_cpus*core_data[2]; } else { if (data[4] == 0) { tmp_max_watts_dvfs[p] += data[0] - num_cpus*core_data[0] + num_cpus*core_data[2]; } else { tmp_max_watts_dvfs[p] += data[4] - num_cpus*core_data[0] + num_cpus*core_data[2]; } } } skip_dvfs: ; } else { /* non-idle nodes, 2 cases : down or not */ if (!bit_test(up_node_bitmap, i)) { layouts_entity_pullget_kv(L_NAME, node_ptr->name, L_NODE_DOWN, &val, L_T_UINT32); } else { layouts_entity_pullget_kv(L_NAME, node_ptr->name, L_NODE_CUR, &val, L_T_UINT32); } } max_watts += val; val = 0; } if (max_watts_dvfs) { for (p = 1; p < allowed_freqs[0] + 1; p++) { max_watts_dvfs[p] = max_watts + tmp_max_watts_dvfs[p]; } xfree(tmp_max_watts_dvfs); } max_watts += tmp_max_watts; if (tmp_bitmap) bit_free(tmp_bitmap); return max_watts; }
/* * Validate the cpus and select the frequency to set * Called from task cpuset code with task launch request containing * a pointer to a hex map string of the cpus to be used by this step */ extern void cpu_freq_cpuset_validate(stepd_step_rec_t *job) { int cpuidx, cpu_num; bitstr_t *cpus_to_set; bitstr_t *cpu_map; char *cpu_bind; char *cpu_str; char *savestr = NULL; debug_flags = slurm_get_debug_flags(); /* init for slurmstepd */ if (debug_flags & DEBUG_FLAG_CPU_FREQ) { info("cpu_freq_cpuset_validate: request: min=(%12d %8x) " "max=(%12d %8x) governor=%8x", job->cpu_freq_min, job->cpu_freq_min, job->cpu_freq_max, job->cpu_freq_max, job->cpu_freq_gov); info(" jobid=%u, stepid=%u, tasks=%u cpu/task=%u, cpus=%u", job->jobid, job->stepid, job->node_tasks, job->cpus_per_task, job->cpus); info(" cpu_bind_type=%4x, cpu_bind map=%s", job->cpu_bind_type, job->cpu_bind); } if (!cpu_freq_count) return; if (job->cpu_bind == NULL) { error("cpu_freq_cpuset_validate: cpu_bind string is null"); return; } cpu_bind = xstrdup(job->cpu_bind); if ( (cpu_str = strtok_r(cpu_bind, ",", &savestr) ) == NULL) { error("cpu_freq_cpuset_validate: cpu_bind string invalid"); xfree(cpu_bind); return; } cpu_map = (bitstr_t *) bit_alloc(cpu_freq_count); cpus_to_set = (bitstr_t *) bit_alloc(cpu_freq_count); do { debug3(" cpu_str = %s", cpu_str); if ((job->cpu_bind_type & CPU_BIND_MAP) == CPU_BIND_MAP) { cpu_num = atoi(cpu_str); if (cpu_num >= cpu_freq_count) { error("cpu_freq_cpuset_validate: invalid cpu " "number %d", cpu_num); bit_free(cpu_map); bit_free(cpus_to_set); xfree(cpu_bind); return; } bit_set(cpu_map, (bitoff_t)cpu_num); } else { if (bit_unfmt_hexmask(cpu_map, cpu_str) == -1) { error("cpu_freq_cpuset_validate: invalid cpu " "mask %s", cpu_bind); bit_free(cpu_map); bit_free(cpus_to_set); xfree(cpu_bind); return; } } bit_or(cpus_to_set, cpu_map); } while ( (cpu_str = strtok_r(NULL, ",", &savestr) ) != NULL); for (cpuidx = 0; cpuidx < cpu_freq_count; cpuidx++) { _cpu_freq_init_data(cpuidx); if (bit_test(cpus_to_set, cpuidx)) { _cpu_freq_setup_data(job, cpuidx); } } cpu_freq_set(job); bit_free(cpu_map); bit_free(cpus_to_set); xfree(cpu_bind); return; }
int main(int argc, char *argv[]) { note("Testing static decl"); { bitstr_t bit_decl(bs, 65); /*bitstr_t *bsp = bs;*/ bit_set(bs,9); bit_set(bs,14); TEST(bit_test(bs,9), "bit 9 set"); TEST(!bit_test(bs,12), "bit 12 not set"); TEST(bit_test(bs,14), "bit 14 set" ); /*bit_free(bsp);*/ /* triggers TEST in bit_free - OK */ } note("Testing basic vixie functions"); { bitstr_t *bs = bit_alloc(16), *bs2; /*bit_set(bs, 42);*/ /* triggers TEST in bit_set - OK */ bit_set(bs,9); bit_set(bs,14); TEST(bit_test(bs,9), "bit 9 set"); TEST(!bit_test(bs,12), "bit 12 not set" ); TEST(bit_test(bs,14), "bit 14 set"); bs2 = bit_copy(bs); bit_fill_gaps(bs2); TEST(bit_ffs(bs2) == 9, "first bit set = 9 "); TEST(bit_fls(bs2) == 14, "last bit set = 14"); TEST(bit_set_count(bs2) == 6, "bitstring"); TEST(bit_test(bs2,12), "bitstring"); TEST(bit_super_set(bs,bs2) == 1, "bitstring"); TEST(bit_super_set(bs2,bs) == 0, "bitstring"); bit_clear(bs,14); TEST(!bit_test(bs,14), "bitstring"); bit_nclear(bs,9,14); TEST(!bit_test(bs,9), "bitstring"); TEST(!bit_test(bs,12), "bitstring"); TEST(!bit_test(bs,14), "bitstring"); bit_nset(bs,9,14); TEST(bit_test(bs,9), "bitstring"); TEST(bit_test(bs,12), "bitstring"); TEST(bit_test(bs,14), "bitstring"); TEST(bit_ffs(bs) == 9, "ffs"); TEST(bit_ffc(bs) == 0, "ffc"); bit_nset(bs,0,8); TEST(bit_ffc(bs) == 15, "ffc"); bit_free(bs); /*bit_set(bs,9); */ /* triggers TEST in bit_set - OK */ } note("Testing and/or/not"); { bitstr_t *bs1 = bit_alloc(128); bitstr_t *bs2 = bit_alloc(128); bit_set(bs1, 100); bit_set(bs1, 104); bit_set(bs2, 100); bit_and(bs1, bs2); TEST(bit_test(bs1, 100), "and"); TEST(!bit_test(bs1, 104), "and"); bit_set(bs2, 110); bit_set(bs2, 111); bit_set(bs2, 112); bit_or(bs1, bs2); TEST(bit_test(bs1, 100), "or"); TEST(bit_test(bs1, 110), "or"); TEST(bit_test(bs1, 111), "or"); TEST(bit_test(bs1, 112), "or"); bit_not(bs1); TEST(!bit_test(bs1, 100), "not"); TEST(bit_test(bs1, 12), "not"); bit_free(bs1); bit_free(bs2); } note("testing bit selection"); { bitstr_t *bs1 = bit_alloc(128), *bs2; bit_set(bs1, 21); bit_set(bs1, 100); bit_fill_gaps(bs1); bs2 = bit_pick_cnt(bs1,20); if (bs2) { TEST(bit_set_count(bs2) == 20, "pick"); TEST(bit_ffs(bs2) == 21, "pick"); TEST(bit_fls(bs2) == 40, "pick"); bit_free(bs2); } else TEST(0, "alloc fail"); bit_free(bs1); } note("Testing realloc"); { bitstr_t *bs = bit_alloc(1); TEST(bit_ffs(bs) == -1, "bitstring"); bit_set(bs,0); /*bit_set(bs, 1000);*/ /* triggers TEST in bit_set - OK */ bs = bit_realloc(bs,1048576); bit_set(bs,1000); bit_set(bs,1048575); TEST(bit_test(bs, 0), "bitstring"); TEST(bit_test(bs, 1000), "bitstring"); TEST(bit_test(bs, 1048575), "bitstring"); TEST(bit_set_count(bs) == 3, "bitstring"); bit_clear(bs,0); bit_clear(bs,1000); TEST(bit_set_count(bs) == 1, "bitstring"); TEST(bit_ffs(bs) == 1048575, "bitstring"); bit_free(bs); } note("Testing bit_fmt"); { char tmpstr[1024]; bitstr_t *bs = bit_alloc(1024); TEST(!strcmp(bit_fmt(tmpstr,sizeof(tmpstr),bs), ""), "bitstring"); bit_set(bs,42); TEST(!strcmp(bit_fmt(tmpstr,sizeof(tmpstr),bs), "42"), "bitstring"); bit_set(bs,102); TEST(!strcmp(bit_fmt(tmpstr,sizeof(tmpstr),bs), "42,102"), "bitstring"); bit_nset(bs,9,14); TEST(!strcmp(bit_fmt(tmpstr,sizeof(tmpstr), bs), "9-14,42,102"), "bitstring"); } note("Testing bit_nffc/bit_nffs"); { bitstr_t *bs = bit_alloc(1024); bit_set(bs, 2); bit_set(bs, 6); bit_set(bs, 7); bit_nset(bs,12,1018); TEST(bit_nffc(bs, 2) == 0, "bitstring"); TEST(bit_nffc(bs, 3) == 3, "bitstring"); TEST(bit_nffc(bs, 4) == 8, "bitstring"); TEST(bit_nffc(bs, 5) == 1019, "bitstring"); TEST(bit_nffc(bs, 6) == -1, "bitstring"); TEST(bit_nffs(bs, 1) == 2, "bitstring"); TEST(bit_nffs(bs, 2) == 6, "bitstring"); TEST(bit_nffs(bs, 100) == 12, "bitstring"); TEST(bit_nffs(bs, 1023) == -1, "bitstring"); bit_free(bs); } note("Testing bit_unfmt"); { bitstr_t *bs = bit_alloc(1024); bitstr_t *bs2 = bit_alloc(1024); char tmpstr[4096]; bit_set(bs,1); bit_set(bs,3); bit_set(bs,30); bit_nset(bs,42,64); bit_nset(bs,97,1000); bit_fmt(tmpstr, sizeof(tmpstr), bs); TEST(bit_unfmt(bs2, tmpstr) != -1, "bitstring"); TEST(bit_equal(bs, bs2), "bitstring"); } totals(); return failed; }
/* * Validate the cpus and select the frequency to set * Called from task cpuset code with task launch request containing * a pointer to a hex map string of the cpus to be used by this step */ void cpu_freq_cpuset_validate(stepd_step_rec_t *job) { int cpuidx, cpu_num; bitstr_t *cpus_to_set; bitstr_t *cpu_map; char *cpu_bind; char *cpu_str; char *savestr = NULL; debug2("cpu_freq_cpuset_validate: request = %12d %8x", job->cpu_freq, job->cpu_freq); debug2(" jobid=%u, stepid=%u, tasks=%u cpu/task=%u, cpus=%u", job->jobid, job->stepid, job->node_tasks, job->cpus_per_task,job->cpus); debug2(" cpu_bind_type=%4x, cpu_bind map=%s", job->cpu_bind_type, job->cpu_bind); if (!cpu_freq_count) return; if (job->cpu_bind == NULL) { error("cpu_freq_cpuset_validate: cpu_bind string is null"); return; } cpu_bind = xstrdup(job->cpu_bind); if ( (cpu_str = strtok_r(cpu_bind, ",", &savestr) ) == NULL) { error("cpu_freq_cpuset_validate: cpu_bind string invalid"); xfree(cpu_bind); return; } cpu_map = (bitstr_t *) bit_alloc(cpu_freq_count); cpus_to_set = (bitstr_t *) bit_alloc(cpu_freq_count); do { debug3(" cpu_str = %s", cpu_str); if ((job->cpu_bind_type & CPU_BIND_MAP) == CPU_BIND_MAP) { cpu_num = atoi(cpu_str); if (cpu_num >= cpu_freq_count) { error("cpu_freq_cpuset_validate: invalid cpu " "number %d", cpu_num); bit_free(cpu_map); bit_free(cpus_to_set); xfree(cpu_bind); return; } bit_set(cpu_map, (bitoff_t)cpu_num); } else { if (bit_unfmt_hexmask(cpu_map, cpu_str) == -1) { error("cpu_freq_cpuset_validate: invalid cpu " "mask %s", cpu_bind); bit_free(cpu_map); bit_free(cpus_to_set); xfree(cpu_bind); return; } } bit_or(cpus_to_set, cpu_map); } while ( (cpu_str = strtok_r(NULL, ",", &savestr) ) != NULL); for (cpuidx=0; cpuidx < cpu_freq_count; cpuidx++) { if (bit_test(cpus_to_set, cpuidx)) { _cpu_freq_find_valid(job->cpu_freq, cpuidx); } } cpu_freq_set(job); bit_free(cpu_map); bit_free(cpus_to_set); xfree(cpu_bind); return; }
char *test_bit_operation() { bit_t tmp; int i; bit_clear(a, 0, 255); bit_clear(b, 0, 255); bit_set(a, 5, 99); bit_set(b, 100, 222); tmp = bit_union(a, b); for (i=5; i<=222; i++) { mu_assert(bit_get(tmp, i) == 1, "bit_union is wrong.\n"); } mu_assert(bit_lt(a, tmp), "bit_union is wrong.\n"); mu_assert(bit_lt(b, tmp), "bit_union is wrong.\n"); bit_free(&tmp); mu_assert(tmp == NULL, "bit_free gets wrong.\n"); bit_clear(a, 0, 255); bit_clear(b, 0, 255); bit_set(a, 7, 99); bit_set(b, 7, 98); tmp = bit_union(a, b); for (i=7; i<=99; i++) { mu_assert(bit_get(tmp, i) == 1, "bit_union is wrong.\n"); } mu_assert(bit_eq(a, tmp), "bit_union is wrong.\n"); mu_assert(bit_lt(b, tmp), "bit_union is wrong.\n"); bit_free(&tmp); mu_assert(tmp == NULL, "bit_free gets wrong.\n"); bit_clear(a, 0, 255); bit_clear(b, 0, 255); bit_set(a, 7, 88); bit_set(b, 50, 98); tmp = bit_union(a, b); for (i=7; i<=98; i++) { mu_assert(bit_get(tmp, i) == 1, "bit_union is wrong.\n"); } mu_assert(bit_lt(a, tmp), "bit_union is wrong.\n"); mu_assert(bit_lt(b, tmp), "bit_union is wrong.\n"); bit_free(&tmp); mu_assert(tmp == NULL, "bit_free gets wrong.\n"); /* test bit_inter */ bit_clear(a, 0, 255); bit_clear(b, 0, 255); bit_set(a, 7, 88); bit_set(b, 50, 98); tmp = bit_inter(a, b); for (i=50; i<=88; i++) { mu_assert(bit_get(tmp, i) == 1, "bit_inter is wrong.\n"); } mu_assert(bit_lt(tmp, a), "bit_inter is wrong.\n"); mu_assert(bit_lt(tmp, b), "bit_inter is wrong.\n"); bit_free(&tmp); mu_assert(tmp == NULL, "bit_free gets wrong.\n"); bit_clear(a, 0, 255); bit_clear(b, 0, 255); bit_set(a, 18, 200); bit_set(b, 18, 200); tmp = bit_inter(a, b); mu_assert(bit_eq(tmp, a), "bit_inter is wrong.\n"); mu_assert(bit_eq(tmp, b), "bit_inter is wrong.\n"); bit_free(&tmp); mu_assert(tmp == NULL, "bit_free gets wrong.\n"); bit_clear(a, 0, 255); bit_clear(b, 0, 255); bit_set(a, 18, 100); bit_set(b, 111, 200); tmp = bit_inter(a, b); bit_clear(a, 0, 255); mu_assert(bit_eq(tmp, a), "bit_inter is wrong.\n"); bit_free(&tmp); mu_assert(tmp == NULL, "bit_free gets wrong.\n"); /* test of bit_minus */ bit_clear(a, 0, 255); bit_clear(b, 0, 255); bit_set(a, 20, 201); bit_set(b, 111, 200); tmp = bit_minus(a, b); for (i=20; i<=110; i++) { mu_assert(bit_get(tmp, i) == 1, "bit_minus is wrong.\n"); } for (i=111; i<=200; i++) { mu_assert(bit_get(tmp, i) == 0, "bit_minus is wrong.\n"); } mu_assert(bit_get(tmp, 201) == 1, "bit_minus is wrong.\n"); bit_free(&tmp); mu_assert(tmp == NULL, "bit_free gets wrong.\n"); tmp = bit_minus(b, a); bit_clear(a, 0, 255); mu_assert(bit_eq(tmp, a), "bit_minus is wrong.\n"); bit_clear(a, 0, 255); bit_clear(b, 0, 255); bit_set(a, 20, 110); bit_set(b, 111, 200); tmp = bit_minus(a, b); mu_assert(bit_eq(tmp, a), "bit_minus is wrong.\n"); bit_free(&tmp); mu_assert(tmp == NULL, "bit_free gets wrong.\n"); bit_clear(a, 0, 255); bit_clear(b, 0, 255); bit_set(a, 20, 120); bit_set(b, 111, 200); tmp = bit_minus(a, b); for (i=20; i<=110; i++) { mu_assert(bit_get(tmp, i) == 1, "bit_minus is wrong.\n"); } for (i=111; i<=200; i++) { mu_assert(bit_get(tmp, i) == 0, "bit_minus is wrong.\n"); } bit_free(&tmp); mu_assert(tmp == NULL, "bit_free gets wrong.\n"); /* test bit_diff */ bit_clear(a, 0, 255); bit_clear(b, 0, 255); bit_set(a, 20, 222); bit_set(b, 111, 200); tmp = bit_diff(a, b); for (i=20; i<=110; i++) { mu_assert(bit_get(tmp, i) == 1, "bit_diff is wrong.\n"); } for (i=111; i<=200; i++) { mu_assert(bit_get(tmp, i) == 0, "bit_diff is wrong.\n"); } for (i=201; i<=222; i++) { mu_assert(bit_get(tmp, i) == 1, "bit_diff is wrong.\n"); } bit_free(&tmp); mu_assert(tmp == NULL, "bit_free gets wrong.\n"); tmp = bit_diff(b, a); for (i=20; i<=110; i++) { mu_assert(bit_get(tmp, i) == 1, "bit_diff is wrong.\n"); } for (i=111; i<=200; i++) { mu_assert(bit_get(tmp, i) == 0, "bit_diff is wrong.\n"); } for (i=201; i<=222; i++) { mu_assert(bit_get(tmp, i) == 1, "bit_diff is wrong.\n"); } bit_free(&tmp); mu_assert(tmp == NULL, "bit_free gets wrong.\n"); bit_clear(a, 0, 255); bit_clear(b, 0, 255); bit_set(a, 20, 110); bit_set(b, 111, 200); tmp = bit_diff(a, b); for (i = 20; i <= 200; i++) { mu_assert(bit_get(tmp, i) == 1, "bit_diff is wrong.\n"); } bit_free(&tmp); mu_assert(tmp == NULL, "bit_free gets wrong.\n"); bit_clear(a, 0, 255); bit_clear(b, 0, 255); bit_set(a, 20, 158); bit_set(b, 111, 200); tmp = bit_diff(a, b); for (i = 20; i <= 110; i++) { mu_assert(bit_get(tmp, i) == 1, "bit_diff is wrong.\n"); } for (i = 111; i <= 158; i++) { mu_assert(bit_get(tmp, i) == 0, "bit_diff is wrong.\n"); } for (i = 159; i <= 200; i++) { mu_assert(bit_get(tmp, i) == 1, "bit_diff is wrong.\n"); } bit_free(&tmp); mu_assert(tmp == NULL, "bit_free gets wrong.\n"); return NULL; }