Esempio n. 1
0
static void *kts_worker(void *data)
{
	kts_worker_t *w = (kts_worker_t*)data;
	for (;;) {
		int i, to_sync, n_slots;
		// update the task and slot information
		pthread_mutex_lock(&w->t->lock);
		while (w->i >= w->t->n_slots && !w->t->to_sync)
			pthread_cond_wait(&w->t->cv, &w->t->lock);
		to_sync = w->t->to_sync, n_slots = w->t->n_slots;
		pthread_mutex_unlock(&w->t->lock);
		// process the pending slot if there is any
		if (w->pending >= 0 && w->pending < n_slots) {
			process_slot(w->t, w->pending, w - w->t->w);
			w->pending = -1;
		}
		// process slots assigned to the current worker
		for (;;) {
			i = __sync_fetch_and_add(&w->i, w->t->n_threads);
			if (i >= n_slots) break;
			process_slot(w->t, i, w - w->t->w);
		}
		// steal slots from other workers
		for (;;) {
			int min = 0x7fffffff, min_i = 0;
			for (i = 0; i < w->t->n_threads; ++i)
				if (min > w->t->w[i].i) min = w->t->w[i].i, min_i = i;
			i = __sync_fetch_and_add(&w->t->w[min_i].i, w->t->n_threads);
			if (i >= n_slots) {
				w->pending = i;
				break;
			} else process_slot(w->t, i, w - w->t->w);
		}
		if (to_sync) break;
	}
	pthread_exit(0);
}
Esempio n. 2
0
/* Print cached content to stdout, generate the content if necessary. */
int cache_process(int size, const char *path, const char *key, int ttl,
		  cache_fill_fn fn, void *cbdata)
{
	unsigned long hash;
	int i;
	struct strbuf filename = STRBUF_INIT;
	struct strbuf lockname = STRBUF_INIT;
	struct cache_slot slot;
	int result;

	/* If the cache is disabled, just generate the content */
	if (size <= 0) {
		fn(cbdata);
		return 0;
	}

	/* Verify input, calculate filenames */
	if (!path) {
		cache_log("[cgit] Cache path not specified, caching is disabled\n");
		fn(cbdata);
		return 0;
	}
	if (!key)
		key = "";
	hash = hash_str(key) % size;
	strbuf_addstr(&filename, path);
	strbuf_ensure_end(&filename, '/');
	for (i = 0; i < 8; i++) {
		strbuf_addf(&filename, "%x", (unsigned char)(hash & 0xf));
		hash >>= 4;
	}
	strbuf_addbuf(&lockname, &filename);
	strbuf_addstr(&lockname, ".lock");
	slot.fn = fn;
	slot.cbdata = cbdata;
	slot.ttl = ttl;
	slot.cache_name = filename.buf;
	slot.lock_name = lockname.buf;
	slot.key = key;
	slot.keylen = strlen(key);
	result = process_slot(&slot);

	strbuf_release(&filename);
	strbuf_release(&lockname);
	return result;
}