コード例 #1
0
ファイル: rt-attr.c プロジェクト: Skotha/bird
 HASH_WALK_FILTER(src_hash, next, src, sp)
 {
   if (src->uc == 0)
   {
     HASH_DO_REMOVE(src_hash, RSH, sp);
     rte_src_free_id(src->global_id);
     sl_free(rte_src_slab, src);
   }
 }
コード例 #2
0
void
endusershell(void)
{
	if (sl) {
		sl_free(sl, 1);
		sl = NULL;
	}
	curshell = NULL;
}
コード例 #3
0
ファイル: pointer_list.c プロジェクト: qwertzuiop961/prgraas
static void pl_each_test(void) {
	printsln((Any)__func__);
	List ac, ex;
	
	ac = sl_of_string("a, b, c, d");
	pl_each(ac, pl_upper_case_free, NULL);
	ex = sl_of_string("A, B, C, D");
	sl_check_expect(ac, ex);
	sl_free(ac);
	sl_free(ex);
	
	ac = sl_of_string("");
	pl_each(ac, pl_upper_case_free, NULL);
	ex = sl_of_string("");
	sl_check_expect(ac, ex);
	sl_free(ac);
	sl_free(ex);
}
コード例 #4
0
ファイル: scene.c プロジェクト: Sun77789/raytracer
void scene_free(scene *s)
{
    rgb_free(s->bg);
    sl_free(s->spheres);
    light_free(s->light);
    rgb_free(s->amb);
    free(s);
    return;
}
コード例 #5
0
ファイル: conf.c プロジェクト: sthen/nsh
void conf_rtables_rtable(FILE *output, int rtableid)
{
	int i;
	StringList *rtable_name, *rtable_daemons;

	rtable_name = sl_init();

	if (db_select_name_rtable(rtable_name, rtableid) < 0) {
		printf("%% database failure select rtables name\n");
		sl_free(rtable_name, 1);
		return;
	} else {
		fprintf(output, "rtable %d %s\n", rtableid,
		    rtable_name->sl_str[0]);
	}

	sl_free(rtable_name, 1);

	/*
	 * Routes must be printed before we attempt to start daemons,
	 * else rtables will not be created in the kernel (Unless an
	 * rdomain is created by specifing one on an interface prior
	 * to this point. An rdomain creates a new corresponding rtable)
	 */
	conf_arp(output, " arp ");
	conf_routes(output, " route ", AF_INET, RTF_STATIC, rtableid);
	conf_routes(output, " route ", AF_INET6, RTF_STATIC, rtableid);

	rtable_daemons = sl_init();

	if (db_select_flag_x_ctl_rtable(rtable_daemons, "ctl", rtableid) < 0) {
		printf("%% database failure select ctl rtable\n");
		sl_free(rtable_daemons, 1);
		return;
	} else {
		for (i = 0; i < rtable_daemons->sl_cur; i++)
			conf_ctl(output, " ", rtable_daemons->sl_str[i], rtableid);
	}

	sl_free(rtable_daemons, 1);

	fprintf(output, "!\n");
}
コード例 #6
0
ファイル: sl_load.c プロジェクト: chubbymaggie/libdetox
void unload_elf(dso *so) {
  /* Are we allowed to unload? */
  if (so->flags_1 & DF_1_NODELETE) {
    sl_printf("Error unload_elf: NODELETE flag set on %s.\n", so->name);
    sl_exit(1);
  }

#ifdef D_RLOAD
  sl_printf("Unloading %s (%p-%p)\n", so->path, so->text_addr, so->end_addr);
#endif

#ifdef SL_STATISTIC
  curr_loaded_dsos--;
#endif
  
  /* Call fini functions */
  so_fini(so);
  
  /* Remove it from chain and global scope */
  chain_delete(so);
  gscope_remove(so);

#if defined(VERIFY_CFTX)  
  /* Remove it from libdetox dso_chain */
  remove_dso(so);
#endif

  /* Free name and path */
  sl_free((void *)so->name, MAX_LIB_NAME);
  sl_free((void *)so->path, MAX_PATH_LEN);
  
  /* Free dep. and lsope lists */
  if (so->deps)
    sl_free(so->deps, so->deps_count * sizeof(dso *));
  if (so->lscope)
    sl_free(so->lscope, so->lscope_num * sizeof(dso *));

  /* Unmap text and data segments */
  unmap_segments(so);

  /* Free struct */
  sl_free(so, sizeof(dso));
}
コード例 #7
0
ファイル: soelim.c プロジェクト: 2trill2spill/freebsd
int
main(int argc, char **argv)
{
	int ch, i;
	int ret = 0;
	int flags = 0;

	includes = sl_init();
	if (includes == NULL)
		err(EXIT_FAILURE, "sl_init()");

	while ((ch = getopt(argc, argv, "CrtvI:")) != -1) {
		switch (ch) {
		case 'C':
			flags |= C_OPTION;
			break;
		case 'r':
		case 'v':
		case 't':
			/* stub compatibility with groff's soelim */
			break;
		case 'I':
			sl_add(includes, optarg);
			break;
		default:
			sl_free(includes, 0);
			usage();
		}
	}

	argc -= optind;
	argv += optind;

	if (argc == 0)
		ret = soelim_file(stdin, flags);

	for (i = 0; i < argc; i++)
		ret = soelim_file(soelim_fopen(argv[i]), flags);

	sl_free(includes, 0);

	return (ret);
}
コード例 #8
0
ファイル: sstring.c プロジェクト: runner-mei/squirrel
DLL_VARIABLE void sbuffer_release(sbuffer_t* lhs, sstring_t* rhs) {
  if(0 != rhs->str)
    sl_free(rhs->str);

  rhs->str = lhs->str;
  rhs->len = lhs->len;

  lhs->str = 0;
  lhs->len = 0;
  lhs->capacity = 0;
}
コード例 #9
0
ファイル: main.c プロジェクト: kidaak/pkgsrc
/*
 * Help/usage command.
 * Call each command handler with argc == 0 and argv[0] == name.
 */
void
help(int argc, char *argv[])
{
	struct cmd *c;
	char *nargv[1], *cmd;
	const char *p;
	int isusage;

	cmd = argv[0];
	isusage = (strcmp(cmd, "usage") == 0);
	if (argc == 0 || (isusage && argc == 1)) {
		UPRINTF("usage: %s [command [...]]\n", cmd);
		return;
	}
	if (argc == 1) {
		StringList *buf;

		buf = ftp_sl_init();
		fprintf(ttyout,
		    "%sommands may be abbreviated.  Commands are:\n\n",
		    proxy ? "Proxy c" : "C");
		for (c = cmdtab; (p = c->c_name) != NULL; c++)
			if (!proxy || c->c_proxy)
				ftp_sl_add(buf, ftp_strdup(p));
		list_vertical(buf);
		sl_free(buf, 1);
		return;
	}

#define	HELPINDENT ((int) sizeof("disconnect"))

	while (--argc > 0) {
		char *arg;
		char cmdbuf[MAX_C_NAME];

		arg = *++argv;
		c = getcmd(arg);
		if (c == (struct cmd *)-1)
			fprintf(ttyout, "?Ambiguous %s command `%s'\n",
			    cmd, arg);
		else if (c == NULL)
			fprintf(ttyout, "?Invalid %s command `%s'\n",
			    cmd, arg);
		else {
			if (isusage) {
				(void)strlcpy(cmdbuf, c->c_name, sizeof(cmdbuf));
				nargv[0] = cmdbuf;
				(*c->c_handler)(0, nargv);
			} else
				fprintf(ttyout, "%-*s\t%s\n", HELPINDENT,
				    c->c_name, c->c_help);
		}
	}
}
コード例 #10
0
ファイル: getusershell.c プロジェクト: AhmadTux/DragonFlyBSD
/*ARGSUSED*/
static int
_nis_initshells(void *rv, void *cb_data, va_list ap)
{
	static char *ypdomain;
	char	*key, *data;
	char	*lastkey;
	int	 keylen, datalen;
	int	 r;

	if (sl)
		sl_free(sl, 1);
	sl = sl_init();

	if (ypdomain == NULL) {
		switch (yp_get_default_domain(&ypdomain)) {
		case 0:
			break;
		case YPERR_RESRC:
			return NS_TRYAGAIN;
		default:
			return NS_UNAVAIL;
		}
	}

	/*
	 * `key' and `data' point to strings dynamically allocated by
	 * the yp_... functions.
	 * `data' is directly put into the stringlist of shells.
	 */
	key = data = NULL;
	if (yp_first(ypdomain, "shells", &key, &keylen, &data, &datalen))
		return NS_UNAVAIL;
	do {
		data[datalen] = '\0';		/* clear trailing \n */
		sl_add(sl, data);

		lastkey = key;
		r = yp_next(ypdomain, "shells", lastkey, keylen,
		    &key, &keylen, &data, &datalen);
		free(lastkey);
	} while (r == 0);

	if (r == YPERR_NOMORE) {
		/*
		 * `data' and `key' ought to be NULL - do not try to free them.
		 */
		return NS_SUCCESS;
	}

	return NS_UNAVAIL;
}
コード例 #11
0
ファイル: complete.c プロジェクト: ryo/netbsd-src
/*
 * Complete a local executable
 */
static unsigned char
complete_executable(EditLine *el, char *word, int dolist)
{
	StringList *words;
	char dir[ MAXPATHLEN ];
	char *fname;
	unsigned char rv;
	size_t len;
	int error;

	if ((fname = strrchr(word, '/')) == NULL) {
		dir[0] = '\0';		/* walk the path */
		fname = word;
	} else {
		if (fname == word) {
			dir[0] = '/';
			dir[1] = '\0';
		} else {
			len = fname - word;
			(void)strncpy(dir, word, len);
			dir[fname - word] = '\0';
		}
		fname++;
	}

	words = sl_init();

	if (*dir == '\0') {		/* walk path */
		char *env;
		char *path;
		env = getenv("PATH");
		len = strlen(env);
		path = salloc(len + 1);
		(void)strcpy(path, env);
		error = find_execs(word, path, words);
	}
	else {		/* check specified dir only */
		error = find_execs(word, dir, words);
	}
	if (error != 0)
		return CC_ERROR;

	rv = complete_ambiguous(el, fname, dolist, words);
	if (rv == CC_REFRESH) {
		if (el_insertstr(el, " ") == -1)
			rv = CC_ERROR;
	}
	sl_free(words, 1);

	return rv;
}
コード例 #12
0
/*
 * Complete a local file
 */
static unsigned char
complete_local(char *word, int list)
{
	StringList *words;
	char dir[MAXPATHLEN];
	char *file;
	DIR *dd;
	struct dirent *dp;
	unsigned char rv;

	if ((file = strrchr(word, '/')) == NULL) {
		dir[0] = '.';
		dir[1] = '\0';
		file = word;
	} else {
		if (file == word) {
			dir[0] = '/';
			dir[1] = '\0';
		} else {
			(void)strlcpy(dir, word, (size_t)(file - word) + 1);
		}
		file++;
	}

	if ((dd = opendir(dir)) == NULL)
		return (CC_ERROR);

	words = sl_init();

	for (dp = readdir(dd); dp != NULL; dp = readdir(dd)) {
		if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, ".."))
			continue;
		if (strlen(file) > dp->d_namlen)
			continue;
		if (strncmp(file, dp->d_name, strlen(file)) == 0) {
			char *tcp;

			tcp = strdup(dp->d_name);
			if (tcp == NULL)
				errx(1, "Can't allocate memory for local dir");
			sl_add(words, tcp);
		}
	}
	closedir(dd);

	rv = complete_ambiguous(file, list, words);
	sl_free(words, 1);
	return (rv);
}
コード例 #13
0
ファイル: complete.c プロジェクト: ryo/netbsd-src
/*
 * Complete mime_transfer_encoding type.
 */
static unsigned char
mime_enc_complete(EditLine *el, int ch)
{
	static char word[LINESIZE];
	StringList *words;
	unsigned char rv;
	const LineInfo *lf;
	size_t word_len;
	int dolist;

	lf = el_line(el);

#ifdef EMACS_CTRL_D_BINDING_HACK
	{
		int cc_ret;
		if ((cc_ret = emacs_ctrl_d(el, lf, ch)) != -1)
			return cc_ret;
	}
#endif /* EMACS_CTRL_D_BINDING_HACK */

	word_len = lf->cursor - lf->buffer;
	if (word_len >= sizeof(word) - 1)
		return CC_ERROR;

	words = mail_sl_init();
	{
		const char *ename;
		const void *cookie;
		cookie = NULL;
		for (ename = mime_next_encoding_name(&cookie);
		     ename;
		     ename = mime_next_encoding_name(&cookie))
			if (word_len == 0 ||
			    strncmp(lf->buffer, ename, word_len) == 0) {
				char *cp;
				cp = estrdup(ename);
				mail_sl_add(words, cp);
			}
	}
	(void)strlcpy(word, lf->buffer, word_len + 1);

	if ((dolist = get_dolist(lf)) == -1)
		return CC_ERROR;

	rv = complete_ambiguous(el, word, dolist, words);

	sl_free(words, 1);
	return rv;
}
コード例 #14
0
ファイル: scandir.c プロジェクト: ashleyh/f
static void f_scandir_work(uv_work_t* req) {
  char* path = req->data;
  f_scandir_response_t response = malloc(sizeof(struct f_scandir_response_s));
  check_oom(response);
  response->dents = sl_alloc_f(1);
  check_oom(response->dents);
  response->path = path;
  if (!f_scandir_impl(path, response)) {
    if (response->dents != NULL) {
      sl_free(response->dents);
    }
    response->dents = NULL;
  }
  req->data = response;
}
コード例 #15
0
ファイル: conf.c プロジェクト: sthen/nsh
int conf_dhcrelay(char *ifname, char *server, int serverlen)
{
	StringList *data;
	int alen;

	data = sl_init();
	if ((alen = db_select_flag_x_data_ctl_rtable(data, "dhcrelay", ifname, 0))
	    > 0) {
		strlcpy(server, data->sl_str[0], serverlen);
		alen = strlen(data->sl_str[0]);
	}
	sl_free(data, 1);

	return(alen);
}
コード例 #16
0
ファイル: conf.c プロジェクト: sthen/nsh
void
conf_db_single(FILE *output, char *dbname, char *lookup, char *ifname)
{
	StringList *dbreturn;
	dbreturn = sl_init();

	if (db_select_flag_x_ctl(dbreturn, dbname, ifname) < 0) {
		printf("%% conf_db_single %s database select failed\n", dbname);
	}
	if (dbreturn->sl_cur > 0) {
		if (lookup == NULL)
			fprintf(output, " %s\n", dbname);
		else if (strcmp(dbreturn->sl_str[0], lookup) != 0)
			fprintf(output, " %s %s\n", dbname, dbreturn->sl_str[0]);
	}
	sl_free(dbreturn, 1);
}
コード例 #17
0
static void
add(DB *db, StringList *sl, size_t port, const char *proto, size_t *cnt,
    int warndup)
{
	size_t i;
	char	 keyb[BUFSIZ], datab[BUFSIZ], abuf[BUFSIZ];
	DBT	 data, key;
	key.data = keyb;
	data.data = datab;

#ifdef DEBUG
	(void)printf("add %s %zu %s [ ", sl->sl_str[0], port, proto);
	for (i = 1; i < sl->sl_cur; i++)
	    (void)printf("%s ", sl->sl_str[i]);
	(void)printf("]\n");
#endif

	/* key `indirect key', data `full line' */
	data.size = snprintf(datab, sizeof(datab), "%zu", (*cnt)++) + 1;
	key.size = snprintf(keyb, sizeof(keyb), "%s %zu/%s %s",
	    sl->sl_str[0], port, proto, mkaliases(sl, abuf, sizeof(abuf))) + 1;
	store(db, &data, &key, warndup);

	/* key `\377port/proto', data = `indirect key' */
	key.size = snprintf(keyb, sizeof(keyb), "\377%zu/%s",
	    port, proto) + 1;
	store(db, &key, &data, warndup);

	/* key `\377port', data = `indirect key' */
	killproto(&key);
	store(db, &key, &data, warndup);

	/* add references for service and all aliases */
	for (i = 0; i < sl->sl_cur; i++) {
		/* key `\376service/proto', data = `indirect key' */
		key.size = snprintf(keyb, sizeof(keyb), "\376%s/%s",
		    sl->sl_str[i], proto) + 1;
		store(db, &key, &data, warndup);

		/* key `\376service', data = `indirect key' */
		killproto(&key);
		store(db, &key, &data, warndup);
	}
	sl_free(sl, 1);
}
コード例 #18
0
ファイル: test-stringlist.c プロジェクト: 2asoft/freebsd
int
main(void)
{
	StringList	*sl;
	char		 teststr[] = "test";

	if ((sl = sl_init()) == NULL)
		return 1;
	if (sl_add(sl, teststr))
		return 2;
	if (sl->sl_cur != 1)
		return 3;
	if (sl->sl_str[0] != teststr)
		return 4;

	sl_free(sl, 0);
	return 0;
}
コード例 #19
0
ファイル: complete.c プロジェクト: ryo/netbsd-src
static unsigned char
complete_alias(EditLine *el, char *word, int dolist)
{
	struct grouphead *gh;
	const char **ap;
	const char **p;
	int h;
	int s;
	size_t len = strlen(word);
	StringList *words;
	unsigned char rv;

	words = sl_init();

	/* allocate space for alias table */
	s = 1;
	for (h = 0; h < HSHSIZE; h++)
		for (gh = groups[h]; gh != NULL; gh = gh->g_link)
			s++;
	ap = salloc(s * sizeof(*ap));

	/* save pointers */
	p = ap;
	for (h = 0; h < HSHSIZE; h++)
		for (gh = groups[h]; gh != NULL; gh = gh->g_link)
			*p++ = gh->g_name;

	*p = NULL;

	sort(ap);
	for (p = ap; *p != NULL; p++)
		if (len == 0 || strncmp(*p, word, len) == 0)
			mail_sl_add(words, estrdup(*p));

	rv = complete_ambiguous(el, word, dolist, words);
	if (rv == CC_REFRESH) {
		if (el_insertstr(el, " ") == -1)
			rv = CC_ERROR;
	}
	sl_free(words, 1);
	return rv;
}
コード例 #20
0
ファイル: complete.c プロジェクト: ryo/netbsd-src
static unsigned char
complete_thread_key(EditLine *el, char *word, int dolist)
{
	const char **ap;
	const char **p;
	const char *name;
	size_t len;
	StringList *words;
	unsigned char rv;
	int cnt;
	const void *cookie;

	len = strlen(word);
	words = sl_init();

	/* count the entries in the table */
	/* XXX - have a function return this rather than counting? */
	cnt = 1;	/* count the NULL terminator */
	cookie = NULL;
	while (thread_next_key_name(&cookie) != NULL)
		cnt++;

	/* allocate sufficient space for the pointers */
	ap = salloc(cnt * sizeof(*ap));

	/* load the array */
	p = ap;
	cookie = NULL;
	while ((name = thread_next_key_name(&cookie)) != NULL)
		*p++ = name;
	*p = NULL;
	sort(ap);
	for (p = ap; *p != NULL; p++)
		if (len == 0 || strncmp(*p, word, len) == 0)
			mail_sl_add(words, estrdup(*p));

	rv = complete_ambiguous(el, word, dolist, words);

	sl_free(words, 1);

	return rv;
}
コード例 #21
0
/*
 * Complete a command
 */
static unsigned char
complete_command(char *word, int list)
{
	const struct cmd *c;
	StringList *words;
	size_t wordlen;
	unsigned char rv;

	words = sl_init();
	wordlen = strlen(word);

	for (c = cmdtab; c->c_name != NULL; c++) {
		if (wordlen > strlen(c->c_name))
			continue;
		if (strncmp(word, c->c_name, wordlen) == 0)
			sl_add(words, c->c_name);
	}

	rv = complete_ambiguous(word, list, words);
	sl_free(words, 0);
	return (rv);
}
コード例 #22
0
ファイル: complete.c プロジェクト: ryo/netbsd-src
static unsigned char
complete_set(EditLine *el, char *word, int dolist)
{
	struct var *vp;
	const char **ap;
	const char **p;
	int h;
	int s;
	size_t len = strlen(word);
	StringList *words;
	unsigned char rv;

	words = sl_init();

	/* allocate space for variables table */
	s = 1;
	for (h = 0; h < HSHSIZE; h++)
		for (vp = variables[h]; vp != NULL; vp = vp->v_link)
			s++;
	ap = salloc(s * sizeof(*ap));

	/* save the pointers */
	for (h = 0, p = ap; h < HSHSIZE; h++)
		for (vp = variables[h]; vp != NULL; vp = vp->v_link)
			*p++ = vp->v_name;
	*p = NULL;
	sort(ap);
	for (p = ap; *p != NULL; p++)
		if (len == 0 || strncmp(*p, word, len) == 0)
			mail_sl_add(words, estrdup(*p));

	rv = complete_ambiguous(el, word, dolist, words);

	sl_free(words, 1);

	return rv;
}
コード例 #23
0
ファイル: conf.c プロジェクト: sthen/nsh
int
ipv6ll_db_compare(struct sockaddr_in6 *sin6, struct sockaddr_in6 *sin6mask,
    char *ifname)
{
	int count, scope;
	StringList *data;
	struct in6_addr store;

	if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) ||
	    IN6_IS_ADDR_MC_LINKLOCAL(&sin6->sin6_addr) ||
	    IN6_IS_ADDR_MC_INTFACELOCAL(&sin6->sin6_addr)) {
		/*
		 * Save any scope or embedded scope.
		 * The kernel does not set sin6_scope_id.
		 * But if it ever does, we're already prepared.
		 */
		store.s6_addr[0] = sin6->sin6_addr.s6_addr[2];
		store.s6_addr[1] = sin6->sin6_addr.s6_addr[3];
		sin6->sin6_addr.s6_addr[2] = sin6->sin6_addr.s6_addr[3] = 0;
		scope = sin6->sin6_scope_id;
		sin6->sin6_scope_id = 0;
		
		data = sl_init();
		db_select_flag_x_ctl_data(data, "ipv6linklocal", ifname,
		    netname6(sin6, sin6mask));
		count = data->sl_cur;
		sl_free(data, 1);

		/* restore any scope or embedded scope */
		sin6->sin6_addr.s6_addr[2] = store.s6_addr[0];
		sin6->sin6_addr.s6_addr[3] = store.s6_addr[1];
		sin6->sin6_scope_id = scope;
		return(count);
	}
	return 1;
}
コード例 #24
0
ファイル: complete.c プロジェクト: AhmadTux/DragonFlyBSD
/*
 * Complete a remote file
 */
static unsigned char
complete_remote(char *word, int list)
{
	static StringList *dirlist;
	static char	 lastdir[MAXPATHLEN];
	StringList	*words;
	char		 dir[MAXPATHLEN];
	char		*file, *cp;
	size_t		 i;
	unsigned char	 rv;
	char		 cmdbuf[MAX_C_NAME];
	char		*dummyargv[3] = { NULL, NULL, NULL };

	(void)strlcpy(cmdbuf, "complete", sizeof(cmdbuf));
	dummyargv[0] = cmdbuf;
	dummyargv[1] = dir;

	if ((file = strrchr(word, '/')) == NULL) {
		dir[0] = '\0';
		file = word;
	} else {
		cp = file;
		while (*cp == '/' && cp > word)
			cp--;
		(void)strlcpy(dir, word, cp - word + 2);
		file++;
	}

	if (dirchange || dirlist == NULL ||
	    strcmp(dir, lastdir) != 0) {		/* dir not cached */
		const char *emesg;

		if (dirlist != NULL)
			sl_free(dirlist, 1);
		dirlist = ftp_sl_init();

		mflag = 1;
		emesg = NULL;
		while ((cp = remglob(dummyargv, 0, &emesg)) != NULL) {
			char *tcp;

			if (!mflag)
				continue;
			if (*cp == '\0') {
				mflag = 0;
				continue;
			}
			tcp = strrchr(cp, '/');
			if (tcp)
				tcp++;
			else
				tcp = cp;
			tcp = ftp_strdup(tcp);
			ftp_sl_add(dirlist, tcp);
		}
		if (emesg != NULL) {
			fprintf(ttyout, "\n%s\n", emesg);
			return (CC_REDISPLAY);
		}
		(void)strlcpy(lastdir, dir, sizeof(lastdir));
		dirchange = 0;
	}

	words = ftp_sl_init();
	for (i = 0; i < dirlist->sl_cur; i++) {
		cp = dirlist->sl_str[i];
		if (strlen(file) > strlen(cp))
			continue;
		if (strncmp(file, cp, strlen(file)) == 0)
			ftp_sl_add(words, cp);
	}
	rv = complete_ambiguous(file, list, words);
	sl_free(words, 0);
	return (rv);
}
コード例 #25
0
ファイル: dc_mm.c プロジェクト: gmsh/dnscache
void dc_free(void * ptr){
	/* if ptr is NULL,no operation is performed. */
	if(!ptr)
		return;
	void * word_before_ptr = (uint64 *)ptr - 1;
	uint64 cap = *(uint64 *)word_before_ptr;
	int pos = cap - SMALL;
	struct sl_node * sn_ptr;
	struct slist * sl_ptr;
	/* if chunks wasn't pre-allocated */
	if(cap < SMALL || cap > BIG){
		sl_ptr = elm_table[cap]->chunks_list;
		pthread_mutex_lock(extra_mutex[cap]);
		mv2head(word_before_ptr,sl_ptr);
		printf("dc_mm : %s%8ld%s\n","free a extra chunk with specific capacity ", 
		        POW2(cap), " Bytes.");
		if(++(elm_table[cap]->idle_num) == elm_table[cap]->total_num ){
			traverse(free_extra_data,elm_table[cap]->chunks_list);
			sl_free(free,elm_table[cap]->chunks_list);		
			free(elm_table[cap]);	
			elm_table[cap] = NULL;	
			printf("dc_mm : %s%8ld%s\n","free a extra chunks list  with specific capacity ", 
			        POW2(cap), " Bytes.");
		}
		extra_free[cap]++;
		pthread_mutex_unlock(extra_mutex[cap]);
		return;				
	}
	/* if chunks was pre-allocated */
	/* if chunk to be freed in the pre-alloc-list */
	sl_ptr = chunks_manager_table[pos]->alloced_chunks;
	int found = find(word_before_ptr,sl_ptr);
	if(found){
		pthread_mutex_lock(pre_alloc_mutex[pos]);
		mv2head(word_before_ptr,sl_ptr);
		push(pop(sl_ptr),chunks_manager_table[pos]->idle_chunks);
		++(chunks_manager_table[pos]->idle_num);
		pre_alloc_free[pos]++;
		pthread_mutex_unlock(pre_alloc_mutex[pos]);
		printf("dc_mm : %s%8ld%s\n","free a chunk with specific capacity ", 
		        POW2(cap), " Bytes.");
		return; /* added by wakemecn at Jun 30th, 2011 */
	}		
	/* if chunk to be freed in the extra-list */
	sl_ptr = elm_table[cap]->chunks_list;
	pthread_mutex_lock(extra_mutex[cap]);
	mv2head(word_before_ptr,sl_ptr);  
	printf("dc_mm : %s%8ld%s\n","free a extra chunk with specific capacity ", 
	        POW2(cap), " Bytes.");
	(elm_table[cap]->idle_num)++;
	if(elm_table[cap]->idle_num == elm_table[cap]->total_num ){
		traverse(free_extra_data,elm_table[cap]->chunks_list);
		sl_free(free,elm_table[cap]->chunks_list);		
		free(elm_table[cap]);
		elm_table[cap] = NULL;	
		printf("dc_mm : %s%8ld%s\n","free a extra chunks list  with specific capacity ", 
		        POW2(cap), " Bytes.");
	}
	extra_free[cap]++;
	pthread_mutex_unlock(extra_mutex[cap]);
}
コード例 #26
0
ファイル: opensl.c プロジェクト: Ced2911/RetroArch
static void *sl_init(const char *device, unsigned rate, unsigned latency)
{
   unsigned i;
   SLInterfaceID id;
   SLboolean req;
   SLresult res;
   sl_t *sl;
   SLDataFormat_PCM fmt_pcm = {0};
   SLDataSource audio_src   = {0};
   SLDataSink audio_sink    = {0};
   SLDataLocator_AndroidSimpleBufferQueue loc_bufq = {0};
   SLDataLocator_OutputMix loc_outmix              = {0};
   settings_t *settings = config_get_ptr();

   (void)device;

   id = SL_IID_ANDROIDSIMPLEBUFFERQUEUE;
   req    = SL_BOOLEAN_TRUE;

   res = 0;
   sl = (sl_t*)calloc(1, sizeof(sl_t));
   if (!sl)
      goto error;

   RARCH_LOG("[SLES]: Requested audio latency: %u ms.", latency);

   GOTO_IF_FAIL(slCreateEngine(&sl->engine_object, 0, NULL, 0, NULL, NULL));
   GOTO_IF_FAIL(SLObjectItf_Realize(sl->engine_object, SL_BOOLEAN_FALSE));
   GOTO_IF_FAIL(SLObjectItf_GetInterface(sl->engine_object, SL_IID_ENGINE, &sl->engine));

   GOTO_IF_FAIL(SLEngineItf_CreateOutputMix(sl->engine, &sl->output_mix, 0, NULL, NULL));
   GOTO_IF_FAIL(SLObjectItf_Realize(sl->output_mix, SL_BOOLEAN_FALSE));

   if (settings->audio.block_frames)
      sl->buf_size = settings->audio.block_frames * 4;
   else
      sl->buf_size = next_pow2(32 * latency);

   sl->buf_count = (latency * 4 * rate + 500) / 1000;
   sl->buf_count = (sl->buf_count + sl->buf_size / 2) / sl->buf_size;

   sl->buffer = (uint8_t**)calloc(sizeof(uint8_t*), sl->buf_count);
   if (!sl->buffer)
      goto error;

   sl->buffer_chunk = (uint8_t*)calloc(sl->buf_count, sl->buf_size);
   if (!sl->buffer_chunk)
      goto error;

   for (i = 0; i < sl->buf_count; i++)
      sl->buffer[i] = sl->buffer_chunk + i * sl->buf_size;

   RARCH_LOG("[SLES]: Setting audio latency: Block size = %u, Blocks = %u, Total = %u ...\n",
         sl->buf_size, sl->buf_count, sl->buf_size * sl->buf_count);

   fmt_pcm.formatType    = SL_DATAFORMAT_PCM;
   fmt_pcm.numChannels   = 2;
   fmt_pcm.samplesPerSec = rate * 1000; // Samplerate is in milli-Hz.
   fmt_pcm.bitsPerSample = 16;
   fmt_pcm.containerSize = 16;
   fmt_pcm.channelMask   = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
   fmt_pcm.endianness    = SL_BYTEORDER_LITTLEENDIAN; /* Android only. */

   audio_src.pLocator = &loc_bufq;
   audio_src.pFormat  = &fmt_pcm;

   loc_bufq.locatorType = SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE;
   loc_bufq.numBuffers  = sl->buf_count;

   loc_outmix.locatorType = SL_DATALOCATOR_OUTPUTMIX;
   loc_outmix.outputMix   = sl->output_mix;

   audio_sink.pLocator = &loc_outmix;

   GOTO_IF_FAIL(SLEngineItf_CreateAudioPlayer(sl->engine, &sl->buffer_queue_object,
            &audio_src, &audio_sink,
            1, &id, &req));
   GOTO_IF_FAIL(SLObjectItf_Realize(sl->buffer_queue_object, SL_BOOLEAN_FALSE));

   GOTO_IF_FAIL(SLObjectItf_GetInterface(sl->buffer_queue_object, SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
            &sl->buffer_queue));

   sl->cond = scond_new();
   sl->lock = slock_new();

   (*sl->buffer_queue)->RegisterCallback(sl->buffer_queue, opensl_callback, sl);

   /* Enqueue a bit to get stuff rolling. */
   sl->buffered_blocks = sl->buf_count;
   sl->buffer_index = 0;
   for (i = 0; i < sl->buf_count; i++)
      (*sl->buffer_queue)->Enqueue(sl->buffer_queue, sl->buffer[i], sl->buf_size);

   GOTO_IF_FAIL(SLObjectItf_GetInterface(sl->buffer_queue_object, SL_IID_PLAY, &sl->player));
   GOTO_IF_FAIL(SLPlayItf_SetPlayState(sl->player, SL_PLAYSTATE_PLAYING));

   return sl;

error:
   RARCH_ERR("Couldn't initialize OpenSL ES driver, error code: [%d].\n", (int)res);
   sl_free(sl);
   return NULL;
}
コード例 #27
0
slint_t mpi_partition_radix2(elements_t *s, partcond2_t *pc, slint_t rhigh, slint_t rlow, slint_t rwidth, int *scounts, int *sdispls, int size, int rank, MPI_Comm comm) /* sl_proto, sl_func mpi_partition_radix2 */
{
  slkey_pure_t max_nclasses;
  slkey_pure_t nclasses, bit_mask;
  slkey_pure_t k;

  const slint_t max_nareas = size - 1;
  slint_t nareas, nareas_new;
  elements_t areas0[max_nareas], areas1[max_nareas], *areas, *areas_new;

  double *locals, *globals;
  double *local_counts, *local_weights, *global_counts, *global_weights;

  const slint_t max_nparts = size - 1;
  slint_t parts_low, parts_high, nparts_removed;
  slint_t parts[max_nparts], part_areas[max_nparts];

  double parts_range_[2 * 2 * (1 + max_nparts + 1)];
  double *parts_range = parts_range_ + (2 * 2);
  double parts_minmax_[2 * 4 * (1 + max_nparts + 1)];
  double *parts_minmax = parts_minmax_ + (2 * 4);
  slint_t parts_update_[1 + max_nparts + 1];
  slint_t *parts_update = parts_update_ + 1;

  double parts_minmax_new[2 * 4];
  double current_minmax[2 * 2];
  
  double final_locals[2 * max_nparts];

  slint_t i, j, jp1, jm1, l, lp1, lm1;
  slint_t current_width;

  double minmax[2 * 4 * size];
  
  slint_t last_new_area, last_new_class;

#ifdef HAVENT_MPI_IN_PLACE
  double local_minmax[2 * 4];
#endif

  slint_t lc, lcs, gc, gcs;
  double lw, gw, lws, gws;
  double d, m;

  elements_t xi, end;

  slint_t round = 0;
  slint_t direction = 1;

  slint_t refine, finalize;

#ifdef RCOUNTS_RDISPLS
  int *rcounts, *rdispls;
#endif

#ifdef WEIGHT_STATS
  slint_t total_count = 0, partial_counts[size + 1];
  double total_weight = 0.0, partial_weights[size + 1];
  double vmin, vmax;
# ifdef HAVENT_MPI_IN_PLACE
  slint_t partial_counts2[size + 1];
  double partial_weights2[size + 1];
# endif
#endif

  rti_treset(rti_tid_mpi_partition_radix2_while);                   /* sl_tid */
  rti_treset(rti_tid_mpi_partition_radix2_while_count);             /* sl_tid */
  rti_treset(rti_tid_mpi_partition_radix2_while_allreduce);         /* sl_tid */
  rti_treset(rti_tid_mpi_partition_radix2_while_round1);            /* sl_tid */
  rti_treset(rti_tid_mpi_partition_radix2_while_round1_allgather);  /* sl_tid */
  rti_treset(rti_tid_mpi_partition_radix2_while_exscan);            /* sl_tid */
  rti_treset(rti_tid_mpi_partition_radix2_while_check);             /* sl_tid */
  rti_treset(rti_tid_mpi_partition_radix2_while_check_pre);         /* sl_tid */
  rti_treset(rti_tid_mpi_partition_radix2_while_check_classes);     /* sl_tid */
  rti_treset(rti_tid_mpi_partition_radix2_while_check_final);       /* sl_tid */
  rti_treset(rti_tid_mpi_partition_radix2_while_check_post);        /* sl_tid */

  rti_tstart(rti_tid_mpi_partition_radix2_sync);
#ifdef SYNC_ON_INIT
  MPI_Barrier(comm);
#endif
  rti_tstop(rti_tid_mpi_partition_radix2_sync);

  rti_tstart(rti_tid_mpi_partition_radix2);

  if (rhigh < 0) rhigh = radix_high;
  if (rlow < 0) rlow = radix_low;
  if (rwidth < 0) rwidth = sort_radix_width_default;
  
  max_nclasses = powof2_typed(rwidth, slkey_pure_t);

  locals = sl_alloc(2 * (max_nareas * max_nclasses + max_nareas), sizeof(double));
  globals = sl_alloc(2 * (max_nareas * max_nclasses + max_nareas), sizeof(double));

  areas = areas0;
  areas_new = areas1;

  /* init the first area (all elements) */
  nareas = 1;
  elem_assign(s, &areas[0]);

  /* init all parts */
  parts_low = 0;
  parts_high = max_nparts - 1;
  for (i = parts_low; i <= parts_high; ++i)
  {
    parts[i] = i;
    part_areas[i] = 0;
  }

  /* init sdispls */
  for (i = 0; i < size; ++i) sdispls[i] = 0;

  rti_tstart(rti_tid_mpi_partition_radix2_while);

  while (parts_low <= parts_high)
  {
    ++round;

    /* setup bitmask */
    current_width = xmin(rwidth, rhigh - rlow + 1);
    rhigh -= (current_width > 0)?current_width - 1:rhigh;

    nclasses = (current_width > 0)?powof2_typed(current_width, slkey_pure_t):1;
    bit_mask = nclasses - 1;
    
    SL_TRACE_IF(DEBUG_OR_NOT, "ROUND: %" sl_int_type_fmt ", rhigh: %" sl_int_type_fmt ", current_width: %" sl_int_type_fmt ", nclasses: %" sl_key_pure_type_fmt, round, rhigh, current_width, nclasses);

    finalize = (current_width <= 0);

    if (!finalize || round == 1)
    {
      /* init counters */
      local_counts = locals;
      global_counts = globals;
      local_weights = locals + (nareas * nclasses) + nareas;
      global_weights = globals + (nareas * nclasses) + nareas;

      /* zero all counter */
      for (i = 0; i < nareas; ++i)
      for (k = 0; k < nclasses; ++k) local_counts[i * nclasses + k] = local_weights[i * nclasses + k] = 0.0;

      rti_tstart(rti_tid_mpi_partition_radix2_while_count);

      /* for every area */
      for (i = 0; i < nareas; ++i)
      {
        elem_assign_at(&areas[i], areas[i].size, &end);

        if (nclasses > 1)
        {
          /* counts and weights in every class */
          for (elem_assign(&areas[i], &xi); xi.keys < end.keys; elem_inc(&xi))
          {
            k = radix_key2class(key_purify(*xi.keys), rhigh, bit_mask);
            local_counts[i * nclasses + k] += 1;
            local_weights[i * nclasses + k] += elem_weight_one(&xi, 0);
          }

        } else
        {
          /* total counts and weights */
          local_counts[i * nclasses + 0] = areas[i].size;

          for (elem_assign(&areas[i], &xi); xi.keys < end.keys; elem_inc(&xi)) local_weights[i * nclasses + 0] += elem_weight_one(&xi, 0);
        }

        /* total counts and weights in this area */
        local_counts[nareas * nclasses + i] = areas[i].size;

        local_weights[nareas * nclasses + i] = 0.0;
        for (k = 0; k < nclasses; ++k) local_weights[nareas * nclasses + i] += local_weights[i * nclasses + k];
      }

      rti_tstop(rti_tid_mpi_partition_radix2_while_count);

      --rhigh;

      rti_tstart(rti_tid_mpi_partition_radix2_while_allreduce);

      /* create global counts and weights */
#ifdef MPI_PARTITION_RADIX_REDUCEBCAST_THRESHOLD
      if (size >= MPI_PARTITION_RADIX_REDUCEBCAST_THRESHOLD)
      {
        MPI_Reduce(locals, globals, (1 + 1) * (nareas * nclasses + nareas), MPI_DOUBLE, MPI_SUM, REDUCEBCAST_ROOT, comm);
        MPI_Bcast(globals, (1 + 1) * (nareas * nclasses + nareas), MPI_DOUBLE, REDUCEBCAST_ROOT, comm);

      } else
#endif
        MPI_Allreduce(locals, globals, (1 + 1) * (nareas * nclasses + nareas), MPI_DOUBLE, MPI_SUM, comm);

      rti_tstop(rti_tid_mpi_partition_radix2_while_allreduce);
    }

#ifdef TIMING
    SL_TRACE_IF(DEBUG_OR_NOT, "allreduce: %f, nareas: %" sl_int_type_fmt ", nclasses: %" sl_key_type_fmt ", doubles: %" sl_int_type_fmt, rti_tlast(rti_tid_mpi_partition_radix2_while_allreduce), nareas, nclasses, (1 + 1) * (nareas * nclasses + nareas));
#endif

/*    if (DEBUG_OR_NOT)
    {
      printf("%d: locals\n", rank);
      for (i = 0; i < nareas; ++i)
      {
        printf("%d: %" sl_int_type_fmt ":", rank, i);
        for (k = 0; k < nclasses; ++k) printf("  %f", local_counts[i * nclasses + k]);
        printf(" = %f\n", local_counts[nareas * nclasses + i]);
        printf("%d: %" sl_int_type_fmt ":", rank, i);
        for (k = 0; k < nclasses; ++k) printf("  %f", local_weights[i * nclasses + k]);
        printf(" = %f\n", local_weights[nareas * nclasses + i]);
      }
      printf("%d: globals\n", rank);
      for (i = 0; i < nareas; ++i)
      {
        printf("%d: %" sl_int_type_fmt ":", rank, i);
        for (k = 0; k < nclasses; ++k) printf("  %f", global_counts[i * nclasses + k]);
        printf(" = %f\n", global_counts[nareas * nclasses + i]);
        printf("%d: %" sl_int_type_fmt ":", rank, i);
        for (k = 0; k < nclasses; ++k) printf("  %f", global_weights[i * nclasses + k]);
        printf(" = %f\n", global_weights[nareas * nclasses + i]);
      }
    }*/

    /* do some initializations */
    if (round == 1)
    {
      rti_tstart(rti_tid_mpi_partition_radix2_while_round1);
    
      /* distribute min/max counts and weights */
      minmax[rank * 2 * 4 + 0 + 0] = (pc->min_count >= 0)?pc->min_count:(-pc->min_count * global_counts[nareas * nclasses + 0] / size);
      minmax[rank * 2 * 4 + 0 + 1] = (pc->max_count >= 0)?pc->max_count:(-pc->max_count * global_counts[nareas * nclasses + 0] / size);
      minmax[rank * 2 * 4 + 0 + 2] = (pc->min_cpart >= 0)?pc->min_cpart:(-pc->min_cpart * global_counts[nareas * nclasses + 0]);
      minmax[rank * 2 * 4 + 0 + 3] = (pc->max_cpart >= 0)?pc->max_cpart:(-pc->max_cpart * global_counts[nareas * nclasses + 0]);

      minmax[rank * 2 * 4 + 4 + 0] = (pc->min_weight >= 0)?pc->min_weight:(-pc->min_weight * global_weights[nareas * nclasses + 0] / size);
      minmax[rank * 2 * 4 + 4 + 1] = (pc->max_weight >= 0)?pc->max_weight:(-pc->max_weight * global_weights[nareas * nclasses + 0] / size);
      minmax[rank * 2 * 4 + 4 + 2] = (pc->min_wpart >= 0)?pc->min_wpart:(-pc->min_wpart * global_weights[nareas * nclasses + 0]);
      minmax[rank * 2 * 4 + 4 + 3] = (pc->max_wpart >= 0)?pc->max_wpart:(-pc->max_wpart * global_weights[nareas * nclasses + 0]);

      rti_tstart(rti_tid_mpi_partition_radix2_while_round1_allgather);
#ifdef HAVENT_MPI_IN_PLACE
      local_minmax[0 + 0] = minmax[rank * 2 * 4 + 0 + 0];
      local_minmax[0 + 1] = minmax[rank * 2 * 4 + 0 + 1];
      local_minmax[0 + 2] = minmax[rank * 2 * 4 + 0 + 2];
      local_minmax[0 + 3] = minmax[rank * 2 * 4 + 0 + 3];
      local_minmax[4 + 0] = minmax[rank * 2 * 4 + 4 + 0];
      local_minmax[4 + 1] = minmax[rank * 2 * 4 + 4 + 1];
      local_minmax[4 + 2] = minmax[rank * 2 * 4 + 4 + 2];
      local_minmax[4 + 3] = minmax[rank * 2 * 4 + 4 + 3];
      MPI_Allgather(local_minmax, 2 * 4, MPI_DOUBLE, minmax, 2 * 4, MPI_DOUBLE, comm);
/*      MPI_Gather(local_minmax_weights, 2 * 4, MPI_DOUBLE, minmax_weights, 2 * 4, MPI_DOUBLE, 0, comm);
      MPI_Bcast(minmax_weights, 2 * 4 * size, MPI_DOUBLE, 0, comm);*/
#else
      MPI_Allgather(MPI_IN_PLACE, 2 * 4, MPI_DOUBLE, minmax_weights, 2 * 4, MPI_DOUBLE, comm);
#endif
      rti_tstop(rti_tid_mpi_partition_radix2_while_round1_allgather);

#ifdef WEIGHT_STATS
      total_count = global_counts[nareas * nclasses + 0];
      total_weight = global_weights[nareas * nclasses + 0];
#endif

      parts_minmax[2 * 4 * (parts_low - 1) + 0 + 0] = parts_minmax[2 * 4 * (parts_low - 1) + 0 + 2] = 0;
      parts_minmax[2 * 4 * (parts_low - 1) + 0 + 1] = parts_minmax[2 * 4 * (parts_low - 1) + 0 + 3] = 0;
      parts_minmax[2 * 4 * (parts_low - 1) + 4 + 0] = parts_minmax[2 * 4 * (parts_low - 1) + 4 + 2] = 0;
      parts_minmax[2 * 4 * (parts_low - 1) + 4 + 1] = parts_minmax[2 * 4 * (parts_low - 1) + 4 + 3] = 0;

      parts_minmax[2 * 4 * (parts_high + 1) + 0 + 0] = parts_minmax[2 * 4 * (parts_high + 1) + 0 + 2] = 0;
      parts_minmax[2 * 4 * (parts_high + 1) + 0 + 1] = parts_minmax[2 * 4 * (parts_high + 1) + 0 + 3] = global_counts[nareas * nclasses + 0];
      parts_minmax[2 * 4 * (parts_high + 1) + 4 + 0] = parts_minmax[2 * 4 * (parts_high + 1) + 4 + 2] = 0;
      parts_minmax[2 * 4 * (parts_high + 1) + 4 + 1] = parts_minmax[2 * 4 * (parts_high + 1) + 4 + 3] = global_weights[nareas * nclasses + 0];

      parts_range[2 * 2 * (parts_low - 1) + 0 + 0] = parts_range[2 * 2 * (parts_high + 1) + 0 + 0] = 0.0;
      parts_range[2 * 2 * (parts_low - 1) + 0 + 1] = parts_range[2 * 2 * (parts_high + 1) + 0 + 1] = global_counts[nareas * nclasses + 0];
      parts_range[2 * 2 * (parts_low - 1) + 2 + 0] = parts_range[2 * 2 * (parts_high + 1) + 2 + 0] = 0.0;
      parts_range[2 * 2 * (parts_low - 1) + 2 + 1] = parts_range[2 * 2 * (parts_high + 1) + 2 + 1] = global_weights[nareas * nclasses + 0];

      for (i = parts_high; i >= parts_low; --i)
      {
        parts_minmax[2 * 4 * parts[i] + 0 + 1] = parts_minmax[2 * 4 * (parts[i] + 1) + 0 + 1] - minmax[2 * 4 * (parts[i] + 1) + 0 + 0];
        parts_minmax[2 * 4 * parts[i] + 0 + 3] = parts_minmax[2 * 4 * (parts[i] + 1) + 0 + 3] - minmax[2 * 4 * (parts[i] + 1) + 0 + 1];
        parts_minmax[2 * 4 * parts[i] + 4 + 1] = parts_minmax[2 * 4 * (parts[i] + 1) + 4 + 1] - minmax[2 * 4 * (parts[i] + 1) + 4 + 0];
        parts_minmax[2 * 4 * parts[i] + 4 + 3] = parts_minmax[2 * 4 * (parts[i] + 1) + 4 + 3] - minmax[2 * 4 * (parts[i] + 1) + 4 + 1];
        
        parts_minmax[2 * 4 * parts[i] + 0 + 0] = parts_minmax[2 * 4 * parts[i] + 0 + 2] = parts_minmax[2 * 4 * parts[i] + 4 + 0] = parts_minmax[2 * 4 * parts[i] + 4 + 2] = -1;

        parts_range[2 * 2 * parts[i] + 0 + 0] = 0.0;
        parts_range[2 * 2 * parts[i] + 0 + 1] = global_counts[nareas * nclasses + 0];
        parts_range[2 * 2 * parts[i] + 2 + 0] = 0.0;
        parts_range[2 * 2 * parts[i] + 2 + 1] = global_weights[nareas * nclasses + 0];
/*        SL_ASSERT(minmax[2 * 4 * (parts[i] + 1) + 0 + 2] <= minmax[2 * 4 * (parts[i] + 0) + 0 + 3]);*/
/*        SL_ASSERT(minmax[2 * 4 * (parts[i] + 1) + 4 + 2] <= minmax[2 * 4 * (parts[i] + 0) + 4 + 3]);*/

        parts_update[parts[i]] = 1;

        if (finalize)
        {
          final_locals[2 * i + 0] = local_counts[nareas * nclasses + 0];
          final_locals[2 * i + 1] = local_weights[nareas * nclasses + 0];
        }
      }

      rti_tstop(rti_tid_mpi_partition_radix2_while_round1);
    }

    if (finalize)
    {
      j = parts_high - parts_low + 1;
    
      SL_TRACE_IF(DEBUG_OR_NOT, "Exscan: finalizing %" sl_int_type_fmt " parts", j);

      rti_tstart(rti_tid_mpi_partition_radix2_while_exscan);

      MPI_Exscan(&final_locals[2 * parts_low], &locals[2 * parts_low], 2 * j, MPI_DOUBLE, MPI_SUM, comm);
      if (rank == 0) for (i = parts_low; i <= parts_high; ++i) locals[2 * i + 0] = locals[2 * i + 1] = 0;

      rti_tstop(rti_tid_mpi_partition_radix2_while_exscan);
    }

    nareas_new = 0;
    last_new_area = last_new_class = -1;

    /* check all remaining parts */

    SL_TRACE_IF(DEBUG_OR_NOT, "ROUND: %" sl_int_type_fmt ", %s", round, (direction > 0)?"forward":"backward");

    nparts_removed = 0;

    rti_tstart(rti_tid_mpi_partition_radix2_while_check);

    i = (direction > 0)?parts_low:parts_high;
    while ((direction > 0)?(i <= parts_high):(i >= parts_low))
    {
      rti_tstart(rti_tid_mpi_partition_radix2_while_check_pre);
    
      SL_TRACE_IF(DEBUG_OR_NOT, "%" sl_int_type_fmt ": PART: %" sl_int_type_fmt ",%" sl_int_type_fmt, round, i, parts[i]);

      j = 2 * 4 * parts[i];
      jp1 = 2 * 4 * (parts[i] + 1);
      jm1 = 2 * 4 * (parts[i] - 1);
      l = 2 * 2 * parts[i];
      lp1 = 2 * 2 * (parts[i] + 1);
      lm1 = 2 * 2 * (parts[i] - 1);

      if (parts_update[parts[i]])
      {
        if (direction > 0)
        {
          parts_minmax_new[0 + 0] = parts_minmax[jm1 + 0 + 0] + minmax[j + 0 + 0];
          parts_minmax_new[0 + 2] = parts_minmax[jm1 + 0 + 2] + minmax[j + 0 + 1];
          parts_minmax_new[4 + 0] = parts_minmax[jm1 + 4 + 0] + minmax[j + 4 + 0];
          parts_minmax_new[4 + 2] = parts_minmax[jm1 + 4 + 2] + minmax[j + 4 + 1];

          SL_TRACE_IF(DEBUG_OR_NOT, "%" sl_int_type_fmt ",%" sl_int_type_fmt ": %f + %f, %f + %f  /  %f + %f, %f + %f", i, parts[i],
            parts_minmax[jm1 + 0 + 0], minmax[j + 0 + 0],
            parts_minmax[jm1 + 0 + 2], minmax[j + 0 + 1],
            parts_minmax[jm1 + 4 + 0], minmax[j + 4 + 0],
            parts_minmax[jm1 + 4 + 2], minmax[j + 4 + 1]);

          SL_TRACE_IF(DEBUG_OR_NOT, "%" sl_int_type_fmt ": 0. parts_minmax_new: %f  %f  %f  %f  /  %f  %f  %f  %f", parts[i], parts_minmax_new[0 + 0], parts_minmax_new[0 + 1], parts_minmax_new[0 + 2], parts_minmax_new[0 + 3], parts_minmax_new[4 + 0], parts_minmax_new[4 + 1], parts_minmax_new[4 + 2], parts_minmax_new[4 + 3]);

          if (parts_minmax_new[0 + 0] < minmax[jp1 + 0 + 2]) parts_minmax_new[0 + 0] = minmax[jp1 + 0 + 2];
          if (parts_minmax_new[0 + 2] > minmax[j   + 0 + 3]) parts_minmax_new[0 + 2] = minmax[j   + 0 + 3];
          if (parts_minmax_new[4 + 0] < minmax[jp1 + 4 + 2]) parts_minmax_new[4 + 0] = minmax[jp1 + 4 + 2];
          if (parts_minmax_new[4 + 2] > minmax[j   + 4 + 3]) parts_minmax_new[4 + 2] = minmax[j   + 4 + 3];

          parts_minmax_new[0 + 1] = parts_minmax[j + 0 + 1];
          parts_minmax_new[0 + 3] = parts_minmax[j + 0 + 3];
          parts_minmax_new[4 + 1] = parts_minmax[j + 4 + 1];
          parts_minmax_new[4 + 3] = parts_minmax[j + 4 + 3];

        } else
        {
          parts_minmax_new[0 + 1] = parts_minmax[jp1 + 0 + 1] - minmax[jp1 + 0 + 0];
          parts_minmax_new[0 + 3] = parts_minmax[jp1 + 0 + 3] - minmax[jp1 + 0 + 1];
          parts_minmax_new[4 + 1] = parts_minmax[jp1 + 4 + 1] - minmax[jp1 + 4 + 0];
          parts_minmax_new[4 + 3] = parts_minmax[jp1 + 4 + 3] - minmax[jp1 + 4 + 1];

          SL_TRACE_IF(DEBUG_OR_NOT, "%" sl_int_type_fmt ",%" sl_int_type_fmt ": %f - %f, %f - %f  /  %f - %f, %f - %f", i, parts[i],
            parts_minmax[jp1 + 0 + 1], minmax[jp1 + 0 + 0],
            parts_minmax[jp1 + 0 + 3], minmax[jp1 + 0 + 1],
            parts_minmax[jp1 + 4 + 1], minmax[jp1 + 4 + 0],
            parts_minmax[jp1 + 4 + 3], minmax[jp1 + 4 + 1]);

          SL_TRACE_IF(DEBUG_OR_NOT, "%" sl_int_type_fmt ": 0. parts_minmax_new: %f  %f  %f  %f  /  %f  %f  %f  %f", parts[i], parts_minmax_new[0 + 0], parts_minmax_new[0 + 1], parts_minmax_new[0 + 2], parts_minmax_new[0 + 3], parts_minmax_new[4 + 0], parts_minmax_new[4 + 1], parts_minmax_new[4 + 2], parts_minmax_new[4 + 3]);

          if (parts_minmax_new[0 + 3] < minmax[jp1 + 0 + 2]) parts_minmax_new[0 + 3] = minmax[jp1 + 0 + 2];
          if (parts_minmax_new[0 + 1] > minmax[j   + 0 + 3]) parts_minmax_new[0 + 1] = minmax[j   + 0 + 3];
          if (parts_minmax_new[4 + 3] < minmax[jp1 + 4 + 2]) parts_minmax_new[4 + 3] = minmax[jp1 + 4 + 2];
          if (parts_minmax_new[4 + 1] > minmax[j   + 4 + 3]) parts_minmax_new[4 + 1] = minmax[j   + 4 + 3];

          parts_minmax_new[0 + 0] = parts_minmax[j + 0 + 0];
          parts_minmax_new[0 + 2] = parts_minmax[j + 0 + 2];
          parts_minmax_new[4 + 0] = parts_minmax[j + 4 + 0];
          parts_minmax_new[4 + 2] = parts_minmax[j + 4 + 2];
        }

        SL_TRACE_IF(DEBUG_OR_NOT, "%" sl_int_type_fmt ": 1. parts_minmax_new: %f  %f  %f  %f  /  %f  %f  %f  %f", parts[i], parts_minmax_new[0 + 0], parts_minmax_new[0 + 1], parts_minmax_new[0 + 2], parts_minmax_new[0 + 3], parts_minmax_new[4 + 0], parts_minmax_new[4 + 1], parts_minmax_new[4 + 2], parts_minmax_new[4 + 3]);
        SL_TRACE_IF(DEBUG_OR_NOT, "%" sl_int_type_fmt ": minmax: %f  %f  /  %f  %f", parts[i], minmax[2 * 4 * (parts[i] + 1) + 0 + 2], minmax[2 * 4 * (parts[i] + 0) + 0 + 3], minmax[2 * 4 * (parts[i] + 1) + 4 + 2], minmax[2 * 4 * (parts[i] + 0) + 4 + 3]);

        if (parts_minmax_new[0 + 0] > parts_minmax_new[0 + 1]) parts_minmax_new[0 + 0] = parts_minmax_new[0 + 1] = (parts_minmax_new[0 + 0] + parts_minmax_new[0 + 1]) / 2;
        if (parts_minmax_new[0 + 2] < parts_minmax_new[0 + 3]) parts_minmax_new[0 + 2] = parts_minmax_new[0 + 3] = (parts_minmax_new[0 + 2] + parts_minmax_new[0 + 3]) / 2;

        if (parts_minmax_new[4 + 0] > parts_minmax_new[4 + 1]) parts_minmax_new[4 + 0] = parts_minmax_new[4 + 1] = (parts_minmax_new[4 + 0] + parts_minmax_new[4 + 1]) / 2;
        if (parts_minmax_new[4 + 2] < parts_minmax_new[4 + 3]) parts_minmax_new[4 + 2] = parts_minmax_new[4 + 3] = (parts_minmax_new[4 + 2] + parts_minmax_new[4 + 3]) / 2;

      } else
      {
        parts_minmax_new[0 + 0] = parts_minmax[j + 0 + 0];
        parts_minmax_new[0 + 1] = parts_minmax[j + 0 + 1];
        parts_minmax_new[0 + 2] = parts_minmax[j + 0 + 2];
        parts_minmax_new[0 + 3] = parts_minmax[j + 0 + 3];

        parts_minmax_new[4 + 0] = parts_minmax[j + 4 + 0];
        parts_minmax_new[4 + 1] = parts_minmax[j + 4 + 1];
        parts_minmax_new[4 + 2] = parts_minmax[j + 4 + 2];
        parts_minmax_new[4 + 3] = parts_minmax[j + 4 + 3];
      }

      SL_TRACE_IF(DEBUG_OR_NOT, "%" sl_int_type_fmt ",%" sl_int_type_fmt ": 2. parts_minmax_new: %f  %f  %f  %f  /  %f  %f  %f  %f", i, parts[i], parts_minmax_new[0 + 0], parts_minmax_new[0 + 1], parts_minmax_new[0 + 2], parts_minmax_new[0 + 3], parts_minmax_new[4 + 0], parts_minmax_new[4 + 1], parts_minmax_new[4 + 2], parts_minmax_new[4 + 3]);

      current_minmax[0 + 0] = xmax(parts_minmax_new[0 + 0], parts_minmax_new[0 + 3]) - parts_range[l + 0 + 0];
      current_minmax[0 + 1] = xmin(parts_minmax_new[0 + 2], parts_minmax_new[0 + 1]) - parts_range[l + 0 + 0];

      current_minmax[2 + 0] = xmax(parts_minmax_new[4 + 0], parts_minmax_new[4 + 3]) - parts_range[l + 2 + 0];
      current_minmax[2 + 1] = xmin(parts_minmax_new[4 + 2], parts_minmax_new[4 + 1]) - parts_range[l + 2 + 0];

      SL_ASSERT(current_minmax[0 + 0] <= current_minmax[0 + 1]);
      SL_ASSERT(current_minmax[2 + 0] <= current_minmax[2 + 1]);

      rti_tstop(rti_tid_mpi_partition_radix2_while_check_pre);

      SL_TRACE_IF(DEBUG_OR_NOT, "%" sl_int_type_fmt ": current_minmax: %f  %f / %f  %f", parts[i], current_minmax[0 + 0], current_minmax[0 + 1], current_minmax[2 + 0], current_minmax[2 + 1]);

      lcs = gcs = 0;
      lws = gws = 0;

      /* HIT is the default */
      refine = 0;

      if (!finalize)
      {
        rti_tstart(rti_tid_mpi_partition_radix2_while_check_classes);
      
        for (k = 0; k < nclasses; ++k)
        {
          lc = local_counts[part_areas[i] * nclasses + k];
          gc = global_counts[part_areas[i] * nclasses + k];
          lw = local_weights[part_areas[i] * nclasses + k];
          gw = global_weights[part_areas[i] * nclasses + k];

          current_minmax[0 + 0] -= gc;
          current_minmax[0 + 1] -= gc;

          current_minmax[2 + 0] -= gw;
          current_minmax[2 + 1] -= gw;

          SL_TRACE_IF(DEBUG_OR_NOT, "k = %" sl_key_pure_type_fmt ", current_minmax: %f  %f  / %f  %f", k, current_minmax[0], current_minmax[1], current_minmax[2], current_minmax[3]);

          /* stop and refine if max count is skipped OR min count AND max weight is skipped */
          if ((current_minmax[0 + 1] < 0) || (current_minmax[0 + 0] < 0 && current_minmax[2 + 1] < 0))
          {
            refine = 1;
            break;
          }

          lcs += lc;
          gcs += gc;
          lws += lw;
          gws += gw;

          gc = gw = 0.0;

          /* if between min/max counts */
          if (current_minmax[0 + 0] <= 0 && current_minmax[0 + 1] >= 0)
          {
            /* go to next if max count not reached AND min weight not reached */
            if (current_minmax[0 + 1] > 0 && current_minmax[2 + 0] > 0) continue;

            /* look ahead for a better stop */
            if (k + 1 < nclasses && current_minmax[0 + 1] - global_counts[part_areas[i] * nclasses + k + 1] >= 0)
            {
              /* continue if weights will improve */
              if (myabs(current_minmax[2 + 0] + current_minmax[2 + 1]) > myabs(current_minmax[2 + 0] + current_minmax[2 + 1] - 2 * global_weights[part_areas[i] * nclasses + k + 1])) continue;
            }

            /* stop */
            break;
          }
        }

        SL_ASSERT(k < nclasses);

        SL_TRACE_IF(DEBUG_OR_NOT, "%s k = %" sl_key_pure_type_fmt, (refine)?"REFINE":"HIT", k);
      
        rti_tstop(rti_tid_mpi_partition_radix2_while_check_classes);

      } else
      {
        rti_tstart(rti_tid_mpi_partition_radix2_while_check_final);

        /* middle of min/max weight */
        m = (current_minmax[2 + 0] + current_minmax[2 + 1]) / 2;

        /* min. part of weight to contribute */
        d = xmax(0, m - locals[i * 2 + 1]);

        /* contribute all? */
        if (d >= final_locals[i * 2 + 1])
        {
          lc = final_locals[i * 2 + 0];
          lw = final_locals[i * 2 + 1];

        } else
        {
          /* contribute only a part */
          lc = 0;
          lw = 0; /* not required */

          do
          {
            d -= elem_weight_one(s, sdispls[1 + parts[i]] + lc);
            ++lc;

          } while (d >= 0 && lc < final_locals[i * 2 + 0]);

          --lc;
        
          /* if unweighted, then m = middle of min/max count, d = ..., lc = d */
        }

        /* check mc against min/max count borders */
        lc = xminmax(current_minmax[0 + 0] - locals[i * 2 + 0], lc, current_minmax[0 + 1] - locals[i * 2 + 0]);

        /* check agains 0 (don't step back!) and the local contribution */
        lc = xminmax(0, lc, final_locals[i * 2 + 0]);

        /* the exact global counts/weights are unknown (set gc/gw so that parts_range is not changed) */
        gc = 0;
        gw = 0;

        lcs += lc;
        gcs += gc;
        lws += lw;
        gws += gw;
        
        gc = (parts_range[2 * 2 * parts[i] + 0 + 1] - parts_range[2 * 2 * parts[i] + 0 + 0]);
        gw = (parts_range[2 * 2 * parts[i] + 2 + 1] - parts_range[2 * 2 * parts[i] + 2 + 0]);

        rti_tstop(rti_tid_mpi_partition_radix2_while_check_final);
      }      

      rti_tstart(rti_tid_mpi_partition_radix2_while_check_post);
      
      SL_TRACE_IF(DEBUG_OR_NOT, "%" sl_int_type_fmt ",%" sl_int_type_fmt ": sdispls[%" sl_int_type_fmt " + 1] = %d, lcs = %" sl_int_type_fmt, i, parts[i], parts[i], sdispls[parts[i] + 1], lcs);

      sdispls[parts[i] + 1] += lcs;

      if (gcs > 0 || gws > 0)
      {
        parts_range[l + 0 + 0] += gcs;
        parts_range[l + 0 + 1] = parts_range[l + 0 + 0] + gc;
        parts_range[l + 2 + 0] += gws;
        parts_range[l + 2 + 1] = parts_range[l + 2 + 0] + gw;

        SL_TRACE_IF(DEBUG_OR_NOT, "%" sl_int_type_fmt ",%" sl_int_type_fmt ": 3. part_minmax_new: %f  %f  %f  %f  /  %f  %f  %f  %f", i, parts[i], parts_minmax_new[0 + 0], parts_minmax_new[0 + 1], parts_minmax_new[0 + 2], parts_minmax_new[0 + 3], parts_minmax_new[4 + 0], parts_minmax_new[4 + 1], parts_minmax_new[4 + 2], parts_minmax_new[4 + 3]);
        SL_TRACE_IF(DEBUG_OR_NOT, "%" sl_int_type_fmt ",%" sl_int_type_fmt ": parts_range: %f  %f  /  %f  %f", i, parts[i], parts_range[2 * 2 * parts[i] + 0 + 0], parts_range[2 * 2 * parts[i] + 0 + 1], parts_range[2 * 2 * parts[i] + 2 + 0], parts_range[2 * 2 * parts[i] + 2 + 1]);

        parts_minmax_new[0 + 0] = xminmax(parts_range[l + 0 + 0], parts_minmax_new[0 + 0], parts_range[l + 0 + 1]);
        parts_minmax_new[0 + 2] = xminmax(parts_range[l + 0 + 0], parts_minmax_new[0 + 2], parts_range[l + 0 + 1]);
        parts_minmax_new[0 + 1] = xminmax(parts_range[l + 0 + 0], parts_minmax_new[0 + 1], parts_range[l + 0 + 1]);
        parts_minmax_new[0 + 3] = xminmax(parts_range[l + 0 + 0], parts_minmax_new[0 + 3], parts_range[l + 0 + 1]);
      
        parts_minmax_new[4 + 0] = xminmax(parts_range[l + 2 + 0], parts_minmax_new[4 + 0], parts_range[l + 2 + 1]);
        parts_minmax_new[4 + 2] = xminmax(parts_range[l + 2 + 0], parts_minmax_new[4 + 2], parts_range[l + 2 + 1]);
        parts_minmax_new[4 + 1] = xminmax(parts_range[l + 2 + 0], parts_minmax_new[4 + 1], parts_range[l + 2 + 1]);
        parts_minmax_new[4 + 3] = xminmax(parts_range[l + 2 + 0], parts_minmax_new[4 + 3], parts_range[l + 2 + 1]);
      }

      SL_TRACE_IF(DEBUG_OR_NOT, "%" sl_int_type_fmt ",%" sl_int_type_fmt ": 4. part_minmax_new: %f  %f  %f  %f  /  %f  %f  %f  %f", i, parts[i], parts_minmax_new[0 + 0], parts_minmax_new[0 + 1], parts_minmax_new[0 + 2], parts_minmax_new[0 + 3], parts_minmax_new[4 + 0], parts_minmax_new[4 + 1], parts_minmax_new[4 + 2], parts_minmax_new[4 + 3]);

      if (parts_minmax_new[0 + 0] != parts_minmax[j + 0 + 0] || parts_minmax_new[0 + 2] != parts_minmax[j + 0 + 2] || parts_minmax_new[4 + 0] != parts_minmax[j + 4 + 0] || parts_minmax_new[4 + 2] != parts_minmax[j + 4 + 2])
      {
        parts_minmax[j + 0 + 0] = parts_minmax_new[0 + 0];
        parts_minmax[j + 0 + 2] = parts_minmax_new[0 + 2];
        parts_minmax[j + 4 + 0] = parts_minmax_new[4 + 0];
        parts_minmax[j + 4 + 2] = parts_minmax_new[4 + 2];

        parts_update[parts[i] + 1] = 1;
      }

      if (parts_minmax_new[0 + 1] != parts_minmax[j + 0 + 1] || parts_minmax_new[0 + 3] != parts_minmax[j + 0 + 3] || parts_minmax_new[4 + 1] != parts_minmax[j + 4 + 1] || parts_minmax_new[4 + 3] != parts_minmax[j + 4 + 3])
      {
        parts_minmax[j + 0 + 1] = parts_minmax_new[0 + 1];
        parts_minmax[j + 0 + 3] = parts_minmax_new[0 + 3];
        parts_minmax[j + 4 + 1] = parts_minmax_new[4 + 1];
        parts_minmax[j + 4 + 3] = parts_minmax_new[4 + 3];

        parts_update[parts[i] - 1] = 1;
      }

      parts_update[parts[i]] = 0;

      /* refine or remove */
      if (refine)
      {
        /* bits left for partitioning? */
        if (rhigh >= rlow)
        {
          if (last_new_area == part_areas[i] && last_new_class == k) part_areas[i] = nareas_new - 1;
          else
          {
            /* update last_new_... */
            last_new_area = part_areas[i];
            last_new_class = k;

            /* create new area */
            elem_assign_at(&areas[part_areas[i]], lcs, &areas_new[nareas_new]);
            areas_new[nareas_new].size = local_counts[part_areas[i] * nclasses + k];
            part_areas[i] = nareas_new;
            ++nareas_new;
          }

        } else
        {
          /* save local count/weight for the later prefix calculations */
          final_locals[2 * (i - nparts_removed * direction) + 0] = lc;
          final_locals[2 * (i - nparts_removed * direction) + 1] = lw;
        }

        parts[i - nparts_removed * direction] = parts[i];
        part_areas[i - nparts_removed * direction] = part_areas[i];

      } else ++nparts_removed;

      rti_tstop(rti_tid_mpi_partition_radix2_while_check_post);
      
      i += direction;
    }

    if (direction > 0) parts_high -= nparts_removed;
    else parts_low += nparts_removed;

    direction *= -1;

/*    SL_NOTICE_IF(DEBUG_OR_NOT, "nparts = %" sl_int_type_fmt " vs. nareas_new = %" sl_int_type_fmt, nparts, nareas_new);*/

    rti_tstop(rti_tid_mpi_partition_radix2_while_check);
    
    /* switch areas */
    nareas = nareas_new;
    if (areas == areas0)
    {
      areas = areas1;
      areas_new = areas0;
    } else
    {
      areas = areas0;
      areas_new = areas1;
    }
  }

  rti_tstop(rti_tid_mpi_partition_radix2_while);

  /* create scounts */
  for (i = 0; i < size - 1; ++i) scounts[i] = sdispls[i + 1] - sdispls[i];
  scounts[size - 1] = s->size - sdispls[size - 1];

#ifdef SCOUNTS_SDISPLS
  printf("%d: scounts", rank);
  for (i = 0, j = 0; i < size; ++i) { printf("  %d", scounts[i]); j += scounts[i]; }
  printf(" = %" sl_int_type_fmt "\n", j);
  printf("%d: sdispls", rank);
  for (i = 0; i < size; ++i) printf("  %d", sdispls[i]);
  printf("\n");
#endif

#ifdef RCOUNTS_RDISPLS
  rcounts = sl_alloc(size, sizeof(int));
  rdispls = sl_alloc(size, sizeof(int));

  MPI_Alltoall(scounts, 1, MPI_INT, rcounts, 1, MPI_INT, comm);

  rdispls[0] = 0;
  for (i = 1; i < size; ++i) rdispls[i] = rdispls[i - 1] + rcounts[i - 1];

  printf("%d: rcounts", rank);
  for (i = 0; i < size; ++i) printf("  %d", rcounts[i]);
  printf("\n");
  printf("%d: rdispls", rank);
  for (i = 0; i < size; ++i) printf("  %d", rdispls[i]);
  printf("\n");

  sl_free(rcounts);
  sl_free(rdispls);
#endif

  sl_free(locals);
  sl_free(globals);

#ifdef WEIGHT_STATS
  partial_counts[size] = 0;
  partial_weights[size] = 0.0;
  for (i = 0; i < size; ++i)
  {
    partial_counts[i] = scounts[i];
    partial_weights[i] = 0.0;
    for (j = sdispls[i]; j < sdispls[i] + scounts[i]; ++j) partial_weights[i] += elem_weight_one(s, j);
    
    partial_counts[size] += partial_counts[i];
    partial_weights[size] += partial_weights[i];
  }

#ifdef HAVENT_MPI_IN_PLACE
  MPI_Reduce(partial_counts, partial_counts2, size + 1, int_mpi_datatype, MPI_SUM, 0, comm);
  MPI_Reduce(partial_weights, partial_weights2, size + 1, MPI_DOUBLE, MPI_SUM, 0, comm);
# define partial_counts   partial_counts2
# define partial_weights  partial_weights2
#else
  /* recvbuf requires workaround for an in-place/aliased-buffer-check-bug in mpich2 (fixed with rev 5518) */
  MPI_Reduce((rank == 0)?MPI_IN_PLACE:partial_counts, (rank == 0)?partial_counts:NULL, size + 1, int_mpi_datatype, MPI_SUM, 0, comm);
  MPI_Reduce((rank == 0)?MPI_IN_PLACE:partial_weights, (rank == 0)?partial_weights:NULL, size + 1, MPI_DOUBLE, MPI_SUM, 0, comm);
#endif

  if (rank == 0)
  {
    printf("%d: total_count: %" sl_int_type_fmt " vs. %" sl_int_type_fmt "\n", rank, total_count, partial_counts[size]);
    d = 0.0;
    vmin = 1.0;
    vmax = 0.0;
    for (i = 0; i < size; ++i)
    {
/*      printf("%d: %" sl_int_type_fmt " %" sl_int_type_fmt " / %f - %" sl_int_type_fmt " / %f\n", rank, i, partial_counts[i], (double) partial_counts[i] / partial_counts[size], (partial_counts[size] / size) - partial_counts[i], fabs(1.0 - ((double) partial_counts[i] * size / partial_counts[size])));*/
      d += fabs((partial_counts[size] / size) - partial_counts[i]);
      if (fabs(1.0 - ((double) partial_counts[i] * size / partial_counts[size])) < vmin) vmin = fabs(1.0 - ((double) partial_counts[i] * size / partial_counts[size]));
      if (fabs(1.0 - ((double) partial_counts[i] * size / partial_counts[size])) > vmax) vmax = fabs(1.0 - ((double) partial_counts[i] * size / partial_counts[size]));
    }
    printf("%d: min/max: %f / %f\n", rank, vmin, vmax);
    printf("%d: average_count: %" sl_int_type_fmt " - %f / %f\n", rank, partial_counts[size] / size, d / size, d / partial_counts[size]);

    printf("%d: total_weight: %f vs. %f\n", rank, total_weight, partial_weights[size]);
    d = 0.0;
    vmin = 1.0;
    vmax = 0.0;
    for (i = 0; i < size; ++i)
    {
/*      printf("%d: %" sl_int_type_fmt " %f / %f - %f / %f\n", rank, i, partial_weights[i], partial_weights[i] / partial_weights[size], (partial_weights[size] / size) - partial_weights[i], fabs(1.0 - (partial_weights[i] * size / partial_weights[size])));*/
      d += fabs((partial_weights[size] / size) - partial_weights[i]);
      if (fabs(1.0 - (partial_weights[i] * size / partial_weights[size])) < vmin) vmin = fabs(1.0 - (partial_weights[i] * size / partial_weights[size]));
      if (fabs(1.0 - (partial_weights[i] * size / partial_weights[size])) > vmax) vmax = fabs(1.0 - (partial_weights[i] * size / partial_weights[size]));
    }
    printf("%d: min/max: %f / %f\n", rank, vmin, vmax);
    printf("%d: average_weight: %f - %f / %f\n", rank, partial_weights[size] / size, d / size, d / partial_weights[size]);
  }
#endif

  rti_tstop(rti_tid_mpi_partition_radix2);

#if defined(TIMING_STATS) && defined(SL_USE_RTI_TIM)
  if (rank == 0)
  {
    printf("%d: mpi_partition_radix: %f\n", rank, rti_tlast(rti_tid_mpi_partition_radix2));
    printf("%d: mpi_partition_radix: sync: %f\n", rank, rti_tlast(rti_tid_mpi_partition_radix2_sync));
    printf("%d: mpi_partition_radix: while: %f\n", rank, rti_tlast(rti_tid_mpi_partition_radix2_while));
    printf("%d: mpi_partition_radix:   count: %f\n", rank, rti_tcumu(rti_tid_mpi_partition_radix2_while_count));
    printf("%d: mpi_partition_radix:   allreduce: %f\n", rank, rti_tcumu(rti_tid_mpi_partition_radix2_while_allreduce));
    printf("%d: mpi_partition_radix:   round1: %f\n", rank, rti_tcumu(rti_tid_mpi_partition_radix2_while_round1));
    printf("%d: mpi_partition_radix:     allgather: %f\n", rank, rti_tcumu(rti_tid_mpi_partition_radix2_while_round1_allgather));
    printf("%d: mpi_partition_radix:   exscan: %f\n", rank, rti_tlast(rti_tid_mpi_partition_radix2_while_exscan));
    printf("%d: mpi_partition_radix:   check: %f\n", rank, rti_tcumu(rti_tid_mpi_partition_radix2_while_check));
    printf("%d: mpi_partition_radix:     pre: %f\n", rank, rti_tlast(rti_tid_mpi_partition_radix2_while_check_pre));
    printf("%d: mpi_partition_radix:     classes: %f\n", rank, rti_tlast(rti_tid_mpi_partition_radix2_while_check_classes));
    printf("%d: mpi_partition_radix:     final: %f\n", rank, rti_tlast(rti_tid_mpi_partition_radix2_while_check_final));
    printf("%d: mpi_partition_radix:     post: %f\n", rank, rti_tlast(rti_tid_mpi_partition_radix2_while_check_post));
  }
#endif

  return 0;
}
コード例 #28
0
/*
 * Complete a remote file
 */
static unsigned char
complete_remote(char *word, int list)
{
	static StringList *dirlist;
	static char	 lastdir[MAXPATHLEN];
	StringList	*words;
	char		 dir[MAXPATHLEN];
	char		*file, *cp;
	int		 i;
	unsigned char	 rv;

	char *dummyargv[] = { "complete", dir, NULL };

	if ((file = strrchr(word, '/')) == NULL) {
		dir[0] = '.';
		dir[1] = '\0';
		file = word;
	} else {
		cp = file;
		while (*cp == '/' && cp > word)
			cp--;
		(void)strlcpy(dir, word, (size_t)(cp - word + 2));
		file++;
	}

	if (dirchange || strcmp(dir, lastdir) != 0) {	/* dir not cached */
		char *emesg;

		sl_free(dirlist, 1);
		dirlist = sl_init();

		mflag = 1;
		emesg = NULL;
#ifndef SMALL
		if (debug)
			(void)putc('\n', ttyout);
#endif /* !SMALL */
		while ((cp = remglob(dummyargv, 0, &emesg)) != NULL) {
			char *tcp;

			if (!mflag)
				continue;
			if (*cp == '\0') {
				mflag = 0;
				continue;
			}
			tcp = strrchr(cp, '/');
			if (tcp)
				tcp++;
			else
				tcp = cp;
			tcp = strdup(tcp);
			if (tcp == NULL)
				errx(1, "Can't allocate memory for remote dir");
			sl_add(dirlist, tcp);
		}
		if (emesg != NULL) {
			fprintf(ttyout, "\n%s\n", emesg);
			return (CC_REDISPLAY);
		}
		(void)strlcpy(lastdir, dir, sizeof lastdir);
		dirchange = 0;
	}

	words = sl_init();
	for (i = 0; i < dirlist->sl_cur; i++) {
		cp = dirlist->sl_str[i];
		if (strlen(file) > strlen(cp))
			continue;
		if (strncmp(file, cp, strlen(file)) == 0)
			sl_add(words, cp);
	}
	rv = complete_ambiguous(file, list, words);
	sl_free(words, 0);
	return (rv);
}
コード例 #29
0
FILE *
ftpd_popen(char *argv[], const char *ptype, int stderrfd)
{
	FILE *iop;
	int argc, pdes[2], pid, isls;
	char **pop;
	StringList *sl;

	iop = NULL;
	isls = 0;
	if ((*ptype != 'r' && *ptype != 'w') || ptype[1])
		return (NULL);

	if (!pids) {
		if ((fds = getdtablesize()) <= 0)
			return (NULL);
		if ((pids = (int *)malloc((u_int)(fds * sizeof(int)))) == NULL)
			return (NULL);
		memset(pids, 0, fds * sizeof(int));
	}
	if (pipe(pdes) < 0)
		return (NULL);

	if ((sl = sl_init()) == NULL)
		goto pfree;

					/* glob each piece */
	if (sl_add(sl, ftpd_strdup(argv[0])) == -1)
		goto pfree;
	for (argc = 1; argv[argc]; argc++) {
		glob_t gl;
		int flags = GLOB_BRACE|GLOB_NOCHECK|GLOB_TILDE|GLOB_LIMIT;

		memset(&gl, 0, sizeof(gl));
		if (glob(argv[argc], flags, NULL, &gl)) {
			if (sl_add(sl, ftpd_strdup(argv[argc])) == -1) {
				globfree(&gl);
				goto pfree;
			}
		} else {
			for (pop = gl.gl_pathv; *pop; pop++) {
				if (sl_add(sl, ftpd_strdup(*pop)) == -1) {
					globfree(&gl);
					goto pfree;
				}
			}
		}
		globfree(&gl);
	}
	if (sl_add(sl, NULL) == -1)
		goto pfree;

#ifndef NO_INTERNAL_LS
	isls = (strcmp(sl->sl_str[0], INTERNAL_LS) == 0);
#endif

	pid = isls ? fork() : vfork();
	switch (pid) {
	case -1:			/* error */
		(void)close(pdes[0]);
		(void)close(pdes[1]);
		goto pfree;
		/* NOTREACHED */
	case 0:				/* child */
		if (*ptype == 'r') {
			if (pdes[1] != STDOUT_FILENO) {
				dup2(pdes[1], STDOUT_FILENO);
				(void)close(pdes[1]);
			}
			if (stderrfd == -1)
				(void)close(STDERR_FILENO);
			else
				dup2(stderrfd, STDERR_FILENO);
			(void)close(pdes[0]);
		} else {
			if (pdes[0] != STDIN_FILENO) {
				dup2(pdes[0], STDIN_FILENO);
				(void)close(pdes[0]);
			}
			(void)close(pdes[1]);
		}
#ifndef NO_INTERNAL_LS
		if (isls) {	/* use internal ls */
			optreset = optind = optopt = 1;
			closelog();
			exit(ls_main(sl->sl_cur - 1, sl->sl_str));
		}
#endif

		execv(sl->sl_str[0], sl->sl_str);
		_exit(1);
	}
	/* parent; assume fdopen can't fail...  */
	if (*ptype == 'r') {
		iop = fdopen(pdes[0], ptype);
		(void)close(pdes[1]);
	} else {
		iop = fdopen(pdes[1], ptype);
		(void)close(pdes[0]);
	}
	pids[fileno(iop)] = pid;

 pfree:
	if (sl)
		sl_free(sl, 1);
	return (iop);
}
コード例 #30
0
ファイル: complete.c プロジェクト: AhmadTux/DragonFlyBSD
/*
 * Complete a local file
 */
static unsigned char
complete_local(char *word, int list)
{
	StringList *words;
	char dir[MAXPATHLEN];
	char *file;
	DIR *dd;
	struct dirent *dp;
	unsigned char rv;
	size_t len;

	if ((file = strrchr(word, '/')) == NULL) {
		dir[0] = '.';
		dir[1] = '\0';
		file = word;
	} else {
		if (file == word) {
			dir[0] = '/';
			dir[1] = '\0';
		} else
			(void)strlcpy(dir, word, file - word + 1);
		file++;
	}
	if (dir[0] == '~') {
		char *p;

		if ((p = globulize(dir)) == NULL)
			return (CC_ERROR);
		(void)strlcpy(dir, p, sizeof(dir));
		free(p);
	}

	if ((dd = opendir(dir)) == NULL)
		return (CC_ERROR);

	words = ftp_sl_init();
	len = strlen(file);

	for (dp = readdir(dd); dp != NULL; dp = readdir(dd)) {
		if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, ".."))
			continue;

#if defined(DIRENT_MISSING_D_NAMLEN)
		if (len > strlen(dp->d_name))
			continue;
#else
		if (len > dp->d_namlen)
			continue;
#endif
		if (strncmp(file, dp->d_name, len) == 0) {
			char *tcp;

			tcp = ftp_strdup(dp->d_name);
			ftp_sl_add(words, tcp);
		}
	}
	closedir(dd);

	rv = complete_ambiguous(file, list, words);
	if (rv == CC_REFRESH) {
		struct stat sb;
		char path[MAXPATHLEN];

		(void)strlcpy(path, dir,		sizeof(path));
		(void)strlcat(path, "/",		sizeof(path));
		(void)strlcat(path, words->sl_str[0],	sizeof(path));

		if (stat(path, &sb) >= 0) {
			char suffix[2] = " ";

			if (S_ISDIR(sb.st_mode))
				suffix[0] = '/';
			if (el_insertstr(el, suffix) == -1)
				rv = CC_ERROR;
		}
	}
	sl_free(words, 1);
	return (rv);
}