Async safe threadpool
idle

As coded, idle is false when thread is in fact idle. Either rename it to working/running/whatever active or swap the true/false values.
Control flow

Unless I am missing something crucial, there is no need to goto neither in Worker nor in ThreadPoolAddTask.

Similarly, found seems redundant:

do {
    for (i = 0, i &lt; MAX_WORKERS; i++) {
        if (...) {
            ....;
            return true;
        }
    }
} while (retry);
return false;


As a side note, retry shouldn't be handled here. It is a caller business logic when and how to retry. I don't see any value added.
Worker argument

I recommend passing a pointer to a worker instead of pointer to its index. It simplifies both ThreadPoolNew and Worker to:

void *Worker(void *arg)
{
    struct threadpool * t = (int*)arg;
x:
    sem_wait(t-&gt;sem);
    __sync_synchronize();
    t-&gt;func(t-&gt;arg);
    t-&gt;idle = false;
    goto x;
}

bool ThreadPoolNew()
{
    for (int i = 0; i &lt; MAX_WORKERS; i++) {
        sem_init(&amp;threads[i].sem, 0, 0);
        pthread_create(&amp;threads[i].thread, NULL, Worker, &amp;threads[i]);
    }
    return true;
}


and removes the need for thread.id. BTW, notice that assert(threads[i].id == i) always holds, so you may post your semaphore as

    sem_post(&amp;threads[i].sem);

You may want to __sync_synchronize() after announcing the thread idle (there is no barrier between setting idle and subsequent sem_wait).