This Appendix lists the source code for a number of programs that I used within the text of this book. Neither I nor Hewlett Packard will offer support for or take responsibility for any unexpected results from the use of these programs. These programs were used simply to demonstrate a specific technical point under discussion. They do not form any part of the HP-UX operating system, and no warranty can be granted under any such terms. The user is free to use and distribute this source code if he or she so desires, although no support or responsibility can be attributed to the original author.
root@hpeos002[] # cat infocache32.c #include <fcntl.h> #include <nlist.h> #include <time.h> #include <machine/cpu.h> #include <machine/pdc_rqsts.h> struct nlist stuff[] = { {"cache_tlb_parms"}, {"cpu_has_hw_tlb_assist"}, {0} }; main(argc, argv) int argc; char **argv; { int hwtlb; int unified_cache,unified_tlb; char *kernel; int incore; int pagesize; struct pdc_cache_rtn_block cache_tlb_parms; if ( argc != 2 ) kernel="/stand/vmunix"; else kernel=argv[1]; printf("Kernel = %s ", kernel); if ( (nlist(kernel, stuff)) < 0) { perror("nlist"); exit(1); } if ( (incore = open("/dev/mem", O_RDONLY)) < 0) { perror("incore"); exit(2); } if (lseek(incore, stuff[1].n_value, 0) < 0) { perror("lseek"); exit(3); } if (read(incore, &hwtlb, sizeof(hwtlb)) < 0) { perror("read"); exit(4); } if (lseek(incore, stuff[0].n_value, 0) < 0) { perror("lseek"); exit(4); } if (read(incore, &cache_tlb_parms, sizeof(struct pdc_cache_rtn_block)) < 0) { perror("read"); exit(5); } unified_cache = cache_tlb_parms.ic_conf.f_sel; unified_tlb = cache_tlb_parms.it_conf.p_sel; pagesize=(cache_tlb_parms.it_conf.page_size?4096:2048); printf( " " ); printf("HW page size is %d bytes ", pagesize); printf("%sHW TLB walker%s ",hwtlb?"":"NO ",hwtlb?" present":"" ); printf("TLB is %s ",unified_tlb?"unified":"separate"); if ( unified_tlb ) printf("TLB size is %d entries ", cache_tlb_parms.it_size); else { printf("I TLB size is %d entries ", cache_tlb_parms.it_size); printf("D TLB size is %d entries ", cache_tlb_parms.dt_size); } printf(" Cache is %s ",unified_cache?"unified":"separate"); if ( unified_cache ) printf("cache size is %d bytes (room for %d pages) ", cache_tlb_parms.ic_size,cache_tlb_parms.ic_size/ pagesize); else { printf("I cache size is %d bytes (room for %d pages) ", cache_tlb_parms.ic_size,cache_tlb_parms.ic_size/ pagesize); printf("D cache size is %d bytes (room for %d pages) ", cache_tlb_parms.dc_size,cache_tlb_parms.dc_size/ pagesize); } printf(" One cache line is %d bytes ", cache_tlb_parms.ic_conf.blocksize*16); printf("Cache lines per chunk: %d ", cache_tlb_parms.ic_conf.lines_per_chunk ); } root@hpeos002[] # root@hpeos002[] # getconf KERNEL_BITS 32 root@hpeos002[] # echo "cpu_arch_is_2_0/D" | adb /stand/vmunix /dev/kmem cpu_arch_is_2_0: cpu_arch_is_2_0: 0 root@hpeos002[] # cc +DD32 -lelf -o infocache32 infocache32.c root@hpeos002[] # ./infocache32 Kernel = /stand/vmunix HW page size is 4096 bytes HW TLB walker present TLB is unified TLB size is 64 entries Cache is separate I cache size is 131072 bytes (room for 32 pages) D cache size is 131072 bytes (room for 32 pages) One cache line is 32 bytes Cache lines per chunk: 1 root@hpeos002[] #
root@hpeos003[] cat infocache64.c #include <fcntl.h> #include <nlist.h> #include <time.h> #include <machine/cpu.h> #include <machine/pdc_rqsts.h> struct nlist64 stuff[] = { {"cache_tlb_parms"}, {"cpu_has_hw_tlb_assist"}, {0} }; main(argc, argv) int argc; char **argv; { int hwtlb; int unified_cache,unified_tlb; char *kernel; int incore; int pagesize; struct pdc_cache_rtn_block cache_tlb_parms; if ( argc != 2 ) kernel="/stand/vmunix"; else kernel=argv[1]; printf("Kernel = %s ", kernel); if ( (nlist64(kernel, stuff)) < 0) { perror("nlist"); exit(1); } if ( (incore = open("/dev/mem", O_RDONLY)) < 0) { perror("incore"); exit(2); } if (lseek(incore, stuff[1].n_value, 0) < 0) { perror("lseek"); exit(3); } if (read(incore, &hwtlb, sizeof(hwtlb)) < 0) { perror("read"); exit(4); } if (lseek(incore, stuff[0].n_value, 0) < 0) { perror("lseek"); exit(4); } if ( (read(incore, &cache_tlb_parms, sizeof(struct pdc_cache_rtn_block)) ) < 0) { perror("read"); exit(5); } unified_cache = cache_tlb_parms.ic_conf.f_sel; unified_tlb = cache_tlb_parms.it_conf.p_sel; pagesize=(cache_tlb_parms.it_conf.page_size?4096:2048); printf( " " ); printf("HW page size is %d bytes ", pagesize); printf("%sHW TLB walker%s ",hwtlb?"":"NO ",hwtlb?" present":"" ); printf("TLB is %s ",unified_tlb?"unified":"separate"); if ( unified_tlb ) printf("TLB size is %d entries ", cache_tlb_parms.it_size); else { printf("I TLB size is %d entries ", cache_tlb_parms.it_size); printf("D TLB size is %d entries ", cache_tlb_parms.dt_size); } printf(" Cache is %s ",unified_cache?"unified":"separate"); if ( unified_cache ) printf("cache size is %d bytes (room for %d pages) ", cache_tlb_parms.ic_size,cache_tlb_parms.ic_size/ pagesize); else { printf("I cache size is %d bytes (room for %d pages) ", cache_tlb_parms.ic_size,cache_tlb_parms.ic_size/ pagesize); printf("D cache size is %d bytes (room for %d pages) ", cache_tlb_parms.dc_size,cache_tlb_parms.dc_size/ pagesize); } printf(" One cache line is %d bytes ", cache_tlb_parms.ic_conf.blocksize*16); printf("Cache lines per chunk: %d ", cache_tlb_parms.ic_conf.lines_per_chunk ); } root@hpeos003[] root@hpeos003[] getconf KERNEL_BITS 64 root@hpeos003[] echo "cpu_arch_is_2_0/D" | adb /stand/vmunix /dev/kmem cpu_arch_is_2_0: cpu_arch_is_2_0: 1 root@hpeos003[] cc +DD64 -lelf -o infocache64 infocache64.c root@hpeos003[] ./infocache64 Kernel = /stand/vmunix HW page size is 4096 bytes NO HW TLB walker TLB is unified TLB size is 240 entries Cache is separate I cache size is 786432 bytes (room for 192 pages) D cache size is 1572864 bytes (room for 384 pages) One cache line is 64 bytes Cache lines per chunk: 1 root@hpeos003[]
root@hpeos002[] # cat dump_ioconfig.c #include <stdio.h> #include <limits.h> #include <errno.h> #include <sys/ioparams.h> main(argc,argv) int argc; char *argv[]; { char hwpath[LINE_MAX]; char *iofilename; FILE *iofile; int i,j,cookie; union ioconfig_record record; if ( argc < 2 ) { iofilename = IOCONFIG_FILE; } else { iofilename = argv[1]; } if ( ( iofile = fopen(iofilename,"r") ) == NULL ) { perror(iofilename); exit(errno); } if ( fread(&cookie,sizeof(cookie),1,iofile) != 1 ) { perror("fread cookie (1)"); exit(errno); } if ( cookie != IOCONFIG_MAGIC ) { fprintf(stderr,"%s s not a valid ioconfig file. Bad magic(0x%08X). ", iofilename, cookie); exit(EINVAL); } if ( fread(&cookie,sizeof(cookie),1,iofile) != 1 ) { perror("fread cookie (2)"); exit(errno); } fprintf(stdout,"Class Instance H/W Path Driver "); fprintf(stdout,"===================================================== "); while ( fread(&record,sizeof(record),1,iofile) == 1 ) { if ( record.rec_name[0] != '_' ) { memset(hwpath,NULL,sizeof(hwpath)); if ( !IS_NULL_HW_PATH(&record.ioc.hw_path) && VERIFY_HW_PATH(&record.ioc.hw_path) ) { for ( j = 0, i = record.ioc.hw_path.first_index; i <= record.ioc.hw_path.last_index; ++i,j+=3 ) sprintf(&hwpath[j],"%3d",record.ioc.hw_path.addr[i]); } printf("%-12s",record.ioc.class); printf("%-8d",record.ioc.instance); printf("%-27s",hwpath); printf("%-17s ",record.ioc.name); } else { if ( !strcmp(record.rec_name,DYN_MAJOR_REC) ) { printf("%-13s b:%3d c:%3d %-17s ", record.dm.rec_name, record.dm.b_major, record.dm.c_major, record.dm.name); continue; } } } fclose(iofile); } root@hpeos002[] # root@hpeos002[] # make dump_ioconfig cc -O dump_ioconfig.c -o dump_ioconfig root@hpeos002[] # ./dump_ioconfig Class Instance H/W Path Driver ===================================================== graphics 0 1 graph3 ext_bus 0 2 0 1 c720 disk 0 2 0 1 0 0 sdisk disk 1 2 0 1 1 0 sdisk disk 2 2 0 1 2 0 sdisk tape 0 2 0 1 3 0 stape disk 3 2 0 1 6 0 sdisk lan 0 2 0 2 lan2 tty 0 2 0 4 asio0 ext_bus 1 2 0 6 CentIf audio 0 2 0 8 audio pc 0 2 0 10 fdc ps2 0 2 0 11 ps2 lan 1 4 0 1 lan2 hil 0 5 0 1 hil tty 1 5 0 2 asio0 ctl 0 2 0 1 7 0 sctl _DYN_MAJOR b: -1 c: 2 devkrs _DYN_MAJOR b: -1 c: 4 lpr0 _DYN_MAJOR b: -1 c: 5 td _DYN_MAJOR b: -1 c: 6 btlan _DYN_MAJOR b: -1 c: 7 ip _DYN_MAJOR b: -1 c: 8 arp _DYN_MAJOR b: -1 c: 10 rawip _DYN_MAJOR b: -1 c: 11 tcp _DYN_MAJOR b: -1 c: 12 udp _DYN_MAJOR b: -1 c: 13 stcpmap _DYN_MAJOR b: -1 c: 14 nuls _DYN_MAJOR b: -1 c: 15 netqa _DYN_MAJOR b: -1 c: 18 tun _DYN_MAJOR b: -1 c: 19 telm _DYN_MAJOR b: -1 c: 20 tels _DYN_MAJOR b: -1 c: 21 tlclts _DYN_MAJOR b: -1 c: 22 tlcots _DYN_MAJOR b: -1 c: 23 tlcotsod _DYN_MAJOR b: -1 c: 25 fcT1_cntl _DYN_MAJOR b: -1 c: 26 fcp _DYN_MAJOR b: -1 c: 31 fddi4 _DYN_MAJOR b: -1 c: 32 btlan0 _DYN_MAJOR b: -1 c: 33 fddi0 _DYN_MAJOR b: -1 c: 36 fddi3 _DYN_MAJOR b: -1 c: 37 btlan1 _DYN_MAJOR b: -1 c: 44 pcitr _DYN_MAJOR b: -1 c: 45 cxperf _DYN_MAJOR b: -1 c: 48 maclan _DYN_MAJOR b: 0 c: 49 dmp _DYN_MAJOR b: 1 c: 50 vol _DYN_MAJOR b: -1 c: 51 vols _DYN_MAJOR b: -1 c: 54 cifs _DYN_MAJOR b: -1 c: 57 krm _DYN_MAJOR b: -1 c: 58 ip6 _DYN_MAJOR b: -1 c: 61 udp6 _DYN_MAJOR b: -1 c: 62 rawip6 _DYN_MAJOR b: -1 c: 63 tcp6 _DYN_MAJOR b: -1 c: 67 idds root@hpeos002[] #
# cat numCPU.c #include <errno.h> #include <stdio.h> #include <stdlib.h> #include <sys/mpctl.h> main(argc,argv) int argc; char *argv[]; { spu_t new_processor; printf("Number of locality domains = %d ", mpctl(MPC_GETNUMLDOMS_SYS,0,0)); printf("Number of processors = %d ",mpctl(MPC_GETNUMSPUS_SYS,0,0)); } # # make numCPU cc -O numCPU.c -o numCPU (Bundled) cc: warning 480: The -O option is available only with the C/ANSI C product; ignored. /usr/ccs/bin/ld: (Warning) At least one PA 2.0 object file (numCPU.o) was detected. The linked output may not run on a PA 1.x system. # ./numCPU Number of locality domains = 1 Number of processors = 4 #
# cat setCPU.c #include <errno.h> #include <stdio.h> #include <stdlib.h> #include <sys/mpctl.h> main(argc,argv) int argc; char *argv[]; { spu_t new_processor; int pid; if ( argc < 3 ) { printf(" 07ERROR : %s <processor> <prog> ", argv[0]); exit(1); } printf("Number of locality domains = %d ", mpctl(MPC_GETNUMLDOMS_SYS,0,0 )); printf("Number of processors = %d ",mpctl(MPC_GETNUMSPUS_SYS,0,0)); if ( fork() == 0) { pid=getpid(); if ( new_processor=mpctl(MPC_SETPROCESS_FORCE, atoi(argv[1]), pid) == -1 ) perror("mpctl-SETPROCESS"); else printf("New processor for proc > %d < == %d ", pid, mpctl(MPC_GETCURRENTSPU,0,0)); if ( execl(argv[2], argv[2], (char *)0) == -1 ) { perror("execl"); exit(1); } exit(0); } } # # ioscan -fnkC processor Class I H/W Path Driver S/W State H/W Type Description =================================================================== processor 0 2/10 processor CLAIMED PROCESSOR Processor processor 1 2/11 processor CLAIMED PROCESSOR Processor processor 2 2/12 processor CLAIMED PROCESSOR Processor processor 3 2/13 processor CLAIMED PROCESSOR Processor # # getconf KERNEL_BITS 64 # echo "cpu_arch_is_2_0/D" | adb /stand/vmunix /dev/kmem cpu_arch_is_2_0: cpu_arch_is_2_0: 1 # # make setCPU cc -O setCPU.c -o setCPU (Bundled) cc: warning 480: The -O option is available only with the C/ANSI C product; ignored. /usr/ccs/bin/ld: (Warning) At least one PA 2.0 object file (setCPU.o) was detected. The linked output may not run on a PA 1.x system. # # ./setCPU 2 ./bigcpu Number of locality domains = 1 Number of processors = 4 New processor for proc > 12325 < == 2 #
# cat clockwatch.c /**************************************************************************** clockwatch Simple daemon program that spawns a child then dies. The child will wake-up and write the date and time into a logfile. The logfile is called "watchlog". By default it lives in /tmp To change the location simply pass a directory name on the command line # clockwatch /var/adm Will result in the logfile /var/adm/watchlog To kill clockwatch use SIGUSR1. This will get rid of a PID file. The PID file is in the same directory as the logfile e.g. /var/adm/.watchpid from the previous example. If the PID file exists in the next invocation, clockwatch will terminate as it "worried" the old PID file is still hangin' around. Enjoy ... KIM Charles Keenan 2003 [email protected] **************************************************************************** */ #include <stdio.h> #include <limits.h> #include <unistd.h> #include <signal.h> #include <time.h> #include <sys/stat.h> struct timeval tp; struct timezone tzp; struct tm *times; char WATCHPID[1024]; char WATCHLOG[1024]; char hostname[16]; FILE *pidFILE; FILE *logFILE; goodbye() { gettimeofday(&tp, &tzp); times=localtime(&tp.tv_sec); fprintf(logFILE,"EXITING (%s) %.2d/%.2d/%d @ %.2d:%.2d:%.2d ", hostname, times->tm_mon + 1, times->tm_mday, (times->tm_year)+1900,times->tm_hour,times->tm_min,times->tm_sec); fflush(logFILE); fclose(logFILE); unlink(WATCHPID); exit(1); } main(argc,argv) int argc; char *argv[]; { int pid; struct stat filebuf; switch ( argc ) { case(1): strcpy(WATCHPID,"/tmp/.watchpid"); strcpy(WATCHLOG,"/tmp/watchlog"); break; case(2): if ( stat(argv[1], &filebuf ) == -1 ) { fprintf(stderr,"%s : Directory does not exist ! Exiting. ",argv[1]); exit(1); } strcpy(WATCHPID,argv[1]); strcat(WATCHPID,"/.watchpid"); strcpy(WATCHLOG,argv[1]); strcat(WATCHLOG,"/watchlog"); break; default: fprintf(stderr," 07Useage : %s [<directory>] ",argv[0]); exit(1); break; } if ( fork() == 0 ) { /* Child */ setsid(); if ( ( stat(WATCHPID, &filebuf ) ) == 0 ) { fprintf(stderr,"%s : Old PID file exists. Unknown problem! Exiting. ",WATCHPID); exit(1); } if ( ( pidFILE=fopen(WATCHPID,"w") ) == NULL ) { fprintf(stderr, "ERROR: Cannot open PID file : %s. Exiting ! ", WATCHPID); exit(2); } pid=getpid(); fprintf(pidFILE,"%d ", pid); fclose(pidFILE); if ( ( logFILE=fopen(WATCHLOG,"w") ) == NULL ) { fprintf(stderr, "ERROR: Cannot open LOG file : %s. Exiting ! ", WATCHLOG); exit(2); } if ( gethostname(&hostname, sizeof(hostname)) != 0 ) { perror("hostname"); exit(1); } fprintf(stdout,"Starting Clockwatch ; logfile = %s ",WATCHLOG); signal(SIGUSR1, goodbye); for ( ; ; ) { gettimeofday(&tp, &tzp); times=localtime(&tp.tv_sec); fprintf(logFILE,"%s %.2d/%.2d/%d @ %.2d:%.2d:%.2d ", hostname, times->tm_mon + 1, times->tm_mday, times->tm_year,times->tm_hour,times->tm_min,times->tm_sec); fflush(logFILE); sleep(10); } } else { exit(0); } } #
3.144.227.9