/*
 * Copyright (c) 2004 Ulrich Drepper <drepper@redhat.com>
 * Copyright (c) 2005 Roland McGrath <roland@redhat.com>
 * Copyright (c) 2012-2015 Dmitry V. Levin <ldv@altlinux.org>
 * Copyright (c) 2014-2017 The strace developers.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "defs.h"

#include <sched.h>
#include "sched_attr.h"

#include "xlat/schedulers.h"
#include "xlat/sched_flags.h"

SYS_FUNC(sched_getscheduler)
{
	if (entering(tcp)) {
		tprintf("%d", (int) tcp->u_arg[0]);
	} else if (!syserror(tcp)) {
		tcp->auxstr = xlookup(schedulers, (kernel_ulong_t) tcp->u_rval);
		if (tcp->auxstr != NULL)
			return RVAL_STR;
	}
	return 0;
}

SYS_FUNC(sched_setscheduler)
{
	tprintf("%d, ", (int) tcp->u_arg[0]);
	printxval(schedulers, tcp->u_arg[1], "SCHED_???");
	tprints(", ");
	printnum_int(tcp, tcp->u_arg[2], "%d");

	return RVAL_DECODED;
}

SYS_FUNC(sched_getparam)
{
	if (entering(tcp))
		tprintf("%d, ", (int) tcp->u_arg[0]);
	else
		printnum_int(tcp, tcp->u_arg[1], "%d");
	return 0;
}

SYS_FUNC(sched_setparam)
{
	tprintf("%d, ", (int) tcp->u_arg[0]);
	printnum_int(tcp, tcp->u_arg[1], "%d");

	return RVAL_DECODED;
}

SYS_FUNC(sched_get_priority_min)
{
	printxval(schedulers, tcp->u_arg[0], "SCHED_???");

	return RVAL_DECODED;
}

SYS_FUNC(sched_rr_get_interval)
{
	if (entering(tcp)) {
		tprintf("%d, ", (int) tcp->u_arg[0]);
	} else {
		if (syserror(tcp))
			printaddr(tcp->u_arg[1]);
		else
			print_timespec(tcp, tcp->u_arg[1]);
	}
	return 0;
}

static void
print_sched_attr(struct tcb *const tcp, const kernel_ulong_t addr,
		 unsigned int usize)
{
	struct sched_attr attr = {};
	unsigned int size;

	if (usize) {
		/* called from sched_getattr */
		size = usize <= sizeof(attr) ? usize : (unsigned) sizeof(attr);
		if (umoven_or_printaddr(tcp, addr, size, &attr))
			return;
		/* the number of bytes written by the kernel */
		size = attr.size;
	} else {
		/* called from sched_setattr */
		if (umove_or_printaddr(tcp, addr, &attr.size))
			return;
		usize = attr.size;
		if (!usize)
			usize = SCHED_ATTR_MIN_SIZE;
		size = usize <= sizeof(attr) ? usize : (unsigned) sizeof(attr);
		if (size >= SCHED_ATTR_MIN_SIZE) {
			if (umoven_or_printaddr(tcp, addr, size, &attr))
				return;
		}
	}

	tprintf("{size=%u", attr.size);

	if (size >= SCHED_ATTR_MIN_SIZE) {
		tprints(", sched_policy=");
		printxval(schedulers, attr.sched_policy, "SCHED_???");
		tprints(", sched_flags=");
		printflags64(sched_flags, attr.sched_flags, "SCHED_FLAG_???");

#define PRINT_SCHED_FIELD(field, fmt)			\
		tprintf(", " #field "=%" fmt, attr.field)

		PRINT_SCHED_FIELD(sched_nice, "d");
		PRINT_SCHED_FIELD(sched_priority, "u");
		PRINT_SCHED_FIELD(sched_runtime, PRIu64);
		PRINT_SCHED_FIELD(sched_deadline, PRIu64);
		PRINT_SCHED_FIELD(sched_period, PRIu64);

		if (usize > size)
			tprints(", ...");
	}

	tprints("}");
}

SYS_FUNC(sched_setattr)
{
	if (entering(tcp)) {
		tprintf("%d, ", (int) tcp->u_arg[0]);
		print_sched_attr(tcp, tcp->u_arg[1], 0);
	} else {
		struct sched_attr attr;

		if (verbose(tcp) && tcp->u_error == E2BIG
		    && umove(tcp, tcp->u_arg[1], &attr.size) == 0) {
			tprintf(" => {size=%u}", attr.size);
		}

		tprintf(", %u", (unsigned int) tcp->u_arg[2]);
	}

	return 0;
}

SYS_FUNC(sched_getattr)
{
	if (entering(tcp)) {
		tprintf("%d, ", (int) tcp->u_arg[0]);
	} else {
		const unsigned int size = tcp->u_arg[2];

		if (size)
			print_sched_attr(tcp, tcp->u_arg[1], size);
		else
			printaddr(tcp->u_arg[1]);
		tprints(", ");
#ifdef AARCH64
		/*
		 * Due to a subtle gcc bug that leads to miscompiled aarch64
		 * kernels, the 3rd argument of sched_getattr is not quite 32-bit
		 * as on other architectures.  For more details see
		 * https://sourceforge.net/p/strace/mailman/message/35721703/
		 */
		if (syserror(tcp))
			print_abnormal_hi(tcp->u_arg[2]);
#endif
		tprintf("%u", size);
		tprintf(", %u", (unsigned int) tcp->u_arg[3]);
	}

	return 0;
}
