示例#1
0
文件: print.c 项目: mrhaoji/slurm
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;
}
示例#2
0
文件: buffer.c 项目: 0x8000-0000/fx3
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);
   }
}
示例#3
0
文件: powercapping.c 项目: npe9/slurm
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;
}
示例#4
0
/* 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;
}
示例#5
0
文件: powercapping.c 项目: npe9/slurm
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;
}
示例#6
0
/*
 * 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;
}
示例#7
0
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;
}
示例#9
0
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;
}