예제 #1
0
/** Shuffle an index to avoid excessive lock contention in models 
	where topologically adjacent objects are loaded sequentially
 **/
void index_shuffle(INDEX *index)	/**< the index to shuffle */
{
	int i, size = index->last_used - index->first_used;
	for (i=0; i<size; i++)
		list_shuffle(index->ordinal[i]);
	output_verbose("shuffled %d lists in index %d", size, index->id);
}
예제 #2
0
/*
 *	Write a binary tree node to disk.
 */
int pdb_write_tree_node_cb(struct pdb* dbptr, FILE* fptr,
	struct pdb_node_t* nptr, int tabs) {

	struct binaryTree* tptr;
	struct linkList* lptr;
	struct linkNode* lnptr;

	/*
	 *	Create a list from the tree so we can iterate through it.
	 */
	tptr = nptr->data;
	lptr = list_create();
	tree_to_list(tptr, lptr);
	lnptr = lptr->root;
	
	/*
	 *	Shuffle tree (if set).
	 */
	if (pdb_is_set(dbptr, PDB_WRITE_SHUFFLE))
		list_shuffle(lptr);
	
	/*
	 *	Set PDB_WRITE_NODE_FIRST_ID as the first in the list
	 *	if PDB_WRITE_NODE_FIRST is set.
	 *	Only if root node.
	 */
	if (!tabs) {
		if (pdb_is_set(dbptr, PDB_WRITE_NODE_FIRST)) {
			while (lnptr) {
				nptr = lnptr->data;
				if (!strcmp(nptr->id, PDB_WRITE_NODE_FIRST_ID)) {
					list_free_node(lptr, lnptr, 0, NULL);
					list_add_node_front(lptr, nptr);
					break;
				}
				lnptr = lnptr->next;
			}
		}
	}
	
	/*
	 *	Write all children to disk.
	 */
	lnptr = lptr->root;
	while (lnptr) {
		nptr = lnptr->data;
		if (!pdb_standard_write_node(dbptr, fptr, nptr, tabs)) {
			list_free(lptr, 0, NULL);
			return 0;
		}
		lnptr = lnptr->next;
	}
	
	/*
	 *	Free temp list (but not data).
	 */
	list_free(lptr, 0, NULL);
	
	return 1;
}
예제 #3
0
파일: buffer.c 프로젝트: yogpstop/MyGCCProj
THREAD_RAC buffer_thread(void *arg) {
	size_t cur = 0;
	buf_str *ctx = arg;
	volatile unsigned char *sync = ctx->p.update + ctx->cur_id;
	MUTEX_LOCK(ctx->p.mutex + ctx->cur_id);
	*sync = 0xFF;
	while (*sync);
	while(1) {
		if (force_exit_signal) break;
		buffering_do(ctx, cur++);
		if (!ctx->list[cur].n) {
			list_shuffle(ctx->list);
			cur = 0;
		}
	}
	MUTEX_UNLOCK(ctx->p.mutex + ctx->cur_id);
	return 0;
}
예제 #4
0
파일: main.c 프로젝트: yogpstop/MyGCCProj
int main(int argc, char **argv) {
	int i;
	buf_str ctx;
	memset(&ctx, 0, sizeof(buf_str));
	ctx.p.period = PERIOD_SIZE;
	ctx.p.buf_max = 0xFFF;//TODO variable buf
	ctx.p.mutex = malloc(sizeof(MUTEX_T) * (ctx.p.buf_max + 1));
	for (i = 0; i <= ctx.p.buf_max; i++) {
		MUTEX_INIT(ctx.p.mutex + i);
	}
	ctx.p.update = malloc(sizeof(unsigned char) * (ctx.p.buf_max + 1));
	memset(ctx.p.update, 0, sizeof(unsigned char) * (ctx.p.buf_max + 1));
	ctx.p.buf = malloc((ctx.p.buf_max + 1) * ctx.p.period * CHANNELS * BITS / 8);
	//FIXME memory allocation failed
	ctx.list = listing(argv + 1);
	if(!ctx.list) force_exit_signal = 1;
	else list_shuffle(ctx.list);
	THREAD_T play, buffer;
#ifndef _WIN32
	pthread_attr_t rt;
	struct sched_param p = {};
	p.sched_priority = sched_get_priority_max(SCHED_RR);
	pthread_attr_init(&rt);
	pthread_attr_setinheritsched(&rt, PTHREAD_EXPLICIT_SCHED);
	pthread_attr_setschedpolicy(&rt, SCHED_RR);
	pthread_attr_setschedparam(&rt, &p);
#endif
	CREATE_THREAD(buffer, buffer_thread, &ctx);
	CREATE_THREAD_RT(play, play_thread, &ctx.p, &rt);
	console();
	JOIN_THREAD(buffer);
	JOIN_THREAD(play);
	list_full_remove(ctx.list);
	for (i = 0; i <= ctx.p.buf_max; i++) {
		MUTEX_DESTROY(ctx.p.mutex + i);
	}
	free(ctx.p.mutex);
	free(ctx.p.update);
	free(ctx.p.buf);
	return 0;
}
예제 #5
0
listhead_t *run_net_tests(int concurrency, char *sourceip4, char *sourceip6)
{
	int maxfd;

	list_shuffle(pendingtests);

	/* 
	 * Determine how many tests can run in parallel.
	 * If no --concurrency set by user, default to (FD_SETSIZE / 4) - typically 256.
	 * But never go above the ressource limit that is set, or above FD_SETSIZE.
	 * And we save some fd's - 20 - for stdio, libs etc.
	 */
	{
		int absmaxconcurrency = (FD_SETSIZE - 20);
		struct rlimit lim;

		getrlimit(RLIMIT_NOFILE, &lim);
		if ((lim.rlim_cur > 20) && ((lim.rlim_cur - 20) < absmaxconcurrency)) absmaxconcurrency = (lim.rlim_cur - 20);

		if (concurrency == 0) concurrency = (FD_SETSIZE / 4);
		if (concurrency > absmaxconcurrency) concurrency = absmaxconcurrency;
	}

	/* Loop to process data */
	do {
		fd_set fdread, fdwrite;
		int n;
		struct timeval tmo;
		myconn_t *rec;
		listitem_t *pcur, *pnext;
		int lookupsposted = 0;

		dbgprintf("*** Starting test loop ***\n");
		/* Start some more tests */
		pcur = pendingtests->head;
		while (pcur && (activetests->len < concurrency) && (lookupsposted < concurrency)) {
			rec = (myconn_t *)pcur->data;

			dbgprintf("  Test: %s\n", rec->testspec);

			/* 
			 * Must save the pointer to the next pending test now, 
			 * since we may move the current item from the pending
			 * list to the active list before going to the next
			 * item in the pending-list.
			 */
			pnext = pcur->next;

			if (rec->netparams.lookupstatus == LOOKUP_NEEDED) {
				dbgprintf("    LOOKUP_NEEDED\n");
				lookupsposted++;
				dns_lookup(rec);
			}

			if ((rec->netparams.lookupstatus == LOOKUP_ACTIVE) || (rec->netparams.lookupstatus == LOOKUP_NEEDED)) {
				/* DNS lookup in progress, skip this test until lookup completes */
				dbgprintf("    lookup in progress: %s\n", (rec->netparams.lookupstatus == LOOKUP_ACTIVE) ? "ACTIVE" : "NEEDED");
				pcur = pnext;
				continue;
			}
			else if (rec->netparams.lookupstatus == LOOKUP_FAILED) {
				/* DNS lookup determined that this host does not have a valid IP. */
				dbgprintf("    LOOKUP_FAILED\n");
				switch (dnsstrategy) {
				  case DNS_STRATEGY_HOSTNAME:
					/* DNS failed -> test failed */
					list_item_move(donetests, pcur, rec->testspec);
					rec->talkresult = TALK_CANNOT_RESOLVE;
					break;
				  case DNS_STRATEGY_STANDARD:
				  case DNS_STRATEGY_IP:	/* This one cannot really happen */
					/* Use IP from hosts.cfg, if it is valid */
					if (!conn_null_ip(xmh_item(rec->hostinfo, XMH_IP))) {
						xfree(rec->netparams.destinationip);
						rec->netparams.destinationip = strdup(xmh_item(rec->hostinfo, XMH_IP));
						rec->netparams.lookupstatus = LOOKUP_COMPLETED;
					}
					else {
						list_item_move(donetests, pcur, rec->testspec);
						rec->talkresult = TALK_CANNOT_RESOLVE;
					}
					break;
				}
				pcur = pnext;
				continue;
			}

			switch (rec->talkprotocol) {
			  case TALK_PROTO_PLAIN:
			  case TALK_PROTO_HTTP:
			  case TALK_PROTO_NTP:
			  case TALK_PROTO_LDAP:
			  case TALK_PROTO_EXTERNAL:
				if (!rec->teststarttime) rec->teststarttime = getcurrenttime(NULL);
				dbgprintf("    conn_prepare_connection()\n");
				if (!rec->netparams.sourceip && (sourceip4 || sourceip6)) {
					switch (conn_is_ip(rec->netparams.destinationip)) {
					  case 4: rec->netparams.sourceip = sourceip4; break;
					  case 6: rec->netparams.sourceip = sourceip6; break;
					}
				}
				if (conn_prepare_connection(rec->netparams.destinationip, 
							rec->netparams.destinationport, 
							rec->netparams.socktype,
							rec->netparams.sourceip, 
							rec->netparams.sslhandling, rec->netparams.sslname, rec->netparams.sslcertfn, rec->netparams.sslkeyfn, 
							rec->timeout*1000000,
							rec->netparams.callback, rec)) {
					dbgprintf("\tmoved to activetests, target %s, timeout %d\n", 
						  rec->netparams.destinationip, rec->timeout);
					list_item_move(activetests, pcur, rec->testspec);
				}
				else {
					dbgprintf("\tmoved to failedtests\n");
					rec->talkresult = TALK_CONN_FAILED;
					list_item_move(donetests, pcur, rec->testspec);
				}
				break;

			  case TALK_PROTO_DNSQUERY:
				dbgprintf("    dns_start_query()\n");
				if (dns_start_query(rec, rec->netparams.destinationip)) {
					dbgprintf("\tmoved to activetests\n");
					list_item_move(activetests, pcur, rec->testspec);
				}
				else {
					dbgprintf("\tmoved to failedtests\n");
					rec->talkresult = TALK_CONN_FAILED;
					list_item_move(donetests, pcur, rec->testspec);
				}
				break;

			  case TALK_PROTO_PING:
				dbgprintf("    PING test, queued\n");
				rec->talkresult = TALK_OK;
				list_item_move(donetests, pcur, rec->testspec);
				break;

			  default:
				dbgprintf("    Huh?\n");
				break;
			}

			pcur = pnext;
		}

		maxfd = conn_fdset(&fdread, &fdwrite);
		// dbgprintf("Setting up select - conn_fdset has maxfd=%d\n", maxfd);
		dns_add_active_fds(activetests, &maxfd, &fdread, &fdwrite);
		// dbgprintf("Setting up select - dns_add_active_fds set maxfd=%d\n", maxfd);

		if (maxfd > 0) {
			tmo.tv_sec = 1; tmo.tv_usec = 0;
			n = select(maxfd+1, &fdread, &fdwrite, NULL, &tmo);
			if (n < 0) {
				if (errno != EINTR) {
					errprintf("FATAL: select() returned error %s\n", strerror(errno));
					return NULL;
				}
			}

			conn_process_active(&fdread, &fdwrite);
			dns_process_active(activetests, &fdread, &fdwrite);
		}

		conn_trimactive();
		dns_finish_queries(activetests);
		dbgprintf("Active: %d, pending: %d\n", activetests->len, pendingtests->len);
	}
	while ((activetests->len + pendingtests->len) > 0);

	dns_finish_queries(donetests);

	return donetests;
}