/*
 * Copyright (C) 1994-2018 Altair Engineering, Inc.
 * For more information, contact Altair at www.altair.com.
 *
 * This file is part of the PBS Professional ("PBS Pro") software.
 *
 * Open Source License Information:
 *
 * PBS Pro is free software. You can redistribute it and/or modify it under the
 * terms of the GNU Affero General Public License as published by the Free
 * Software Foundation, either version 3 of the License, or (at your option) any
 * later version.
 *
 * PBS Pro is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.
 * See the GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Commercial License Information:
 *
 * For a copy of the commercial license terms and conditions,
 * go to: (http://www.pbspro.com/UserArea/agreement.html)
 * or contact the Altair Legal Department.
 *
 * Altair’s dual-license business model allows companies, individuals, and
 * organizations to create proprietary derivative works of PBS Pro and
 * distribute them - whether embedded or bundled with other software -
 * under a commercial license agreement.
 *
 * Use of Altair’s trademarks, including but not limited to "PBS™",
 * "PBS Professional®", and "PBS Pro™" and Altair’s logos is subject to Altair's
 * trademark licensing policies.
 *
 */
#ifndef	_LIMITS_IF_H
#define	_LIMITS_IF_H
#ifdef	__cplusplus
extern "C" {
#endif
#include	"pbs_ifl.h"
#include	"pbs_entlim.h"

enum limtype {
	LIM_RES,	/* new-style resource limit */
	LIM_RUN,	/* new-style run (i.e. job count) limit */
	LIM_OLD		/* old-style run limit */
};

/**	@fn void *lim_alloc_liminfo(void)
 *	@brief	allocate and return storage for recording limit information
 *
 *	@par MT-safe:	No
 */
extern void	*lim_alloc_liminfo(void);

/**	@fn void *lim_dup_liminfo(void *p)
 *	@brief	duplicate limit information allocated by lim_alloc_liminfo()
 *
 *	@param	p	the data to be cloned
 *
 *	@return		pointer to cloned data on success or NULL on failure
 *
 *	@par MT-safe:	No
 */
extern void	*lim_dup_liminfo(void *);

/**	@fn void lim_free_liminfo(void *p)
 *	@brief	free limit information allocated by lim_alloc_liminfo()
 *
 *	@param	p	the data to be freed
 *
 *	@par MT-safe:	No
 */
extern void	lim_free_liminfo(void *);

/**	@fn int has_hardlimits(void *p)
 *	@brief	are any hard limits set?
 *
 *	@param p	the limit storage to test
 *
 *	@retval 0	no hard limits set
 *	@retval 1	at least one hard limit set
 *
 *	@par MT-safe:	No
 */
extern int	has_hardlimits(void *);

/**	@fn int has_softlimits(void *p)
 *	@brief	are any soft limits set?
 *
 *	@param p	the limit storage to test
 *
 *	@retval 0	no soft limits set
 *	@retval 1	at least one soft limit set
 *
 *	@par MT-safe:	No
 */
extern int	has_softlimits(void *);

/**	@fn int is_reslimattr(const struct attrl *a)
 *	@brief	is the given attribute a new-style resource limit attribute?
 *
 *	@param a	pointer to the attribute
 *
 *	@retval 0	the named attribute is not a new-style resource limit
 *	@retval 1	the named attribute is a new-style resource limit
 *
 *	@par MT-safe:	Yes
 */
extern int	is_reslimattr(const struct attrl *);

/**	@fn int is_runlimattr(const struct attrl *a)
 *	@brief	is the given attribute a new-style run limit attribute?
 *
 *	@param a	pointer to the attribute
 *
 *	@retval 0	the named attribute is not a new-style run limit
 *	@retval 1	the named attribute is a new-style run limit
 *
 *	@par MT-safe:	Yes
 */
extern int	is_runlimattr(const struct attrl *);

/**	@fn int is_oldlimattr(const struct attrl *a)
 *	@brief	is the given attribute an old-style limit attribute?
 *
 *	@param a	pointer to the attribute
 *
 *	@retval 0	the named attribute is not an old-style limit attribute
 *	@retval 1	the named attribute is an old-style limit attribute
 *
 *	@par MT-safe:	Yes
 */
extern int	is_oldlimattr(const struct attrl *);

/**
 * @brief
 * 		convert an old limit attribute name to the new one
 *
 * @param[in]	a	-	attribute list structure
 * 
 * @return char *
 * @retval !NULL	: old limit attribute name
 * @retval NULL		: attribute value is not an old limit attribute
 *
 */
extern char *	convert_oldlim_to_new(const struct attrl *a);

/**	@fn int lim_setlimits(const struct attrl *a, enum limtype lt, void *p)
 *	@brief set resource or run-time limits
 *
 *	For the given attribute value and limit data, parse and set any limit
 *	directives found therein.
 *
 *	@param a	pointer to the attribute, whose value is a new-style
 *			param and may contain multiple limits to set
 *	@param lt	the class of limit being set
 *	@param p	the place to store limit information
 *
 *	@retval 0	limits were successfully set
 *	@retval nonzero	limits were not successfully set
 *
 *	@par MT-safe:	No
 */
extern int	lim_setlimits(const struct attrl *, enum limtype, void *);

/**	@fn int check_limits(server_info *si, queue_info *qi, resource_resv *rr,
 *                          schd_error *err, int mode)
 *	@brief	check all run-time hard limits to see whether a job may run
 *
 *	@param si	server_info structure (for server resources, list of
 *			running jobs, limit information, ...)
 *	@param qi	queue_info structure (for server resources, list of
 *			running jobs, limit information, ...)
 *	@param rr	resource_resv structure (array of assigned resources to
 *			count against resource limits, group/user name, ...)
 *	@param err	schd_error structure to return error information
 *
 *	@param mode specifies the mode in which limits need to be checked
 *
 *	@retval 0	job exceeds no run-time hard limits
 *	@retval nonzero	job exceeds at least one run-time hard limit
 *
 *	@par MT-safe:	No
 */
extern int	check_limits(server_info *, queue_info *, resource_resv *,
	schd_error *, unsigned int);

/**	@fn int check_soft_limits(server_info *si, queue_info *qi, resource_resv *rr)
 *	@brief	check to see whether a job exceeds its run-time soft limits
 *
 *	@param si	server_info structure (for server resources, list of
 *			running jobs, limit information, ...)
 *	@param qi	queue_info structure (for server resources, list of
 *			running jobs, limit information, ...)
 *	@param rr	resource_resv structure (array of assigned resources to
 *			count against resource limits, group/user name, ...)
 *
 *	@retval 0	job exceeds no run-time soft limits
 *	@retval PREEMPT_TO_BIT(enum preempt) otherwise
 *
 *	@par MT-safe:	No
 *
 *	@see		#preempt in constant.h
 */
extern int	check_soft_limits(server_info *, queue_info *, resource_resv *);

/**
 *      @fn void clear_limres()
 *      @brief free and clear saved limit resources.  Must be called whenever
 *             resource definitions are updated.
 *      @return void
 */
extern void 	clear_limres(void);

/**
 * 	@fn schd_resource query_limres()
 * 	@brief returns a linked list of resources being limited.
 * 	@par This is to be treated as read-only.  Modifying this will adversely
 * 	     affect the limits code
 *
 * 	@return schd_resource *
 */
extern schd_resource *query_limres(void);


#ifdef	__cplusplus
}
#endif
#endif	/* _LIMITS_IF_H */
