Tải bản đầy đủ
FigureB.6 Solaris 7 x86 32-Bit Kernel Address Space

FigureB.6 Solaris 7 x86 32-Bit Kernel Address Space

Tải bản đầy đủ

C

A SAMPLE PROCFS
UTILITY

$ msacct ls -lR
.:
total 3012
drwxrwxrwx
9 jmauro
tech
[a LOT of output snipped]
....
-rwxrwxrwx
1 jmauro
staff
-r--r--r-1 jmauro
staff

2560 Oct 22 13:02 2.X

5166 Feb 12 18:11 msacct.c
4401 Feb 6 22:02 ptime.c

*** Usage Counters ***
Minor Faults:.................0
Major Faults:.................0
Swaps:........................0
Input Blocks:.................0
Output Blocks:................0
STREAMS Messages Sent:........0
STREAMS Messages Received:....0
Signals:......................0
Voluntary Context Switches:...1684
Involuntary Context Switches:.25
System Calls:.................3693
Read/Write Characters:........53305
*** State Times ***
Total Elapsed Time:...........11.065
Total User Time:..............0.403
Total System Time:............0.429
Other System Trap Time:.......0.000
Text Page Fault Sleep Time....0.000
Data Page Fault Sleep Time....0.000
Kernel Page Fault Sleep Time..0.000
User Lock Wait Sleep Time.....0.000
All Other Sleep Time..........10.201
Time Waiting for a CPU........0.038
Stopped Time..................0.000

641

642

A Sample Procfs utility

/*
* Turn on microstate accounting, and print all field resource
* usage and microstat accounting fields when process terminates.
*
* Borrowed largely from ptime.c
* (Thanks Roger Faulkner and Mike Shapiro)
*
* Usage: msacct command
*
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include














static
static
static
static

int
void
void
int

look(pid_t);
hr_min_sec(char *, long);
prtime(char *, timestruc_t *);
perr(const char *);

static
static

void
void

tsadd(timestruc_t *result, timestruc_t *a, timestruc_t *b);
tssub(timestruc_t *result, timestruc_t *a, timestruc_t *b);

static
static

char
char

*command;
procname[64];

main(int argc, char **argv)
{
int ctlfd;
long ctl[2];
pid_t pid;
struct siginfo info;
int status;
if ((command = strrchr(argv[0], ’/’)) != NULL)
command++;
else
command = argv[0];
if (argc <= 1) {
(void) fprintf(stderr,
"usage:%s command [ args ... ]\n", command);
(void) fprintf(stderr,
" (time a command using microstate accounting)\n");
return (1);
}
switch (pid = fork()) {
case -1:
(void) fprintf(stderr, "%s: cannot fork\n", command);
return (2);
case 0:
/* newly created child process */
/* open the /proc ctl file and turn on microstate accounting */
(void) sprintf(procname, "/proc/%d/ctl", (int)getpid());
ctlfd = open(procname, O_WRONLY);

643

ctl[0] = PCSET;
ctl[1] = PR_MSACCT;
(void) write(ctlfd, ctl, 2*sizeof (long));
(void) close(ctlfd);
(void) execvp(argv[1], &argv[1]);
(void) fprintf(stderr, "%s: exec failed\n", command);
if (errno == ENOENT)
_exit(127);
else
_exit(126);
}
(void)
(void)
(void)
(void)

sprintf("%d", procname, (int)pid);
/* for perr() */
signal(SIGINT, SIG_IGN);
signal(SIGQUIT, SIG_IGN);
waitid(P_PID, pid, &info, WEXITED | WNOWAIT);

(void) look(pid);
(void) waitpid(pid, &status, 0);
if (WIFEXITED(status))
return (WEXITSTATUS(status));
else
return ((status & ~WCOREFLG) | 0200);
}
static int
look(pid_t pid)
{
char pathname[100];
int rval = 0;
int fd;
prusage_t prusage;
timestruc_t real, user, sys;
prusage_t *pup = &prusage;
(void) sprintf(pathname, "/proc/%d/usage", (int)pid);
if ((fd = open(pathname, O_RDONLY)) < 0)
return (perr("open usage"));
if (read(fd, &prusage, sizeof (prusage)) != sizeof (prusage))
rval = perr("read usage");
else {
real = pup->pr_term;
tssub(&real, &real, &pup->pr_create);
user = pup->pr_utime;
sys = pup->pr_stime;
tsadd(&sys, &sys, &pup->pr_ttime);
(void) fprintf(stderr, "\n");
printf("*** Usage Counters *** \n");
printf("Minor Faults:.................%ld\n", pup->pr_minf);
printf("Major Faults:.................%ld\n", pup->pr_majf);
printf("Swaps:........................%ld\n", pup->pr_nswap);
printf("Input Blocks:.................%ld\n", pup->pr_inblk);
printf("Output Blocks:................%ld\n", pup->pr_oublk);
printf("STREAMS Messages Sent:........%ld\n", pup->pr_msnd);
printf("STREAMS Messages Received:....%ld\n", pup->pr_mrcv);
printf("Signals:......................%ld\n", pup->pr_sigs);
printf("Voluntary Context Switches:...%ld\n", pup->pr_vctx);
printf("Involuntary Context Switches:.%ld\n", pup->pr_ictx);
printf("System Calls:.................%ld\n", pup->pr_sysc);
printf("Read/Write Characters:........%ld\n", pup->pr_ioch);
printf("*** State Times *** \n");
prtime("Total Elapsed Time:...........", &real);

644

A Sample Procfs utility

prtime("Total User Time:..............",
prtime("Total System Time:............",
prtime("Other System Trap Time:.......",
prtime("Text Page Fault Sleep Time....",
prtime("Data Page Fault Sleep Time....",
prtime("Kernel Page Fault Sleep Time..",
prtime("User Lock Wait Sleep Time.....",
prtime("All Other Sleep Time..........",
prtime("Time Waiting for a CPU........",
prtime("Stopped Time..................",

&user);
&sys);
&pup->pr_ttime);
&pup->pr_tftime);
&pup->pr_dftime);
&pup->pr_kftime);
&pup->pr_ltime);
&pup->pr_slptime);
&pup->pr_wtime);
&pup->pr_stoptime);

}
(void) close(fd);
return (rval);
}
static void
hr_min_sec(char *buf, long sec)
{
if (sec >= 3600)
(void) sprintf(buf, "%ld:%.2ld:%.2ld",
sec / 3600, (sec % 3600) / 60, sec % 60);
else if (sec >= 60)
(void) sprintf(buf, "%ld:%.2ld",
sec / 60, sec % 60);
else {
(void) sprintf(buf, "%ld", sec);
}
}
static void
prtime(char *name, timestruc_t *ts)
{
char buf[32];
hr_min_sec(buf, ts->tv_sec);
(void) fprintf(stderr, "%s%s.%.3u\n",
name, buf, (u_int)ts->tv_nsec/1000000);
}
static int
perr(const char *s)
{
if (s)
(void) fprintf(stderr, "%s: ", procname);
else
s = procname;
perror(s);
return (1);
}
static void
tsadd(timestruc_t *result, timestruc_t *a, timestruc_t *b)
{
result->tv_sec = a->tv_sec + b->tv_sec;
if ((result->tv_nsec = a->tv_nsec + b->tv_nsec) >= 1000000000) {
result->tv_nsec -= 1000000000;
result->tv_sec += 1;
}
}
static void
tssub(timestruc_t *result, timestruc_t *a, timestruc_t *b)
{
result->tv_sec = a->tv_sec - b->tv_sec;

645

if ((result->tv_nsec = a->tv_nsec - b->tv_nsec) < 0) {
result->tv_nsec += 1000000000;
result->tv_sec -= 1;
}
}

646

A Sample Procfs utility

BIBLIOGRAPHY

1. Bach, M. J., The Design of the UNIX Operating System, Prentice Hall, 1986.
2. Bonwick, Jeff, The Slab Allocator: An Object-Caching Kernel Memory Allocator. Sun Microsystems, Inc. White paper.
3. Bourne, S. R., The UNIX System, Addison-Wesley, 1983.
4. Catanzaro, B., Multiprocessor System Architectures, Prentice Hall, 1994.
5. Cockcroft, A., Sun Performance and Tuning — Java and the Internet, 2nd
Edition, Sun Microsystems Press/Prentice Hall, 1998.
6. Cockcroft, A., CPU Time Measurement Errors, Computer Measurement
Group Paper 2038, 1998.
7. Cypress Semiconductor, The CY7C601 SPARC RISC Users Guide, Ross Technology, 1990.
8. Eykholt, J. R., et al., Beyond Multiprocessing — Multithreading the SunOS
Kernel, Summer ‘92 USENIX Conference Proceedings.
9. Gingell, R. A., Moran, J. P., Shannon, W. A., Virtual Memory Architecture in
SunOS, Proceedings of the Summer 1987 USENIX Conference.
10.Goodheart, B., Cox, J., The Magic Garden Explained — The Internals of
UNIX System V Release 4, Prentice Hall, 1994.
11.Hwang, K., Xu, Z., Scalable Parallel Computing, McGraw-Hill, 1998.
12.Intel Corp, The Intel Architecture Software Programmers Manual, Volume 1,
2 and 3, Intel Part Numbers 243190, 24319102, and 24319202, 1993.
13.Kleiman, S. R., Vnodes: An Architecture for Multiple File System Types in
Sun UNIX, Proceedings of Summer 1986 Usenix Conference.
14.Kleiman, S., Shah, D., Smaalders, B., Programming with Threads, Prentice
647

648

Bibliography

Hall, SunSoft Press, 1996.
15.Leffler, S. J., McKusick, M. K., Karels, M. J., Quarterman, J.S., The Design
and Implementation of the 4.3BSD UNIX Operating System, Addison-Wesley,
1989.
16.Lewis, B., Berg, D. J., Threads Primer. A Guide to Multithreaded Programming, SunSoft Press/Prentice Hall, 1996.
17.Lewis, B., Berg, D. J., Multithreaded Programming with Pthreads. Sun
Microsystems Press/Prentice Hall. 1998
18.McKusick, M. K., Bostic, K., Karels, M. J., Quarterman, J. S., The Design and
Implementation of the 4.4 BSD Operating System, Addison-Wesley, 1996.
19.McKusick, M. K., Joy, W., Leffler, S., Fabry, R., A Fast File System for UNIX,
ACM Transactions on Computer Systems, 2(3):181--197. August 1984.
20.Moran, J. P., SunOS Virtual Memory Implementation, Proceedings of 1988
EUUG Conference.
21.Pfister, G., In Search of Clusters, Prentice Hall, 1998.
22.Rosenthal, David S., Evolving the Vnode Interface, Proceedings of Summer
1990 USENIX Conference.
23.Schimmel, C., UNIX Systems for Modern Architectures, Addison-Wesley,
1994.
24.Seltzer, M., Bostic, K., McKusick, M., Staelin, C. An Implementation of a
Log-Structured File System for UNIX, Proceedings of the Usenix Winter Conference, January 1993.
25.Shah, D. K., Zolnowsky, J., Evolving the UNIX Signal Model for Lightweight
Threads, Sun Proprietary/Confidential Internal Use Only, White paper, SunSoft TechConf ‘96.
26.Snyder, P., tmpfs: A Virtual Memory File System, Sun Microsystems White
paper.
27.SPARC International, System V Application Binary Interface — SPARC Version 9 Processor Supplement, 1997.
28.Sun Microsystems, Writing Device Drivers - Part Number 805-3024-10, Sun
Microsystems, 1998
29.Sun Microsystems, STREAMS Programming Guide - Part Number
805-4038-10, Sun Microsystems, 1998
30.Sun Microsystems, UltraSPARC Microprocessor Users Manual - Part Number 802-7220, Sun Microsystems, 1995.
31.Stevens, W. R., Advanced Programming in the UNIX Environment, Addison-Wesley, 1992.
32.Stevens, W. R., UNIX Network Programming, Volume 2. Interprocess Communication. 2nd Edition. Addison-Wesley, 1998.
33.Tanenbaum, A. Operating Systems: Design and Implementation. Prentice