#if !defined(astris_concurrency_h_)
#define astris_concurrency_h_
/*  ****************************************************************************
 *  ASTRIS - Concurrency for Astris, using GCD
 *
 *  Astris concurrency		File: astris_concurrency.h
 *
 *******************************************************************************
 *
 *  Copyright (C) 2015-2016  Apple, Inc. All rights reserved.
 *
 *  This document is the property of Apple Inc.
 *  It is considered confidential and proprietary.
 *
 *  This document may not be reproduced or transmitted in any form,
 *  in whole or in part, without the express written permission of
 *  Apple Inc.
 **************************************************************************** */

// C99 library
#include <stdint.h>

// System library
#include <dispatch/dispatch.h>

#ifdef __cplusplus
extern "C" {
#endif

// Constants

typedef enum concurrency_exec_threads_t_ {
    K_CONCURRENCY_EXEC_THREADS_PTHREADS                = 0,
    K_CONCURRENCY_EXEC_THREADS_GCD_CONCUR_QUEUE_NORMAL = 1,
    // Unimplemeted.
} concurrency_exec_threads_t;

typedef enum concurrency_exec_core_api_t_ {
    K_CONCURRENCY_EXEC_CORE_API_SYNCH_IN_THREAD      = 0,
    K_CONCURRENCY_EXEC_CORE_API_GCD_SER_QUEUE_SYNCH  = 1,
    K_CONCURRENCY_EXEC_CORE_API_GCD_SER_QUEUE_ASYNCH = 2,
    // WARNING: Core API does not support this.  DO NOT USE!!!
} concurrency_exec_core_api_t;

// Types

typedef struct astris_concurrency_t_ {
    int m_exec_threads;
    // Specifies how to execute threads.
    //      0 - Use pthreads
    //      1 - Use GCD concurrent queue, Normal priority.
    int m_exec_core_api;
    // Specifies how to execute Astris Core API
    //      0 - In current thread, synchronously.
    //      1 - On dedicated GCD serial queue, synchronously.
    //      2 - On dedicated GCD serial queue, asynchronously.
    //          WARNING: Core API does not support this.  DO NOT USE!!!

    dispatch_queue_t m_main_concurrent_queue;
    // Points to main concurrent queue, used for threads in Astris
    dispatch_queue_t m_core_api_serial_queue;
    // Astris Core API serial queue.  Serializes requests.

    // Statistics
    uint64_t m_casq_num_requests;
    // Number of requests to the Astris Core API serial queue.
    uint64_t m_casq_exec_time_us;
    // Total execution time for the Core API serial queue in us.
    uint64_t m_casq_num_failures;
    // Number of errors in Core API serial queue.

} astris_concurrency_t;

// Functions

astris_concurrency_t *astris_concurrency_new(concurrency_exec_threads_t exec_threads, concurrency_exec_core_api_t exec_core_api);

// Constructor

void astris_concurrency_delete(astris_concurrency_t *act);

// Destructor

#ifdef __cplusplus
}
#endif

#endif // !defined(astris_concurrency_h_)
