/* $Id: pack.c,v 1.1 2003/03/31 17:42:16 deschwen Exp $ */ #include "pack.h" /* herein the various structures (defined in "pack.h") are packed * to Perl data structures, mostly hashes. Calls to these functions * are generated by xsubpp according to the typemap. * * see perlguts(1) for some of the Perl magic used here */ /* some macros help us to keep the code below understandable */ /* pack the integer value in p->name into hash hv * using key "name" */ #define PACK_IV(name) \ sv = newSViv(p->name);\ if (hv_store(hv, #name, sizeof(#name)-1, sv, 0) == NULL) {\ warn("__FILE__:__LINE__ failed to pack '" ## #name ## "' elem");\ }\ /* pack the double value in p->name into hash hv * using key "name" */ #define PACK_NV(name) \ sv = newSVnv(p->name);\ if (hv_store(hv, #name, sizeof(#name)-1, sv, 0) == NULL) {\ warn("__FILE__:__LINE__ failed to pack '" ## #name ## "' elem");\ }\ /* pack the string starting at p->name into hash hv * using key "name", string length in len (calculated if len == 0) */ #define PACK_PV(name, len) \ sv = newSVpv(p->name, len);\ if (hv_store(hv, #name, sizeof(#name)-1, sv, 0) == NULL) {\ warn("__FILE__:__LINE__ failed to pack '" ## #name ## "' elem");\ }\ /* pack reference to av into hash hv * using key "name" */ #define PACK_AV(name) \ sv = newRV_noinc((SV*)av);\ if (hv_store(hv, #name, sizeof(#name)-1, sv, 0) == NULL) {\ warn("__FILE__:__LINE__ failed to pack '" ## #name ## "' elem");\ }\ /* pack struct pst_static into a hash * and put a reference to this hash onto Perl stack */ void XS_pack_pst_staticPtr(SV* st, pst_static* p) { HV *hv = newHV(); SV *sv; PACK_IV(boot_time); PACK_IV(physical_memory); PACK_IV(page_size); PACK_IV(cpu_states); PACK_IV(pst_status_size); PACK_IV(pst_static_size); PACK_IV(pst_dynamic_size); PACK_IV(pst_vminfo_size); PACK_IV(command_length); PACK_IV(pst_processor_size); PACK_IV(pst_diskinfo_size); PACK_IV(pst_lvinfo_size); PACK_IV(pst_swapinfo_size); PACK_IV(pst_maxmem); PACK_IV(pst_lotsfree); PACK_IV(pst_desfree); PACK_IV(pst_minfree); PACK_IV(pst_max_ninode); PACK_IV(pst_max_nfile); PACK_IV(pst_stable_size); { /* pst_supported_pgsize[] */ AV *av = newAV(); int i; for (i=0; ipst_supported_pgsize[i])); } PACK_AV(pst_supported_pgsize); } /* put ref to hv onto stack */ sv = newSVrv(st, NULL); SvREFCNT_dec(sv); SvRV(st) = (SV*)hv; } /* pack struct pst_dynamic into a hash * and put a reference to this hash onto Perl stack */ void XS_pack_pst_dynamicPtr(SV* st, pst_dynamic* p) { HV *hv = newHV(); SV *sv; PACK_IV(psd_proc_cnt); /* MP: number of active processors */ PACK_IV(psd_max_proc_cnt); /* MP: max active processors */ PACK_IV(psd_last_pid); /* last run process ID */ PACK_IV(psd_rq); /* run queue length */ PACK_IV(psd_dw); /* jobs in disk wait */ PACK_IV(psd_pw); /* jobs in page wait */ PACK_IV(psd_sl); /* jobs sleeping in core */ PACK_IV(psd_sw); /* swapped out runnable jobs */ PACK_IV(psd_vm); /* total virtual memory */ PACK_IV(psd_avm); /* active virtual memory */ PACK_IV(psd_rm); /* total real memory */ PACK_IV(psd_arm); /* active real memory */ PACK_IV(psd_vmtxt); /* virt mem text */ PACK_IV(psd_avmtxt); /* active virt mem text */ PACK_IV(psd_rmtxt); /* real mem text */ PACK_IV(psd_armtxt); /* active real mem text */ PACK_IV(psd_free); /* free memory pages */ PACK_NV(psd_avg_1_min); /* global run queue lengths */ PACK_NV(psd_avg_5_min); PACK_NV(psd_avg_15_min); PACK_IV(psd_openlv); /* # of open Logical Volumes */ PACK_IV(psd_openvg); /* # of open LV Volume groups */ PACK_IV(psd_allocpbuf); /* # of allocated LV pvol buffers */ PACK_IV(psd_usedpbuf); /* # of LV pvol buffers in used */ PACK_IV(psd_maxpbuf); /* max # of LV pvol buffers avail. */ PACK_IV(psd_activeprocs); /* # of active proc table entries */ PACK_IV(psd_activeinodes); /* # of active inode table entries */ PACK_IV(psd_activefiles); /* # of active file table entries */ PACK_IV(psd_mpdcnt); /* # of (bad) memory pages deallocated */ PACK_IV(psd_procovf); /* # of times the proc table overflowed */ PACK_IV(psd_inodeovf); /* # of times the inode table overflowed */ PACK_IV(psd_fileovf); /* # of times the file table overflowed */ PACK_IV(psd_global_virtual); /* Available global virt space (pages) */ PACK_IV(psd_valid); /* This is a vector that will indicate * if a certain field in is valid */ { /* global cpu time/state */ AV *av = newAV(); int i; for (i=0; ipsd_cpu_time[i])); } PACK_AV(psd_cpu_time); } /* put ref to hv onto stack */ sv = newSVrv(st, NULL); SvREFCNT_dec(sv); SvRV(st) = (SV*)hv; } /* pack struct pst_vminfo into a hash * and put a reference to this hash onto Perl stack */ void XS_pack_pst_vminfoPtr(SV* st, pst_vminfo* p) { HV *hv = newHV(); SV *sv; PACK_IV(psv_rdfree); /* rate: pages freed by daemon */ PACK_IV(psv_rintr); /* device interrupts */ PACK_IV(psv_rpgpgin); /* pages paged in */ PACK_IV(psv_rpgpgout); /* pages paged out */ PACK_IV(psv_rpgrec); /* total page reclaims */ PACK_IV(psv_rpgtlb); /* tlb flushes - 800 only */ PACK_IV(psv_rscan); /* scans in pageout daemon */ PACK_IV(psv_rswtch); /* context switches */ PACK_IV(psv_rsyscall); /* calls to syscall() */ PACK_IV(psv_rxifrec); /* found in freelist rather than in filesys */ PACK_IV(psv_rxsfrec); /* found in freelist rather than on swapdev */ PACK_IV(psv_cfree); /* cnt: free memory pages */ PACK_IV(psv_sswpin); /* sum: swapins */ PACK_IV(psv_sswpout); /* swapouts */ PACK_IV(psv_sdfree); /* pages freed by daemon */ PACK_IV(psv_sexfod); /* pages filled on demand from executables */ PACK_IV(psv_sfaults); /* total faults taken */ PACK_IV(psv_sintr); /* device interrupts */ PACK_IV(psv_sintrans); /* intransit blocking page faults */ PACK_IV(psv_snexfod); /* number of exfod's created */ PACK_IV(psv_snzfod); /* number of zero filled on demand */ PACK_IV(psv_spgfrec); /* page reclaims from free list */ PACK_IV(psv_spgin); /* pageins */ PACK_IV(psv_spgout); /* pageouts */ PACK_IV(psv_spgpgin); /* pages paged in */ PACK_IV(psv_spgpgout); /* pages paged out */ PACK_IV(psv_spswpin); /* pages swapped in */ PACK_IV(psv_spswpout); /* pages swapped out */ PACK_IV(psv_srev); /* revolutions of the hand */ PACK_IV(psv_sseqfree); /* pages taken from sequential programs */ PACK_IV(psv_sswtch); /* context switches */ PACK_IV(psv_ssyscall); /* calls to syscall() */ PACK_IV(psv_strap); /* calls to trap */ PACK_IV(psv_sxifrec); /* found in free list rather than in filesys */ PACK_IV(psv_sxsfrec); /* found on free list rather than on swapdev*/ PACK_IV(psv_szfod); /* pages zero filled on demand */ PACK_IV(psv_sscan); /* scans in pageout daemon */ PACK_IV(psv_spgrec); /* total page reclaims */ PACK_IV(psv_deficit); /* estimate of needs of new swapped-in procs */ PACK_IV(psv_tknin); /* number of characters read from ttys */ PACK_IV(psv_tknout); /* number of characters written to ttys */ PACK_IV(psv_cntfork); /* number of forks */ PACK_IV(psv_sizfork); /* number of pages forked */ PACK_IV(psv_lreads); /* number of disk blk reads issued */ PACK_IV(psv_lwrites); /* number of disk blk writes issued */ PACK_IV(psv_swpocc); /* # of times swrq occ'd since boot */ PACK_IV(psv_swpque); /* cumulative len of swrq since boot */ PACK_IV(psv_paging_thold); /* paging threshold, moves between pst_desfree & pst_lotsfree */ PACK_IV(psv_sysmem); /* pages of memory unavailable for in-memory backing store */ PACK_IV(psv_swapspc_cnt); /* pages of on-disk backing store */ PACK_IV(psv_swapspc_max); /* max pages of on-disk backing store */ PACK_IV(psv_swapmem_cnt); /* pages of in-memory backing store */ PACK_IV(psv_swapmem_max); /* max pages of in-memory backing store */ PACK_IV(psv_swapper_mem); /* pages of backing store management */ PACK_IV(psv_lreadsize); /* # of char xfer'd by bread */ PACK_IV(psv_lwritesize); /* # of char xfer'd by bwrite */ PACK_IV(psv_swapmem_on); /* in-memory backing store enabled */ { /* success by page size of LP fault page size selection */ AV *av = newAV(); int i; for (i=0; ipsv_select_success[i])); } PACK_AV(psv_select_success); } { /* failure by page size of LP fault page size selection */ AV *av = newAV(); int i; for (i=0; ipsv_select_failure[i])); } PACK_AV(psv_select_failure); } { /* success by page size of LP allocation */ AV *av = newAV(); int i; for (i=0; ipsv_pgalloc_success[i])); } PACK_AV(psv_pgalloc_success); } { /* failure by page size of LP allocation */ AV *av = newAV(); int i; for (i=0; ipsv_pgalloc_failure[i])); } PACK_AV(psv_pgalloc_failure); } { /* LP demotions by page size */ AV *av = newAV(); int i; for (i=0; ipsv_demotions[i])); } PACK_AV(psv_demotions); } /* put ref to hv onto stack */ sv = newSVrv(st, NULL); SvREFCNT_dec(sv); SvRV(st) = (SV*)hv; } /* pack a number of (struct pst_swapinfo) into an array of hashes * and put a reference to this array onto Perl stack */ void XS_pack_my_swapinfoPtr(SV* st, my_swapinfo* q) { AV *av = newAV(); SV *sv; pst_swapinfo *p ; int i; for (i = 0, p = q->data; i < (q->size); i++, p++) { HV *hv = newHV(); PACK_IV(pss_idx); PACK_IV(pss_flags); PACK_IV(pss_priority); PACK_IV(pss_nfpgs); PACK_IV(pss_swapchunk); if (p->pss_flags & SW_BLOCK) { PACK_IV(pss_major); PACK_IV(pss_minor); PACK_IV(pss_start); PACK_IV(pss_nblksavail); PACK_IV(pss_nblksenabled); } else if (p->pss_flags & SW_FS){ PACK_IV(pss_allocated); PACK_IV(pss_min); PACK_IV(pss_limit); PACK_IV(pss_reserve); PACK_PV(pss_mntpt, 0); } av_push(av, newRV_noinc((SV*)hv)); } /* put ref to av onto stack */ sv = newSVrv(st, NULL); SvREFCNT_dec(sv); SvRV(st) = (SV*)av; } /* pack a number of (struct pst_status) into an array of hashes * and put a reference to this array onto Perl stack */ void XS_pack_my_statusPtr(SV* st, my_status* q) { AV *av = newAV(); SV *sv; pst_status *p ; int i; for (i = 0, p = q->data; i < (q->size); i++, p++) { HV *hv = newHV(); PACK_IV(pst_idx); /* Index for further pstat() requests */ PACK_IV(pst_uid); /* Real UID */ PACK_IV(pst_pid); /* Process ID */ PACK_IV(pst_ppid); /* Parent process ID */ PACK_IV(pst_dsize); /* # real pages used for data */ PACK_IV(pst_tsize); /* # real pages used for text */ PACK_IV(pst_ssize); /* # real pages used for stack */ PACK_IV(pst_nice); /* Nice value */ PACK_IV(pst_pgrp); /* Process group of this process */ PACK_IV(pst_pri); /* priority of process */ PACK_IV(pst_addr); /* address of process (in memory) */ PACK_IV(pst_cpu); /* processor utilization for scheduling */ PACK_IV(pst_utime); /* user time spent executing (in seconds) */ PACK_IV(pst_stime); /* system time spent executing (in seconds) */ PACK_IV(pst_start); /* time process started (seconds since epoch) */ PACK_IV(pst_flag); /* flags associated with process */ PACK_IV(pst_stat); /* Current status */ PACK_IV(pst_wchan); /* If state PS_SLEEP, value sleeping on */ PACK_IV(pst_procnum); /* processor this proc last run on */ PACK_PV(pst_cmd, 0); /* Command line for the process, if available */ PACK_IV(pst_time); /* resident time for scheduling */ PACK_IV(pst_cpticks); /* ticks of cpu time */ PACK_IV(pst_cptickstotal); /* total ticks for life of process */ PACK_IV(pst_fss); /* fair share scheduler group id */ PACK_NV(pst_pctcpu); /* %cpu for this process during p_time */ PACK_IV(pst_rssize); /* resident set size for process (private pages) */ PACK_IV(pst_suid); /* saved UID */ PACK_PV(pst_ucomm, 0); /* executable basename the process is running */ PACK_IV(pst_shmsize); /* # real pages used for shared memory */ PACK_IV(pst_mmsize); /* # real pages used for memory mapped files */ PACK_IV(pst_usize); /* # real pages used for U-Area & K-Stack */ PACK_IV(pst_iosize); /* # real pages used for I/O device mapping */ PACK_IV(pst_vtsize); /* # virtual pages used for text */ PACK_IV(pst_vdsize); /* # virtual pages used for data */ PACK_IV(pst_vssize); /* # virtual pages used for stack */ PACK_IV(pst_vshmsize); /* # virtual pages used for shared memory */ PACK_IV(pst_vmmsize); /* # virtual pages used for mem-mapped files */ PACK_IV(pst_vusize); /* # virtual pages used for U-Area & K-Stack */ PACK_IV(pst_viosize); /* # virtual pages used for I/O dev mapping */ PACK_IV(pst_minorfaults); /* # page reclaims for the process */ PACK_IV(pst_majorfaults); /* # page faults needing disk access */ PACK_IV(pst_nswap); /* # of swaps for the process */ PACK_IV(pst_nsignals); /* # signals received by the process */ PACK_IV(pst_msgrcv); /* # socket msgs received by the proc*/ PACK_IV(pst_msgsnd); /* # of socket msgs sent by the proc */ PACK_IV(pst_maxrss); /* highwater mark for proc resident set size */ PACK_IV(pst_sid); /* session ID */ PACK_IV(pst_schedpolicy); /* scheduling policy for the process */ PACK_IV(pst_ticksleft); /* clock ticks left in process' RR timeslice */ PACK_IV(pst_highestfd); /* highest file descriptor currently opened */ PACK_IV(pst_euid); /* Effective UID */ PACK_IV(pst_egid); /* Effective GID */ PACK_IV(pst_ioch); /* # of characters read/written */ PACK_IV(pst_gid); /* Real GID */ PACK_IV(pst_sgid); /* saved effective gid */ PACK_IV(pst_nlwps); /* # lwps within this process */ PACK_IV(pst_lwpid); /* LWP identifier. NOTE: If this process is * multi-threaded, this is an lwpid of one of the * LWPs in the process at this exact moment, which * LWP is undefined (random) */ PACK_IV(pst_valid); /* This is a vector that will indicate if a * certain field in the structure is valid or not. */ PACK_IV(pst_text_size); /* Page size used for text objects. */ PACK_IV(pst_data_size); /* Page size used for data objects. */ /* push reference to hash into av */ av_push(av, newRV_noinc((SV*)hv)); } /* put ref to av onto stack */ sv = newSVrv(st, NULL); SvREFCNT_dec(sv); SvRV(st) = (SV*)av; } /* pack a number of (struct pst_processor) into an array of hashes * and put a reference to this array onto Perl stack */ void XS_pack_my_processorPtr(SV *st, my_processor *q) { AV *av = newAV(); SV *sv; pst_processor *p ; int i; for (i = 0, p = q->data; i < (q->size); i++, p++) { HV *hv = newHV(); PACK_IV(psp_idx); /* Index of the current spu in the * array of processor statistic entries */ PACK_IV(psp_fsreads); /* # of reads from filesys blocks. */ PACK_IV(psp_fswrites); /* # of writes to filesys blocks. */ PACK_IV(psp_nfsreads); /* # of nfs disk blk reads issued. */ PACK_IV(psp_nfswrites); /* # of nfs disk blk writes issued. */ PACK_IV(psp_bnfsread); /* # of bytes read from NFS. */ PACK_IV(psp_bnfswrite); /* # of bytes written to NFS. */ PACK_IV(psp_phread); /* # of physical reads to raw devs. */ PACK_IV(psp_phwrite); /* # of physical writes to raw devs. */ PACK_IV(psp_runocc); /* # of times the processor had * processes waiting to run. This * running total is updated once * a second. */ PACK_IV(psp_runque); /* # of processes the processor had * waiting to run. This running total * is updated once a second. */ PACK_IV(psp_sysexec); /* # of exec system calls. */ PACK_IV(psp_sysread); /* # of read system calls. */ PACK_IV(psp_syswrite); /* # of write system calls. */ PACK_IV(psp_sysnami); /* # of calls to sysnami(). */ PACK_IV(psp_sysiget); /* # of calls to sysiget(). */ PACK_IV(psp_dirblk); /* # of filesystem blocks read doing * directory lookup. */ PACK_IV(psp_semacnt); /* # of System V semaphore ops. */ PACK_IV(psp_msgcnt); /* # of System V message ops. */ PACK_IV(psp_muxincnt); /* # of MUX interrupts received. */ PACK_IV(psp_muxoutcnt); /* # of MUX interrupts sent. */ PACK_IV(psp_ttyrawcnt); /* # of raw characters read. */ PACK_IV(psp_ttycanoncnt); /* # of canonical chars processed. */ PACK_IV(psp_ttyoutcnt); /* # of characters output. */ PACK_IV(psp_iticksperclktick); /* interval timer counts (CR16) * per clock tick, * see sysconf(_SC_CLK_TCK) */ PACK_IV(psp_sysselect); /* # of select system calls. */ PACK_NV(psp_avg_1_min); /* per-processor run queue lengths */ PACK_NV(psp_avg_5_min); PACK_NV(psp_avg_15_min); { /* per-processor cpu time/state */ AV *av = newAV(); int i; for (i=0; ipsp_cpu_time[i])); } PACK_AV(psp_cpu_time); } /* push reference to hash into av */ av_push(av, newRV_noinc((SV*)hv)); } /* put ref to av onto stack */ sv = newSVrv(st, NULL); SvREFCNT_dec(sv); SvRV(st) = (SV*)av; }