ThermalForce::ThermalForce(Cloud * const C, const double redFactor) 
: Force(C), evenRandCache(new RandCache[C->n/DOUBLE_STRIDE]), oddRandCache(new RandCache[C->n/DOUBLE_STRIDE]),
#ifdef DISPATCH_QUEUES
evenRandGroup(dispatch_group_create()), oddRandGroup(dispatch_group_create()),
randQueue(dispatch_queue_create("com.DEMON.ThermalForce", NULL)),
#endif
heatVal(redFactor) {
#ifdef DISPATCH_QUEUES
    dispatch_group_async(oddRandGroup, randQueue, ^{
#endif
    for (cloud_index i = 0, e = cloud->n/DOUBLE_STRIDE; i < e; i++)
        oddRandCache[i] = RandCache(cloud->rands);
#ifdef DISPATCH_QUEUES
    });
static void tests(void)
{
//    CFStringRef messageToUser = CFSTR("OK to sync with world?");
//    CFStringRef messageToUser = CFSTR("Allow “Emily‘s iPad to use your iCloud Keychain?");
#if !TARGET_IPHONE_SIMULATOR
#if TARGET_OS_EMBEDDED
    CFStringRef our_peer_id = (CFStringRef)MGCopyAnswer(kMGQUserAssignedDeviceName, NULL);
#else
    CFStringRef our_peer_id = CFSTR("🔥💩");
#endif
#else
    CFStringRef our_peer_id = CFSTR("Emily‘s iPad");
#endif

    CFStringRef messageToUser = CFStringCreateWithFormat(kCFAllocatorDefault, 0, CFSTR("Allow “%@” to use your iCloud Keychain?"), our_peer_id);
    dispatch_queue_t processQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_group_t work_group = dispatch_group_create();

    // Prep the group for exitting the whole shebang.
    dispatch_group_enter(work_group);
    dispatch_group_notify(work_group, processQueue, ^
        {
            printf("Exiting via dispatch_group_notify; all work done\n");
            CFRunLoopStop(CFRunLoopGetMain());
        //  exit(0);
        });
Beispiel #3
0
int main (int argc, const char * argv[]) {
	dispatch_group_t	mg = dispatch_group_create();
	dispatch_semaphore_t ds;
	__block int numRunning = 0;
	int	qWidth = 5;		
	int numWorkBlocks = 100;
	
	if (argc >= 2) {
		qWidth = atoi(argv[1]);	// use the command 1st line parameter as the queue width
		if (qWidth==0) qWidth=1; // protect against bad values
	}
	
	if (argc >=3) {
		numWorkBlocks = atoi(argv[2]);	// use the 2nd command line parameter as the queue width
		if (numWorkBlocks==0) numWorkBlocks=1; // protect against bad values
	}
	
	printf("Starting dispatch semaphore test to simulate a %d wide dispatch queue\n", qWidth );
	ds = dispatch_semaphore_create(qWidth);
	
	int i;
	for (i=0; i<numWorkBlocks; i++) {
		// synchronize the whole shebang every 25 work units...
		if (i % 25 == 24) {
			dispatch_group_async(mg,dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{
				// wait for all pending work units to finish up... 
				for (int x=0; x<qWidth; x++) dispatch_semaphore_wait(ds, DISPATCH_TIME_FOREVER);
				// do the thing that is critical here
				printf("doing something critical...while %d work units are running \n",numRunning);
				// and let work continue unimpeeded
				for (int x=0; x<qWidth; x++) dispatch_semaphore_signal(ds);
			});
		} else {
Beispiel #4
0
void test_dispatch_latency(unsigned samples, unsigned sleeptime)
{
    unsigned i;

    uint64_t *lat = (uint64_t *)malloc(sizeof(uint64_t) * 3);
    uint64_t *history = (uint64_t *)malloc(sizeof(uint64_t) * samples);

    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_group_t group = dispatch_group_create();

    for (i = 0; i < samples; i++) {
        usleep(sleeptime);

        /*
         lat[0] to lat[1] is latency to block execution
         lat[1] to lat[2] is latency from block execution to block synchronization
         */
        lat[0] = libtime_cpu();
        dispatch_group_async(group, queue, ^{ lat[1] = libtime_cpu(); });
        dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
        lat[2] = libtime_cpu();

        /*
        printf("%04u lat[0] = %" PRIu64 "\n", i, lat[0]);
        printf("%04u lat[1] = %" PRIu64 ", %" PRIu64 "\n", i, lat[1], lat[1] - lat[0]);
        printf("%04u lat[2] = %" PRIu64 ", %" PRIu64 "\n", i, lat[2], lat[2] - lat[1]);
        */

        history[i] = lat[1] - lat[0];
        //history[i] = lat[2] - lat[1];
    }
Beispiel #5
0
static void
render(unsigned char *img, int comps, int w, int h, int nsubsamples, int tilew, int tileh)
{

    float *fimg = (float *)malloc(sizeof(float) * w * h * 3);
    memset((void *)fimg, 0, sizeof(float) * w * h * 3);
    
    dispatch_queue_t dque = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    //dispatch_queue_t dque = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
    dispatch_group_t dgroup = dispatch_group_create();
    
    int i, j;
    for (j = 0; j < h; j += tileh) {
        for (i = 0; i < w; i += tilew) {

            void (^renderblock)(void) = ^{
                render_tile(img, comps, fimg, w, h, nsubsamples, i, j, tilew, tileh);
            };
            //renderblock();
            dispatch_group_async(dgroup, dque, renderblock);
        }
    }
    
    dispatch_group_wait(dgroup, DISPATCH_TIME_FOREVER);
    //dispatch_release(dgroup);
}
static void do_test(void)
{
	size_t i;
	char buf[1000];
	dispatch_group_t g = dispatch_group_create();

	for (i = 0; i < QUEUES; i++) {
#ifdef WIN32
		_snprintf(buf, sizeof(buf), "com.example.memoryload-node#%ld", i);
#else
		snprintf(buf, sizeof(buf), "com.example.memoryload-node#%ld", (long int)i);
#endif
		queues[i] = dispatch_queue_create(buf, NULL);
		dispatch_suspend(queues[i]);
	}

	for (i = 0; i < QUEUES; i++) {
		dispatch_group_async_f(g, queues[i], g, start_node);
	}

	dispatch_group_notify_f(g, dispatch_get_main_queue(), NULL, collect);

	for (i = 0; i < QUEUES; i++) {
		dispatch_resume(queues[i]);
		dispatch_release(queues[i]);
	}
}
static void
test_io_close(int with_timer, bool from_path)
{
	#define chunks 4
	#define READSIZE (512*1024)
	unsigned int i;
	const char *path = LARGE_FILE;
	int fd = open(path, O_RDONLY);
	if (fd == -1) {
		if (errno == ENOENT) {
			test_skip("Large file not found");
			return;
		}
		test_errno("open", errno, 0);
		test_stop();
	}
#ifdef F_GLOBAL_NOCACHE
	if (fcntl(fd, F_GLOBAL_NOCACHE, 1) == -1) {
		test_errno("fcntl F_GLOBAL_NOCACHE", errno, 0);
		test_stop();
	}
#endif
	struct stat sb;
	if (fstat(fd, &sb)) {
		test_errno("fstat", errno, 0);
		test_stop();
	}
	const size_t size = (size_t)sb.st_size / chunks;
	const int expected_error = with_timer? ECANCELED : 0;
	dispatch_source_t t = NULL;
	dispatch_group_t g = dispatch_group_create();
	dispatch_group_enter(g);
	void (^cleanup_handler)(int error) = ^(int error) {
		test_errno("create error", error, 0);
		dispatch_group_leave(g);
		close(fd);
	};
	dispatch_io_t io;
	if (!from_path) {
		io = dispatch_io_create(DISPATCH_IO_RANDOM, fd,
				dispatch_get_global_queue(0, 0), cleanup_handler);
	} else {
#if DISPATCHTEST_IO_PATH
		io = dispatch_io_create_with_path(DISPATCH_IO_RANDOM, path, O_RDONLY, 0,
				dispatch_get_global_queue(0, 0), cleanup_handler);
#endif
	}
	dispatch_io_set_high_water(io, READSIZE);
	if (with_timer == 1) {
		dispatch_io_set_low_water(io, READSIZE);
		dispatch_io_set_interval(io,  2 * NSEC_PER_SEC,
				DISPATCH_IO_STRICT_INTERVAL);
	} else if (with_timer == 2) {
		t = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0,
				dispatch_get_global_queue(0,0));
		dispatch_retain(io);
		dispatch_source_set_event_handler(t, ^{
			dispatch_io_close(io, DISPATCH_IO_STOP);
			dispatch_source_cancel(t);
		});
Beispiel #8
0
static VALUE
rb_group_init(VALUE self, SEL sel)
{
    RGroup(self)->group = dispatch_group_create();
    assert(RGroup(self)->group != NULL);
    
    return self;
}
Beispiel #9
0
__XDISPATCH_USE_NAMESPACE


group::group ()
    : object(),
      m_native( dispatch_group_create() )
{
    XDISPATCH_ASSERT( m_native );
}
RequestTimer::RequestTimer(RequestInjectionData* data)
    : m_reqInjectionData(data)
{
  // Unlike the canonical Linux implementation, this does not distinguish
  // between whether we wanted real seconds or CPU seconds -- you always get
  // real seconds. There isn't a nice way to get CPU seconds on OS X that I've
  // found, outside of setitimer, which has its own configurability issues. So
  // we just always give real seconds, which is "close enough".

  m_timerGroup = dispatch_group_create();
}
Beispiel #11
0
void
test_proc(pid_t bad_pid)
{
	dispatch_source_t proc_s[PID_CNT], proc;
	int res;
	pid_t pid, monitor_pid;

	event_cnt = 0;
	// Creates a process and register multiple observers.  Send a signal,
	// exit the process, etc., and verify all observers were notified.

	posix_spawnattr_t attr;
	res = posix_spawnattr_init(&attr);
	assert(res == 0);
#if HAVE_DECL_POSIX_SPAWN_START_SUSPENDED
	res = posix_spawnattr_setflags(&attr, POSIX_SPAWN_START_SUSPENDED);
	assert(res == 0);
#endif

	char* args[] = {
		"/bin/sleep", "2", NULL
	};

	res = posix_spawnp(&pid, args[0], NULL, &attr, args, NULL);
	if (res < 0) {
		perror(args[0]);
		exit(127);
	}

	res = posix_spawnattr_destroy(&attr);
	assert(res == 0);

	dispatch_group_t group = dispatch_group_create();

	assert(pid > 0);
	monitor_pid = bad_pid ? bad_pid : pid; // rdar://problem/8090801

	int i;
	for (i = 0; i < PID_CNT; ++i) {
		dispatch_group_enter(group);
		proc = proc_s[i] = dispatch_source_create(DISPATCH_SOURCE_TYPE_PROC,
				monitor_pid, DISPATCH_PROC_EXIT, dispatch_get_global_queue(0, 0));
		test_ptr_notnull("dispatch_source_proc_create", proc);
		dispatch_source_set_event_handler(proc, ^{
			long flags = dispatch_source_get_data(proc);
			test_long("DISPATCH_PROC_EXIT", flags, DISPATCH_PROC_EXIT);
			event_cnt++;
			dispatch_source_cancel(proc);
		});
		dispatch_source_set_cancel_handler(proc, ^{
			dispatch_group_leave(group);
		});
static void tests(void)
{
    SKIP: {
        skip("Skipping ckdclient tests because CloudKeychainProxy.xpc is not installed", kTestTestCount, XPCServiceInstalled());
 //       dispatch_queue_t dqueue = dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
            xpc_queue = dispatch_queue_create("sc_90_ckdclient", DISPATCH_QUEUE_SERIAL);

        sDispatchGroup = dispatch_group_create();
        
        initializeTestData();
        basicKVSTests(sDispatchGroup);
    }
}
Beispiel #13
0
int main(int argc, const char *argv[]) {
	dispatch_queue_t queue =
			dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0);

	dispatch_group_t group = dispatch_group_create();

	__block int sum = 0;

	for (int i = 0; i < 10; i++) {
		dispatch_group_async(group, queue, ^{
			printf("+%d\n", i);
			sum += i;
		});
	}
Beispiel #14
0
void ISPCLaunch(void *func, void *data) {
    if (!initialized) {
        while (1) {
            if (lAtomicCompareAndSwap32(&lock, 1, 0) == 0) {
                if (!initialized) {
                    gcdQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
                    gcdGroup = dispatch_group_create();
                    lInitTaskInfo();
                    __asm__ __volatile__("mfence":::"memory");
                    initialized = 1;
                }
                lock = 0;
                break;
            }
        }
    }
Beispiel #15
0
void dispatch_apply_fwrite(uint32_t* data) {
    dispatch_queue_t queue =
        dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_group_t group = dispatch_group_create();

    for (int fi = 0; fi < kNumFiles; ++fi)
        dispatch_group_enter(group);  // There's no dispatch_group_apply().

    dispatch_apply(kNumFiles, queue, ^(size_t fi) {
        char buf[80];
        sprintf(buf, "f%02d.out", (int)fi);
        FILE* f = fopen(buf, "wb");
        fwrite(data + fi * kIntChunkSize, 1, kChunkSize, f);
        fclose(f);
        dispatch_group_leave(group);
    });
Beispiel #16
0
/* Lua-side of rendering context */
static void create_lua_context (struct vox_engine *engine)
{
    lua_State *L = engine->L;

    if (engine->flags & VOX_ENGINE_DEBUG) {
        /* In debug mode we just create an empty table for context. */
        lua_newtable (L);
    } else {
        struct context_data *data = lua_newuserdata (L, sizeof (struct context_data));
        luaL_getmetatable (L, CONTEXT_META);
        lua_setmetatable (L, -2);
        data->context = engine->ctx;

        data->rendering_group = dispatch_group_create ();
        data->rendering_queue = dispatch_queue_create ("scene operations", 0);
    }
}
Beispiel #17
0
void
test_short_timer(void)
{
	// Add a large number of timers with suspended target queue in front of
	// the timer being measured <rdar://problem/7401353>
	g = dispatch_group_create();
	q = dispatch_queue_create("q", NULL);
	int i;
	for (i = 0; i < N; i++) {
		t[i] = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, q);
		dispatch_source_set_timer(t[i], DISPATCH_TIME_NOW, interval, 0);
		dispatch_group_enter(g);
		dispatch_source_set_registration_handler(t[i], ^{
			dispatch_suspend(t[i]);
			dispatch_group_leave(g);
		});
		dispatch_resume(t[i]);
	}
static dispatch_group_t create_group(size_t count, int delay) {
	size_t i;
	int* param;

	dispatch_group_t group = dispatch_group_create();

	for (i = 0; i < count; ++i) {
		dispatch_queue_t queue = dispatch_queue_create("foo", NULL);
		param = (int*)malloc(sizeof(int));
		*param = delay;

		MU_ASSERT_NOT_NULL(queue);
		MU_ASSERT_NOT_NULL(param);

		dispatch_group_async_f(group, queue, param, work);

		dispatch_release(queue);
	}
	return group;
}
dispatch_group_t
create_group(size_t count, int delay)
{
	size_t i;

	dispatch_group_t group = dispatch_group_create();

	for (i = 0; i < count; ++i) {
		dispatch_queue_t queue = dispatch_queue_create(NULL, NULL);
		assert(queue);

		dispatch_group_async(group, queue, ^{
			if (delay) {
				fprintf(stderr, "sleeping...\n");
				sleep(delay);
				fprintf(stderr, "done.\n");
			}
		});

		dispatch_release(queue);
		}
int main(void)
{
	test_start("Dispatch Debug");

	dispatch_queue_t main_q = dispatch_get_main_queue();
	dispatch_debug(main_q, "dispatch_queue_t");
	
	dispatch_queue_t default_q = dispatch_get_concurrent_queue(0);
	dispatch_debug(default_q, "dispatch_queue_t");
	
	dispatch_source_attr_t attr = dispatch_source_attr_create();
	dispatch_debug(attr, "dispatch_source_attr_t");

	dispatch_source_t s = dispatch_source_timer_create(DISPATCH_TIMER_INTERVAL,
		1000000000ull, 0, attr, main_q, ^(dispatch_event_t ev __attribute__((unused))) {});
	dispatch_debug(s, "dispatch_source_t");

	dispatch_group_t g = dispatch_group_create();
	dispatch_debug(g, "dispatch_group_t");

	return 0;
}
int main(int argc, char *argv[]) {
	int i;
	dispatch_group_t g = dispatch_group_create();
	dispatch_queue_t q =
			dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

	struct timespec ts3 = {3, 0};
	struct timespec ts1 = {1, 0};
	struct timeval basetime, etime;

	printf("loop start\n");
	gettimeofday(&basetime, NULL);

	for (i = 0; i < 10; i++) {
		dispatch_group_async(g, q, ^{
			pthread_t p = pthread_self();
			struct timeval tp;
			nanosleep(&ts3, NULL);
			gettimeofday(&tp, NULL);

			{
				int j = i;
				pthread_t q = pthread_self();
				struct timeval tq;
				gettimeofday(&tq, NULL);

				printf(
						"hello count %d\n"
						"running thread %p time: %ld\n"
						"printing thread %p time: %ld\n"
						"\n",
						j, p, tp.tv_sec - basetime.tv_sec, q, tq.tv_sec - basetime.tv_sec);
			}
		});
		nanosleep(&ts1, NULL);
	}
#include <Security/Security.h>
#include <stdlib.h>

#define BLOCKS 7000

static void tests() {

    SecKeychainRef kc = getPopulatedTestKeychain();

    static dispatch_once_t onceToken = 0;
    static dispatch_queue_t release_queue = NULL;
    dispatch_once(&onceToken, ^{
        release_queue = dispatch_queue_create("com.apple.security.identity-search-queue", DISPATCH_QUEUE_CONCURRENT);
    });
    dispatch_group_t g = dispatch_group_create();

    for(int i = 0; i < BLOCKS; i++) {
        dispatch_group_async(g, release_queue, ^() {
            SecKeychainItemRef blockItem = NULL;

            CFMutableDictionaryRef query = createQueryCustomItemDictionaryWithService(kc, kSecClassInternetPassword, CFSTR("test_service"), CFSTR("test_service"));
            CFDictionarySetValue(query, kSecMatchLimit, kSecMatchLimitOne);

            ok_status(SecItemCopyMatching(query, (CFTypeRef*) &blockItem), "%s: SecItemCopyMatching(%d)", testName, i);

            CFReleaseNull(blockItem);
        });
    }

    dispatch_group_wait(g, DISPATCH_TIME_FOREVER);
Beispiel #23
0
dispatch_group_t createGroup() {
    return dispatch_group_create();
}
Beispiel #24
0
#include <sys/stat.h>
#include <sys/param.h>
#include <sys/sysctl.h>
#endif // WIN32
#include <list>

// Parallel Local Declarations
#if defined(PBRT_HAS_PTHREADS) && !defined(PBRT_USE_GRAND_CENTRAL_DISPATCH)
static pthread_t *threads;
#endif
#ifdef WIN32
static HANDLE *threads;
#endif // WIN32
#ifdef PBRT_USE_GRAND_CENTRAL_DISPATCH
static dispatch_queue_t gcdQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
static dispatch_group_t gcdGroup = dispatch_group_create();
#else
static Mutex *taskQueueMutex = Mutex::Create();
static std::vector<Task *> taskQueue;
#endif // PBRT_USE_GRAND_CENTRAL_DISPATCH
#ifndef PBRT_USE_GRAND_CENTRAL_DISPATCH
static Semaphore workerSemaphore;
static uint32_t numUnfinishedTasks;
static ConditionVariable tasksRunningCondition;
#endif // PBRT_USE_GRAND_CENTRAL_DISPATCH
#ifndef PBRT_USE_GRAND_CENTRAL_DISPATCH
static
#ifdef WIN32
DWORD WINAPI taskEntry(LPVOID arg);
#else
void *taskEntry(void *arg);
Beispiel #25
0
    }

    /* Wait at least three seconds for our sources to flush to ASL */
    dispatch_group_wait(read_source_group, dispatch_time(DISPATCH_TIME_NOW, 3LL * NSEC_PER_SEC));
}

static void
asl_descriptor_init(void *ctx __unused)
{
    assert((redirect_descriptors = calloc(16, sizeof(*redirect_descriptors))) != NULL);
    n_redirect_descriptors = 16;

    redirect_serial_q = dispatch_queue_create("com.apple.asl-redirect", NULL);
    assert(redirect_serial_q != NULL);

    read_source_group = dispatch_group_create();
    assert(read_source_group != NULL);

    atexit(redirect_atexit);
}

static int
asl_log_from_descriptor(aslclient ac, aslmsg am, int level, int descriptor)
{
    int err __block = 0;
    static dispatch_once_t once_control;
    dispatch_once_f(&once_control, NULL, asl_descriptor_init);
    asl_client_t *asl = (asl_client_t *)ac;
    asl_msg_t *msg = (asl_msg_t *)am;

    if (descriptor < 0) return EBADF;
Beispiel #26
0
void
TasksInit() {
    gcdQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    gcdGroup = dispatch_group_create();
    initialized = true;
}
int
main(int argc, char** argv)
{
	struct hostent *he;
	int sockfd, clientfd;
	struct sockaddr_in addr1, addr2, server;
	socklen_t addr2len;
	socklen_t addr1len;
	pid_t clientid;

	const char *path = "/usr/share/dict/words";
	int read_fd, fd;

	if (argc == 2) {
		// Client
		dispatch_test_start(NULL);

		if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
			test_errno("Client-socket()", errno, 0);
			test_stop();
		}

		if ((he = gethostbyname("localhost")) == NULL) {
			fprintf(stderr, "Client-gethostbyname() failed\n");
			test_stop();
		}

		memcpy(&server.sin_addr, he->h_addr_list[0], he->h_length);
		server.sin_family = AF_INET;
		server.sin_port = atoi(argv[1]);

		fprintf(stderr, "Client-connecting on port ... %d\n", server.sin_port);

		if (connect(sockfd, (struct sockaddr *)&server, sizeof(server))) {
			test_errno("client-connect()", errno, 0);
			test_stop();
		}

		// Read from the socket and compare the contents are what we expect

		fd = open(path, O_RDONLY);
		if (fd == -1) {
			test_errno("client-open", errno, 0);
			test_stop();
		}
#ifdef F_NOCACHE
		if (fcntl(fd, F_NOCACHE, 1)) {
			test_errno("client-fcntl F_NOCACHE", errno, 0);
			test_stop();
		}
#else
		// investigate what the impact of lack of file cache disabling has 
		// for this test
#endif
		struct stat sb;
		if (fstat(fd, &sb)) {
			test_errno("client-fstat", errno, 0);
			test_stop();
		}
		size_t size = sb.st_size;

		__block dispatch_data_t g_d1 = dispatch_data_empty;
		__block dispatch_data_t g_d2 = dispatch_data_empty;
		__block int g_error = 0;

		dispatch_group_t g = dispatch_group_create();
		dispatch_group_enter(g);
		dispatch_read(fd, size, dispatch_get_global_queue(0, 0),
				^(dispatch_data_t d1, int error) {
			test_errno("Client-dict-read error", error, 0);
			test_long("Client-dict-dispatch data size",
					dispatch_data_get_size(d1), size);
			dispatch_retain(d1);
			g_d1 = d1;
			dispatch_group_leave(g);
		});
void DetectionManager::processDetection(ImageData *image) {
    int threads = 4;
    
    dispatch_queue_t queue[4];
    for (int i = 0 ; i < threads; i++) {
        queue[i] = dispatch_queue_create("Threads", DISPATCH_QUEUE_CONCURRENT);
    }
    
    
    double simulation_time = read_timer();
    
//preprocess
    shopTopLeftCorner = NULL;
    shopTopLeftCornerShown = false;
    allyMinions->clear();
    enemyMinions->clear();
    allyChampions->clear();
    enemyChampions->clear();
    selfChampions->clear();
    enemyTowers->clear();
    buyableItems->clear();
    spell1LevelDots->clear();
    spell2LevelDots->clear();
    spell3LevelDots->clear();
    spell4LevelDots->clear();
    
    dispatch_group_t dispatchGroup = dispatch_group_create();
    

////#pragma omp parallel num_threads(128)
    
    
    for (int threadNum = 0; threadNum < threads; threadNum++)
    {
        
        dispatch_group_async(dispatchGroup, queue[threadNum], ^{
    
    int perThread = (image->imageWidth * image->imageHeight) / threads;// / omp_get_num_threads();
        int start = threadNum * perThread;
        int end = (threadNum + 1) * perThread;

        int x = start % (image->imageWidth);
        int y = start / (image->imageWidth);

        uint8_t* pixel = getPixel2(image, x, y);

        Minion* minionBar;
        Champion* championBar;
        Tower* towerBar;
        GenericObject* topLeftCorner;

        for (int xy = start; xy < end; ++xy) {
            if (x >= image->imageWidth) {
                x = 0;
                y++;
            }

            //Ally minion detection
            minionBar = AllyMinionManager::detectMinionBarAtPixel(image, pixel, x, y);
            if (minionBar != NULL) {
                //#pragma omp critical (addAllyMinion)
                allyMinions->push_back(minionBar);
            }
            //Enemy minion detection
            minionBar = EnemyMinionManager::detectMinionBarAtPixel(image, pixel, x, y);
            if (minionBar != NULL) {
                //#pragma omp critical (addEnemyMinion)
                enemyMinions->push_back(minionBar);
            }
            //Enemy champion detection
            championBar = EnemyChampionManager::detectChampionBarAtPixel(image, pixel, x, y);
            if (championBar != NULL) {
                //#pragma omp critical (addEnemyChampion)
                enemyChampions->push_back(championBar);
            }
            //Ally champion detection
            championBar = AllyChampionManager::detectChampionBarAtPixel(image, pixel, x, y);
            if (championBar != NULL) {
                //#pragma omp critical (addAllyChampion)
                allyChampions->push_back(championBar);
            }
            //Enemy tower detection
            towerBar = EnemyTowerManager::detectTowerBarAtPixel(image, pixel, x, y);
            if (towerBar != NULL) {
                //#pragma omp critical (addEnemyTower)
                enemyTowers->push_back(towerBar);
            }
            //Self champion detection
            championBar = SelfChampionManager::detectChampionBarAtPixel(image, pixel, x, y);
            if (championBar != NULL) {
                //#pragma omp critical (addSelfChampion)
                selfChampions->push_back(championBar);
            }
            //Shop window detection
            if (shopTopLeftCorner == NULL) {
                topLeftCorner = ShopManager::detectShopTopLeftCorner(image, pixel, x, y);
                if (topLeftCorner != NULL) {
                    shopTopLeftCorner = topLeftCorner;
                    shopTopLeftCornerShown = true;
                }
            }

            x++;
            pixel += 4;
        }
        });
    }
Boolean
SCDynamicStoreSetDispatchQueue(SCDynamicStoreRef store, dispatch_queue_t queue)
{
	dispatch_group_t		drainGroup	= NULL;
	dispatch_queue_t		drainQueue	= NULL;
	dispatch_group_t		group		= NULL;
	mach_port_t			mp;
	Boolean				ok		= FALSE;
	dispatch_source_t		source;
	SCDynamicStorePrivateRef	storePrivate	= (SCDynamicStorePrivateRef)store;

	if (store == NULL) {
		// sorry, you must provide a session
		_SCErrorSet(kSCStatusNoStoreSession);
		return FALSE;
	}

	if (queue == NULL) {
		if (storePrivate->dispatchQueue == NULL) {
			_SCErrorSet(kSCStatusInvalidArgument);
			return FALSE;
		}

		ok = TRUE;
		goto cleanup;
	}

	if (storePrivate->server == MACH_PORT_NULL) {
		// sorry, you must have an open session to play
		_SCErrorSet(kSCStatusNoStoreServer);
		return FALSE;
	}

	if ((storePrivate->dispatchQueue != NULL) || (storePrivate->rls != NULL)) {
		_SCErrorSet(kSCStatusInvalidArgument);
		return FALSE;
	}

	if (storePrivate->notifyStatus != NotifierNotRegistered) {
		// sorry, you can only have one notification registered at once...
		_SCErrorSet(kSCStatusNotifierActive);
		return FALSE;
	}

	/*
	 * mark our using of the SCDynamicStore notifications, create and schedule
	 * the notification port (storePrivate->rlsNotifyPort), and a bunch of other
	 * "setup"
	 */
	storePrivate->notifyStatus = Using_NotifierInformViaDispatch;
	rlsSchedule((void*)store, NULL, NULL);
	if (storePrivate->rlsNotifyPort == NULL) {
		/* if we could not schedule the notification */
		_SCErrorSet(kSCStatusFailed);
		goto cleanup;
	}

	// retain the dispatch queue
	storePrivate->dispatchQueue = queue;
	dispatch_retain(storePrivate->dispatchQueue);

	//
	// We've taken a reference to the callers dispatch_queue and we
	// want to hold on to that reference until we've processed any/all
	// notifications.  To facilitate this we create a group, dispatch
	// any notification blocks to via that group, and when the caller
	// has told us to stop the notifications (unschedule) we wait for
	// the group to empty and use the group's finalizer to release
	// our reference to the SCDynamicStore.
	//
	group = dispatch_group_create();
	storePrivate->dispatchGroup = group;
	CFRetain(store);
	dispatch_set_context(storePrivate->dispatchGroup, (void *)store);
	dispatch_set_finalizer_f(storePrivate->dispatchGroup, (dispatch_function_t)CFRelease);

	// create a dispatch source for the mach notifications
	mp = CFMachPortGetPort(storePrivate->rlsNotifyPort);
	source = dispatch_source_create(DISPATCH_SOURCE_TYPE_MACH_RECV, mp, 0, queue);
	if (source == NULL) {
		SCLog(TRUE, LOG_ERR, CFSTR("SCDynamicStore dispatch_source_create() failed"));
		_SCErrorSet(kSCStatusFailed);
		goto cleanup;
	}

	dispatch_source_set_event_handler(source, ^{
		kern_return_t	kr;
		mach_msg_id_t	msgid;
		union {
			u_int8_t			buf[sizeof(mach_msg_empty_t) + MAX_TRAILER_SIZE];
			mach_msg_empty_rcv_t		msg;
			mach_no_senders_notification_t	no_senders;
		} notify_msg;

		kr = mach_msg(&notify_msg.msg.header,	// msg
			      MACH_RCV_MSG,		// options
			      0,			// send_size
			      sizeof(notify_msg),	// rcv_size
			      mp,			// rcv_name
			      MACH_MSG_TIMEOUT_NONE,	// timeout
			      MACH_PORT_NULL);		// notify
		if (kr != KERN_SUCCESS) {
			SCLog(TRUE, LOG_ERR,
			      CFSTR("SCDynamicStore notification handler, kr=0x%x"),
			      kr);
			return;
		}

		msgid = notify_msg.msg.header.msgh_id;

		CFRetain(store);
		dispatch_group_async(group, queue, ^{
			if (msgid == MACH_NOTIFY_NO_SENDERS) {
				// re-establish notification and inform the client
				(void)__SCDynamicStoreReconnectNotifications(store);
			}
			rlsPerform(storePrivate);
			CFRelease(store);
		});
	});