
/*
TODO: 1. Linux имеет стандартную структуру атрибутов для CV,
которую нужно реализовать если понадобится.
2. Для систем, которые не имеют готового примитива CV можно будет
реализовать его на доступных примитивах синхронизации. Пример (требует проверки и доработки): 
https://stackoverflow.com/questions/11000725/implementation-of-condition-variables
*/

/**
 * @brief Атрибуты условной переменной (для систем, где они присутствуют)
 * @note TODO: Поддержка будет реализована по мере необходимости 
 

typedef struct {
    int attr;
} hsal_condvar_attrs;*/

TYPE hsal_condvar_attrs:
STRUCT 
    attr	    :DINT;
END_STRUCT
END_TYPE

(*

/**
 * @brief Структура условной переменной 
 */
typedef struct HSAL_CondVar {
    uintptr_t id;       ///< ID (указатель) объекта условной переменной

    /**
     * @brief Инициализировать условную переменную
     * @param [in] cv Объект условной переменной
     * @param [in] attrs Атрибуты условной переменной (на данный момент не реализовано)
     * @return Код ошибки или 0 в случае успеха
     */ 
    int ( *init)(struct HSAL_CondVar *cv, hsal_condvar_attrs *attrs);
    /**
     * @brief Уведомить один тред об изменении переменной
     * @param [in] cv Объект условной переменной
     * @return Код ошибки или 0 в случае успеха
     */ 
    int ( *signal)(struct HSAL_CondVar *cv);
    /**
     * @brief Уведомить все треды об изменении переменной
     * @param [in] cv Объект условной переменной
     * @return Код ошибки или 0 в случае успеха
     */ 
    int ( *broadcast)(struct HSAL_CondVar *cv);
    // TODO: wait with timeout
    /**
     * @brief Блокирующая функция ожидания условной переменной
     * @param [in] cv Объект условной переменной
     * @param [in] mtx Мютекс, защищающий данные в треде  
     * @return Код ошибки или 0 в случае успеха
     */ 
    int ( *wait)(struct HSAL_CondVar *cv, HSAL_Mutex *mtx);
    /**
     * @brief Уничтожить условную переменную  
     * @return Код ошибки или 0 в случае успеха
     */ 
    int ( *destroy)(struct HSAL_CondVar *cv);
} HSAL_CondVar;*)

@EXTERNAL FUNCTION typedef_init : DINT
VAR_INPUT 
	cv      :REF_TO HSAL_CondVar;
    attrs   :REF_TO hsal_condvar_attrs;
END_VAR
END_FUNCTION

@EXTERNAL FUNCTION typedef_cignal : DINT
VAR_INPUT 
	cv      :REF_TO HSAL_CondVar;
END_VAR
END_FUNCTION

@EXTERNAL FUNCTION typedef_broadcast : DINT
VAR_INPUT 
	cv      :REF_TO HSAL_CondVar;
END_VAR
END_FUNCTION

@EXTERNAL FUNCTION typedef_wait : DINT
VAR_INPUT 
	cv      :REF_TO HSAL_CondVar;
    mtx     :REF_TO HSAL_Mutex;
END_VAR
END_FUNCTION

@EXTERNAL FUNCTION typedef_destroy : DINT
VAR_INPUT 
	cv      :REF_TO HSAL_CondVar;
    mtx     :REF_TO HSAL_Mutex;
END_VAR
END_FUNCTION


TYPE HSAL_CondVar:
STRUCT 
    id	        :REF_TO HSAL_CondVar;
    init        :REF_TO typedef_init; 
    cignal      :REF_TO typedef_cignal;
    broadcast   :REF_TO typedef_broadcast;
    wait        :REF_TO typedef_wait;
    destroy     :REF_TO typedef_destroy;
END_STRUCT
END_TYPE

/**
 * int hsal_condvar_constructor(struct HSAL_CondVar *cv);
 * @brief Конструктор условной переменной 
 */

@EXTERNAL FUNCTION hsal_condvar_constructor : DINT
VAR_INPUT 
	cv  :REF_TO HSAL_CondVar;
END_VAR
END_FUNCTION


