I have written a Windows console app that uses some windows APIs.
Specifically it uses threads (CreateThread, ResumeThread) and signaling(WaitForMulipleObjects, WaitForSingleObject).
The program run fine on Windows. However I want to run this on my Mac. Does anybody know the c++ equivalent for these calls?

Code:
#include <SDKDDKVer.h>
#include <windows.h>
#include <cmath>
#include <iostream>
#include <fstream>
#include <tchar.h>
#include <limits>
#include <mutex>

using namespace std;

#define MAX_INT64       (0X7FFFFFFFFFFFFFFFLL)
#define MOD(a,b)        (a%b)
#define SQRT(x)         (sqrt(x))
#define TRUNC(x)        ((MYTYPE)(x))
#define MAX_WAIT        (INFINITE)
#define NUM_BLOCKS      (1000)
#define WORKER_THREADS  (8)

typedef long long MYTYPE;
typedef long double MYFLOATTYPE;

typedef struct Triple
{
    MYTYPE a;
    MYTYPE b;
    MYTYPE c;
} Triple;

typedef struct TripleBlock
{
    Triple* Triples;
    long NumTriples;
    long NumTriplesAllocated;
    TripleBlock* Next;
} TripleBlock;

typedef struct ThreadStartData
{
    MYTYPE min;
    MYTYPE startmax;
    MYTYPE max;
    MYTYPE numdone;
    MYTYPE numthreads;
    MYTYPE complete;
    TripleBlock* block;
} ThreadStartData;

void PrintTriples(TripleBlock* block);
TripleBlock* AllocateTripleBlock(long numtriples);
void AddTriple(MYTYPE a, MYTYPE b, MYTYPE c, TripleBlock* block);
DWORD WINAPI CalculateTriples(LPVOID lpParam);
DWORD WINAPI ProgressTriples(LPVOID lpParam);

std::mutex m;
ofstream myfile;

int _tmain(int argc, _TCHAR* argv[])
{
    MYTYPE min =  2;
    MYTYPE max = 0;

    if (argc == 1)
    {
        max = MAX_INT64;
    }
    else if (argc == 2)
    {
        max = _ttol(argv[1]);
    }
    else
    {
        cout << argv[0] << " max" << endl;
        return 0;
    }

    int numThreads = WORKER_THREADS;
    if (max < WORKER_THREADS * 5)
        numThreads = 1;

    cout << "Using " << numThreads << " worker threads." << endl;

    DWORD* dwThreadIdArray = (DWORD*) malloc(numThreads * sizeof(DWORD));
    HANDLE* hThreadArray = (HANDLE*) malloc(numThreads * sizeof(HRESULT));
    ThreadStartData* data = (ThreadStartData*) malloc(numThreads * sizeof(ThreadStartData));

    memset(dwThreadIdArray, 0, numThreads * sizeof(DWORD));
    memset(hThreadArray, 0, numThreads * sizeof(HRESULT));
    memset(data, 0, numThreads * sizeof(sizeof(ThreadStartData)));

    MYTYPE inc = max / numThreads;

    m.lock();
    for (int i = 0; i < numThreads; i++)
    {
        data[i].min = min;
        data[i].max = max;
        data[i].numdone = 0;
        data[i].numthreads = numThreads;
        data[i].complete = 0;
        data[i].block = AllocateTripleBlock(NUM_BLOCKS);
   
        MYTYPE startmax = min + inc;
        if (startmax > max)
            startmax = max;

        data[i].startmax = startmax;
        
        if (data[i].startmax > max)
            data[i].startmax = max;

        min += (inc + 1);
   
        hThreadArray[i] = CreateThread( 
            NULL,                   // default security attributes
            0,                      // use default stack size  
            CalculateTriples,       // thread function name
            &data[i],               // argument to thread function 
            CREATE_SUSPENDED,       // creation flags 
            &dwThreadIdArray[i]);   // returns the thread identifier 
    }

    DWORD dwProgressThreadID;
    HANDLE hProgressthread = CreateThread( 
        NULL,                   // default security attributes
        0,                      // use default stack size  
        ProgressTriples,        // thread function name
        data,                   // argument to thread function 
        CREATE_SUSPENDED,       // creation flags 
        &dwProgressThreadID);   // returns the thread identifier 

    m.unlock();

    for(int i=0; i < numThreads; i++)
    {
        SetThreadPriority(hThreadArray[i], THREAD_PRIORITY_ABOVE_NORMAL);
        ResumeThread(hThreadArray[i]);
    }

    ResumeThread(hProgressthread);

    // wait for all the threads to complete
    DWORD result  = 0;
    MYTYPE lastPercent = -1;
    WaitForMultipleObjects(numThreads, hThreadArray, TRUE, MAX_WAIT);
    WaitForSingleObject(hProgressthread, MAX_WAIT);

    // print the results
    myfile.open("triples.txt");

    for (int i = 0; i < numThreads; i++)
    {
        PrintTriples(data[i].block);
    }
    myfile.close();

    cout << endl << endl;

    // cleanup
    for (int i = 0; i < numThreads; i++)
    {
        TripleBlock* block = data[i].block;
        while (block)
        {
            TripleBlock* next = block->Next;
            if (block->NumTriplesAllocated > 0)
                free(block->Triples);
            free(block);            
            block = next;
        }
        CloseHandle(hThreadArray[i]);
    }
    
    free(dwThreadIdArray);
    free(data);

    return 0;
}

/// <summary>
/// show progress thread.
/// </summary>
/// <param name="lpParam">The lp parameter.</param>
/// <returns>DWORD.</returns>
DWORD WINAPI ProgressTriples(LPVOID lpParam)
{
    ThreadStartData* data = (ThreadStartData*)lpParam;

    MYTYPE numThreads = data->numthreads;
    MYTYPE max = data->max;

    MYTYPE lastPercent = -1;
    bool done = true;   
    do 
    {
        MYTYPE total = 0;
        done = true;
        
        for (int i = 0; i < numThreads; i++)
        {
            total += data[i].numdone;
            if (data[i].complete == 0)
                done = false;
        }
        
        if (done)
        {
            cout << "done." << endl;
            break;
        }

        MYFLOATTYPE percentdone = ((MYFLOATTYPE)total / (MYFLOATTYPE)max) * 100;
        if (lastPercent != TRUNC(percentdone))
        {
            lastPercent = TRUNC(percentdone);
            cout << lastPercent << "% done.  (" << total << " of " << max << ")" << endl;
            Sleep(1 * 1000);
        }
    }
    while (!done);
    return 0;
}

/// <summary>
/// Calculates the triples.
/// </summary>
/// <param name="lpParam">The lp parameter.</param>
/// <returns>DWORD.</returns>
DWORD WINAPI CalculateTriples(LPVOID lpParam)
{
    ThreadStartData* data = (ThreadStartData*)lpParam;
    MYTYPE min = data->min;
    MYTYPE max = data->max;
    MYTYPE startmax = data->startmax;
    TripleBlock* block = data->block;

    for (MYTYPE a = min; a >= min && a < startmax; a++)
    {
        data->numdone++;
     
        MYFLOATTYPE asquared = (MYFLOATTYPE)a * (MYFLOATTYPE)a;
        for (MYTYPE b = a + 1; b > a; b += 2)
        {
            MYFLOATTYPE bsquared = (MYFLOATTYPE)b * (MYFLOATTYPE)b;
            MYFLOATTYPE csquared = asquared + bsquared;      
            MYFLOATTYPE csqroot = SQRT(csquared);     
            MYTYPE c = TRUNC(csqroot);

            // check for max
            if (c > max || c < b)
                break;

            // check for a true square
            if (csqroot != TRUNC(csqroot))
                continue;

            // check gcd
            MYTYPE i = 0;
            for (i = a; i >= 1; i--)
            {
                if (MOD(c, i) != 0)
                    continue;

                if (MOD(b, i) != 0) 
                    continue;

                if (MOD(a, i) != 0)
                    continue;

                break;
            }

            // if gcd != 1 then no triplet
            if (i != 1)
            {
                continue;
            }
            
            AddTriple(a, b, c, block);
            break;
        }
    }

    data->complete = -1;
    return 0;
}

/// <summary>
/// Adds the triple.
/// </summary>
/// <param name="a">a.</param>
/// <param name="b">b.</param>
/// <param name="c">c.</param>
/// <param name="block">block.</param>
void AddTriple(MYTYPE a, MYTYPE b, MYTYPE c, TripleBlock* block)
{
    while (block->NumTriples >= block->NumTriplesAllocated)
    {
        if (block->Next == NULL)
        {
            block->Next = AllocateTripleBlock(NUM_BLOCKS);
        }
        block = block->Next;
    }

    Triple* triple = &(block->Triples[block->NumTriples]);
    triple->a = a;
    triple->b = b;
    triple->c = c;
    block->NumTriples++;
}

/// <summary>
/// Allocates the triple block.
/// </summary>
/// <param name="numtriples">The numtriples.</param>
/// <returns>TripleBlock *</returns>
TripleBlock* AllocateTripleBlock(long numtriples)
{
    TripleBlock* block = (TripleBlock*) malloc(sizeof(TripleBlock));
    if (block == NULL) 
        return NULL;

    memset(block, 0, sizeof(TripleBlock));
    block->NumTriplesAllocated = numtriples;

    block->Triples = (Triple*) malloc(numtriples * sizeof(Triple));
    if (block->Triples == NULL) 
        return NULL;
    memset(block->Triples, 0, numtriples * sizeof(Triple));

    return block;
}

/// <summary>
/// Prints the triples.
/// </summary>
/// <param name="block">The block.</param>
void PrintTriples(TripleBlock* block)
{
    while (block)
    {
        Triple* triple = block->Triples;
        for (MYTYPE i = 0; i < block->NumTriples; i++, triple++)
        {
            myfile << "  " << triple->a << ", " << triple->b << ", " << triple->c << endl;
        }
        block = block->Next;
    }
}