#!/usr/bin/perl

# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License, Version 1.0 only
# (the "License").  You may not use this file except in compliance
# with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#

#
# Copyright 2005 Andrei Dorofeev (dorofeev@gmail.com)
# All rights reserved.
#

use strict;
use warnings;
use Getopt::Std;
use Sun::Solaris::Exacct qw(:EXACCT_ALL);
use Sun::Solaris::Project;
use POSIX qw(ctime);
use POSIX qw(getuid);
use Fcntl qw(:mode);

sub display
{
	my ($eo) = @_;
	my $h = $eo->as_hash();

	printf("%8s   %5s %10.2f   %10.2f %6s %6s %6s %6s %9s\n",
		$h->{EXD_TASK_PROJID},
		$h->{EXD_TASK_TASKID},
		$h->{EXD_TASK_CPU_USER_SEC} +
		($h->{EXD_TASK_CPU_USER_NSEC} / 1000000000),
		$h->{EXD_TASK_CPU_SYS_SEC} +
		($h->{EXD_TASK_CPU_SYS_NSEC} / 1000000000),
		$h->{EXD_TASK_FAULTS_MAJOR} + $h->{EXD_TASK_FAULTS_MINOR},
		$h->{EXD_TASK_BLOCKS_IN} + $h->{EXD_TASK_BLOCKS_OUT},
		$h->{EXD_TASK_SIGNALS},
		$h->{EXD_TASK_SWAPS},
		$h->{EXD_TASK_SYSCALLS});
}

my @tasks;
my $eo;

#
# Main
#
for (;;) {
	my $taskid;

	@tasks = qx{ ps -o taskid -ef | sort -u | grep -v TASKID};

	getuid() == 0 || die ("ERROR: Got root?\n");

	getacct(P_TASKID, 0) ||
		die("ERROR: task accounting disabled.\n" .
		 "Please run \"acctadm -E task; acctadm -e extended task\"\n");

	printf("%8s   %5s  %9s   %9s %6s %6s %6s %6s %9s\n",
		"PROJECT", "TASK", "CPU/USER", "CPU/SYSTEM",
		"FAULTS", "BLOCKS", "SIGS", "SWAPS", "SYSCALLS");

	foreach $taskid (@tasks) {
	 $eo = getacct(P_TASKID, $taskid) || die ("getacct failed");
	 display($eo);
	}
	sleep 5;
}
exit(0);
