// Memory values std::string mem_string() { // These values are in bytes int64_t total_mem; int64_t used_mem; int64_t unused_mem; // blah vm_size_t page_size; mach_port_t mach_port; mach_msg_type_number_t count; vm_statistics_data_t vm_stats; std::ostringstream oss; // Get total physical memory int mib[2]; mib[0] = CTL_HW; mib[1] = HW_MEMSIZE; size_t length = sizeof(int64_t); sysctl(mib, 2, &total_mem, &length, NULL, 0); mach_port = mach_host_self(); count = sizeof(vm_stats) / sizeof(natural_t); if (KERN_SUCCESS == host_page_size(mach_port, &page_size) && KERN_SUCCESS == host_statistics(mach_port, HOST_VM_INFO, (host_info_t)&vm_stats, &count)) { unused_mem = (int64_t)vm_stats.free_count * (int64_t)page_size; used_mem = ((int64_t)vm_stats.active_count + (int64_t)vm_stats.inactive_count + (int64_t)vm_stats.wire_count) * (int64_t)page_size; } oss << used_mem / 1024 / 1024 << '/' << total_mem / 1024 / 1024 << "MB"; return oss.str(); }
const FPlatformMemoryConstants& FMacPlatformMemory::GetConstants() { static FPlatformMemoryConstants MemoryConstants; if( MemoryConstants.TotalPhysical == 0 ) { // Gather platform memory constants. // Get page size. vm_size_t PageSize; host_page_size(mach_host_self(), &PageSize); // Get swap file info xsw_usage SwapUsage; SIZE_T Size = sizeof(SwapUsage); sysctlbyname("vm.swapusage", &SwapUsage, &Size, NULL, 0); // Get memory. vm_statistics Stats; mach_msg_type_number_t StatsSize = sizeof(Stats); host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t)&Stats, &StatsSize); uint64_t FreeMem = Stats.free_count * PageSize; uint64_t UsedMem = (Stats.active_count + Stats.inactive_count + Stats.wire_count) * PageSize; uint64_t TotalPhys = FreeMem + UsedMem; uint64_t TotalPageFile = SwapUsage.xsu_total; uint64_t TotalVirtual = TotalPhys + TotalPageFile; MemoryConstants.TotalPhysical = TotalPhys; MemoryConstants.TotalVirtual = TotalVirtual; MemoryConstants.PageSize = (uint32)PageSize; MemoryConstants.TotalPhysicalGB = (MemoryConstants.TotalPhysical + 1024 * 1024 * 1024 - 1) / 1024 / 1024 / 1024; } return MemoryConstants; }
MemoryInfo getMemoryInfo() { MemoryInfo infos; #if defined( __WINDOWS__ ) MEMORYSTATUS memory; GlobalMemoryStatus( &memory ); // memory.dwMemoryLoad; infos._totalRam = memory.dwTotalPhys; infos._freeRam = memory.dwAvailPhys; //memory.dwTotalPageFile; //memory.dwAvailPageFile; infos._totalSwap = memory.dwTotalVirtual; infos._freeSwap = memory.dwAvailVirtual; #elif defined( __LINUX__ ) struct sysinfo sys_info; sysinfo( &sys_info ); infos._totalRam = sys_info.totalram * sys_info.mem_unit; infos._freeRam = sys_info.freeram * sys_info.mem_unit; //infos._sharedRam = sys_info.sharedram * sys_info.mem_unit; //infos._bufferRam = sys_info.bufferram * sys_info.mem_unit; infos._totalSwap = sys_info.totalswap * sys_info.mem_unit; infos._freeSwap = sys_info.freeswap * sys_info.mem_unit; // TUTTLE_LOG_VAR( TUTTLE_TRACE, sys_info.sharedram * sys_info.mem_unit ); // TUTTLE_LOG_VAR( TUTTLE_TRACE, sys_info.bufferram * sys_info.mem_unit ); #elif defined( __APPLE__ ) uint64_t physmem; size_t len = sizeof physmem; int mib[2] = { CTL_HW, HW_MEMSIZE }; size_t miblen = sizeof(mib) / sizeof(mib[0]); // Total physical memory. if (sysctl(mib, miblen, &physmem, &len, NULL, 0) == 0 && len == sizeof (physmem)) infos._totalRam = physmem; // Virtual memory. mib[0] = CTL_VM; mib[1] = VM_SWAPUSAGE; struct xsw_usage swap; len = sizeof(struct xsw_usage); if (sysctl(mib, miblen, &swap, &len, NULL, 0) == 0) { infos._totalSwap = swap.xsu_total; infos._freeSwap = swap.xsu_avail; } // In use. mach_port_t stat_port = mach_host_self(); vm_size_t page_size; vm_statistics_data_t vm_stat; mach_msg_type_number_t count = sizeof(vm_stat) / sizeof(natural_t); if (KERN_SUCCESS == host_page_size(stat_port, &page_size) && KERN_SUCCESS == host_statistics(stat_port, HOST_VM_INFO, (host_info_t)&vm_stat, &count)) { //uint64_t used = ((int64_t)vm_stat.active_count + (int64_t)vm_stat.inactive_count + (int64_t)vm_stat.wire_count) * (int64_t)page_size; //infos._freeRam = infos._totalRam - used; infos._freeRam = (int64_t)vm_stat.free_count * (int64_t)page_size; } #else // TODO: could be done on FreeBSD too // see https://github.com/xbmc/xbmc/blob/master/xbmc/linux/XMemUtils.cpp infos._totalRam = infos._freeRam = infos._totalSwap = infos._freeSwap = std::numeric_limits<std::size_t>::max(); #endif TUTTLE_LOG_DEBUG( "[Memory infos] " << infos ); return infos; }
int readCpuCounters(SFLHost_cpu_counters *cpu) { mach_port_t machport = mach_host_self(); // share this at top level like xen handle $$$ int gotData = NO; struct clockinfo ci = { 0 }; size_t len = sizeof(ci); if(sysctlbyname("kern.clockrate", &ci, &len, NULL, 0) != 0) { myLog(LOG_ERR, "sysctl(<kern.clockrate>) failed : %s", strerror(errno)); } else { // cpu ticks. From ganglia/libmetrics/Darwin/metrics.c:cpu_user_func() mach_msg_type_number_t count = HOST_CPU_LOAD_INFO_COUNT; host_cpu_load_info_data_t cpuStats; kern_return_t ret = host_statistics(machport, HOST_CPU_LOAD_INFO, (host_info_t)&cpuStats, &count); if (ret != KERN_SUCCESS) { myLog(LOG_ERR, "readCpuCounters: host_statistics() : %s", strerror(errno)); } else { gotData = YES; cpu->cpu_user = (uint32_t)(JIFFY_TO_MS(cpuStats.cpu_ticks[CPU_STATE_USER], ci.hz)); cpu->cpu_nice = (uint32_t)(JIFFY_TO_MS(cpuStats.cpu_ticks[CPU_STATE_NICE], ci.hz)); cpu->cpu_system = (uint32_t)(JIFFY_TO_MS(cpuStats.cpu_ticks[CPU_STATE_SYSTEM], ci.hz)); cpu->cpu_idle = (uint32_t)(JIFFY_TO_MS(cpuStats.cpu_ticks[CPU_STATE_IDLE], ci.hz)); // $$$ // cpu->cpu_wio // cpu->cpu_intr // cpu->cpu_sintr } } double loadavg[3]; if(getloadavg(loadavg, 3) != -1) { gotData = YES; cpu->load_one = loadavg[0]; cpu->load_five = loadavg[1]; cpu->load_fifteen = loadavg[2]; } // $$$ // cpu->proc_run, // cpu->proc_total // $$$ // cpu->interrupts // cpu->contexts // cpu->uptime // num_cpus. From ganglia/libmetrics/Darwin/metrics.c:cpu_num_func() { int ncpu = 0; size_t len = sizeof(ncpu); if(sysctlbyname("hw.ncpu", &ncpu, &len, NULL, 0) != 0) { myLog(LOG_ERR, "sysctl(<ncpu>) failed : %s", strerror(errno)); } else { gotData = YES; cpu->cpu_num = (uint32_t)ncpu; } } //cpu_speed. From ganglia/libmetrics/Darwin/metrics.c:cpu_speed_func() { unsigned long cpu_speed = 0; size_t len = sizeof(cpu_speed); if(sysctlbyname("hw.cpufrequency", &cpu_speed, &len, NULL, 0) != 0) { myLog(LOG_ERR, "sysctl(<cpu_speed>) failed : %s", strerror(errno)); } else { gotData = YES; cpu->cpu_speed = (uint32_t)(cpu_speed / 1000000); // Hz to MHz } } return gotData; }
static int VM_MEMORY_FREE(const char *cmd, const char *param, unsigned flags, AGENT_RESULT *result) { #if defined(HAVE_SYS_PSTAT_H) struct pst_static pst; struct pst_dynamic dyn; long page; assert(result); init_result(result); if(pstat_getstatic(&pst, sizeof(pst), (size_t)1, 0) == -1) { return SYSINFO_RET_FAIL; } else { /* Get page size */ page = pst.page_size; /* return pst.physical_memory;*/ if (pstat_getdynamic(&dyn, sizeof(dyn), 1, 0) == -1) { return SYSINFO_RET_FAIL; } else { /* cout<<"total virtual memory allocated is " << dyn.psd_vm << " pages, " << dyn.psd_vm * page << " bytes" << endl; cout<<"active virtual memory is " << dyn.psd_avm <<" pages, " << dyn.psd_avm * page << " bytes" << endl; cout<<"total real memory is " << dyn.psd_rm << " pages, " << dyn.psd_rm * page << " bytes" << endl; cout<<"active real memory is " << dyn.psd_arm << " pages, " << dyn.psd_arm * page << " bytes" << endl; cout<<"free memory is " << dyn.psd_free << " pages, " << */ /* Free memory in bytes */ SET_UI64_RESULT(result, (zbx_uint64_t)dyn.psd_free * (zbx_uint64_t)page); return SYSINFO_RET_OK; } } #elif defined(HAVE_SYSINFO_FREERAM) struct sysinfo info; assert(result); init_result(result); if( 0 == sysinfo(&info)) { #ifdef HAVE_SYSINFO_MEM_UNIT SET_UI64_RESULT(result, (zbx_uint64_t)info.freeram * (zbx_uint64_t)info.mem_unit); #else SET_UI64_RESULT(result, info.freeram); #endif return SYSINFO_RET_OK; } else { return SYSINFO_RET_FAIL; } #elif defined(HAVE_SYS_VMMETER_VMTOTAL) int mib[2],len; struct vmtotal v; assert(result); init_result(result); len=sizeof(struct vmtotal); mib[0]=CTL_VM; mib[1]=VM_METER; sysctl(mib,2,&v,&len,NULL,0); SET_UI64_RESULT(result, v.t_free<<2); return SYSINFO_RET_OK; /* OS/X */ #elif defined(HAVE_MACH_HOST_INFO_H) vm_statistics_data_t page_info; vm_size_t pagesize; mach_msg_type_number_t count; kern_return_t kret; int ret; assert(result); init_result(result); pagesize = 0; kret = host_page_size (mach_host_self(), &pagesize); count = HOST_VM_INFO_COUNT; kret = host_statistics (mach_host_self(), HOST_VM_INFO, (host_info_t)&page_info, &count); if (kret == KERN_SUCCESS) { double pw, pa, pi, pf, pu; pw = (double)page_info.wire_count*pagesize; pa = (double)page_info.active_count*pagesize; pi = (double)page_info.inactive_count*pagesize; pf = (double)page_info.free_count*pagesize; pu = pw+pa+pi; SET_UI64_RESULT(result, pf); ret = SYSINFO_RET_OK; } else { ret = SYSINFO_RET_FAIL; } return ret; #else assert(result); init_result(result); return SYSINFO_RET_FAIL; #endif }
TCN_IMPLEMENT_CALL(jint, OS, info)(TCN_STDARGS, jlongArray inf) { jint rv; int i; jsize ilen = (*e)->GetArrayLength(e, inf); jlong *pvals = (*e)->GetLongArrayElements(e, inf, NULL); UNREFERENCED(o); if (ilen < 16) { return APR_EINVAL; } for (i = 0; i < 16; i++) pvals[i] = 0; #if defined(__linux__) { struct sysinfo info; if (sysinfo(&info)) rv = apr_get_os_error(); else { pvals[0] = (jlong)(info.totalram * info.mem_unit); pvals[1] = (jlong)(info.freeram * info.mem_unit); pvals[2] = (jlong)(info.totalswap * info.mem_unit); pvals[3] = (jlong)(info.freeswap * info.mem_unit); pvals[4] = (jlong)(info.sharedram * info.mem_unit); pvals[5] = (jlong)(info.bufferram * info.mem_unit); pvals[6] = (jlong)(100 - (info.freeram * 100 / info.totalram)); rv = APR_SUCCESS; } } #elif defined(sun) { /* static variables with basic procfs info */ static long creation = 0; /* unix timestamp of process creation */ static int psinf_fd = 0; /* file descriptor for the psinfo procfs file */ static int prusg_fd = 0; /* file descriptor for the usage procfs file */ static size_t rss = 0; /* maximum of resident set size from previous calls */ /* static variables with basic kstat info */ static kstat_ctl_t *kstat_ctl = NULL; /* kstat control object, only initialized once */ static kstat_t *kstat_cpu[MAX_CPUS]; /* array of kstat objects for per cpu statistics */ static int cpu_count = 0; /* number of cpu structures found in kstat */ static kid_t kid = 0; /* kstat ID, for which the kstat_ctl holds the correct chain */ /* non-static variables - general use */ int res = 0; /* general result state */ /* non-static variables - sysinfo/swapctl use */ long ret_sysconf; /* value returned from sysconf call */ long tck_dividend; /* factor used by transforming tick numbers to milliseconds */ long tck_divisor; /* divisor used by transforming tick numbers to milliseconds */ long sys_pagesize = sysconf(_SC_PAGESIZE); /* size of a system memory page in bytes */ long sys_clk_tck = sysconf(_SC_CLK_TCK); /* number of system ticks per second */ struct anoninfo info; /* structure for information about sizes in anonymous memory system */ /* non-static variables - procfs use */ psinfo_t psinf; /* psinfo structure from procfs */ prusage_t prusg; /* usage structure from procfs */ size_t new_rss = 0; /* resident set size read from procfs */ time_t now; /* time needed for calculating process creation time */ /* non-static variables - kstat use */ kstat_t *kstat = NULL; /* kstat working pointer */ cpu_sysinfo_t cpu; /* cpu sysinfo working pointer */ kid_t new_kid = 0; /* kstat ID returned from chain update */ int new_kstat = 0; /* flag indicating, if kstat structure has changed since last call */ rv = APR_SUCCESS; if (sys_pagesize <= 0) { rv = apr_get_os_error(); } else { ret_sysconf = sysconf(_SC_PHYS_PAGES); if (ret_sysconf >= 0) { pvals[0] = (jlong)((jlong)sys_pagesize * ret_sysconf); } else { rv = apr_get_os_error(); } ret_sysconf = sysconf(_SC_AVPHYS_PAGES); if (ret_sysconf >= 0) { pvals[1] = (jlong)((jlong)sys_pagesize * ret_sysconf); } else { rv = apr_get_os_error(); } res=swapctl(SC_AINFO, &info); if (res >= 0) { pvals[2] = (jlong)((jlong)sys_pagesize * info.ani_max); pvals[3] = (jlong)((jlong)sys_pagesize * info.ani_free); pvals[6] = (jlong)(100 - (jlong)info.ani_free * 100 / info.ani_max); } else { rv = apr_get_os_error(); } } if (psinf_fd == 0) { psinf_fd = proc_open("psinfo"); } res = proc_read(&psinf, PSINFO_T_SZ, psinf_fd); if (res >= 0) { new_rss = psinf.pr_rssize*1024; pvals[13] = (jlong)(new_rss); if (new_rss > rss) { rss = new_rss; } pvals[14] = (jlong)(rss); } else { psinf_fd = 0; rv = apr_get_os_error(); } if (prusg_fd == 0) { prusg_fd = proc_open("usage"); } res = proc_read(&prusg, PRUSAGE_T_SZ, prusg_fd); if (res >= 0) { if (creation <= 0) { time(&now); creation = (long)(now - (prusg.pr_tstamp.tv_sec - prusg.pr_create.tv_sec)); } pvals[10] = (jlong)(creation); pvals[11] = (jlong)((jlong)prusg.pr_stime.tv_sec * 1000 + (prusg.pr_stime.tv_nsec / 1000000)); pvals[12] = (jlong)((jlong)prusg.pr_utime.tv_sec * 1000 + (prusg.pr_utime.tv_nsec / 1000000)); pvals[15] = (jlong)(prusg.pr_majf); } else { prusg_fd = 0; rv = apr_get_os_error(); } if (sys_clk_tck <= 0) { rv = apr_get_os_error(); } else { tck_dividend = 1000; tck_divisor = sys_clk_tck; for (i = 0; i < 3; i++) { if (tck_divisor % 2 == 0) { tck_divisor = tck_divisor / 2; tck_dividend = tck_dividend / 2; } if (tck_divisor % 5 == 0) { tck_divisor = tck_divisor / 5; tck_dividend = tck_dividend / 5; } } if (kstat_ctl == NULL) { kstat_ctl = kstat_open(); kid = kstat_ctl->kc_chain_id; new_kstat = 1; } else { new_kid = kstat_chain_update(kstat_ctl); if (new_kid < 0) { res=kstat_close(kstat_ctl); kstat_ctl = kstat_open(); kid = kstat_ctl->kc_chain_id; new_kstat = 1; } else if (new_kid > 0 && kid != new_kid) { kid = new_kid; new_kstat = 1; } } if (new_kstat) { cpu_count = 0; for (kstat = kstat_ctl->kc_chain; kstat; kstat = kstat->ks_next) { if (strncmp(kstat->ks_name, "cpu_stat", 8) == 0) { kstat_cpu[cpu_count++]=kstat; } } } for (i = 0; i < cpu_count; i++) { new_kid = kstat_read(kstat_ctl, kstat_cpu[i], NULL); if (new_kid >= 0) { cpu = ((cpu_stat_t *)kstat_cpu[i]->ks_data)->cpu_sysinfo; if ( tck_divisor == 1 ) { pvals[7] += (jlong)(((jlong)cpu.cpu[CPU_IDLE]) * tck_dividend); pvals[7] += (jlong)(((jlong)cpu.cpu[CPU_WAIT]) * tck_dividend); pvals[8] += (jlong)(((jlong)cpu.cpu[CPU_KERNEL]) * tck_dividend); pvals[9] += (jlong)(((jlong)cpu.cpu[CPU_USER]) * tck_dividend); } else { pvals[7] += (jlong)(((jlong)cpu.cpu[CPU_IDLE]) * tck_dividend / tck_divisor); pvals[7] += (jlong)(((jlong)cpu.cpu[CPU_WAIT]) * tck_dividend / tck_divisor); pvals[8] += (jlong)(((jlong)cpu.cpu[CPU_KERNEL]) * tck_dividend / tck_divisor); pvals[9] += (jlong)(((jlong)cpu.cpu[CPU_USER]) * tck_dividend / tck_divisor); } } } } /* * The next two are not implemented yet for Solaris * inf[4] - Amount of shared memory * inf[5] - Memory used by buffers * */ } #elif defined(DARWIN) uint64_t mem_total; size_t len = sizeof(mem_total); vm_statistics_data_t vm_info; mach_msg_type_number_t info_count = HOST_VM_INFO_COUNT; sysctlbyname("hw.memsize", &mem_total, &len, NULL, 0); pvals[0] = (jlong)mem_total; host_statistics(mach_host_self (), HOST_VM_INFO, (host_info_t)&vm_info, &info_count); pvals[1] = (jlong)(((double)vm_info.free_count)*vm_page_size); pvals[6] = (jlong)(100 - (pvals[1] * 100 / mem_total)); rv = APR_SUCCESS; /* DARWIN */ #else rv = APR_ENOTIMPL; #endif (*e)->ReleaseLongArrayElements(e, inf, pvals, 0); return rv; }
void get_system_info(struct system_info * si) { register long total; register int i; unsigned int count = HOST_CPU_LOAD_INFO_COUNT; if (host_statistics(mach_host_self(), HOST_CPU_LOAD_INFO, (host_info_t) & cpuload, &count) == KERN_SUCCESS) { for (i = 0; i < CPU_STATE_MAX; i++) { cp_time[i] = cpuload.cpu_ticks[i]; } } #ifdef MAX_VERBOSE /* * print out the entries */ for (i = 0; i < CPU_STATE_MAX; i++) printf("cp_time[%d] = %d\n", i, cp_time[i]); fflush(stdout); #endif /* MAX_VERBOSE */ /* * get the load averages */ #ifdef MAX_VERBOSE printf("%-30s%03.2f, %03.2f, %03.2f\n", "load averages:", si->load_avg[0], si->load_avg[1], si->load_avg[2]); #endif /* MAX_VERBOSE */ total = percentages(CPU_STATE_MAX, cpu_states, cp_time, cp_old, cp_diff); /* * get the memory statistics */ { kern_return_t status; count = HOST_VM_INFO_COUNT; status = host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t) & vm_stats, &count); if (status != KERN_SUCCESS) { puke("error: vm_statistics() failed (%s)", strerror(errno)); return; } /* * we already have the total memory, we just need to get it in the * right format. */ pagesize = 1; /* temporary fix to div by 0 errors */ memory_stats[0] = pagetok(maxmem / pagesize); memory_stats[1] = pagetok(vm_stats.free_count); memory_stats[2] = pagetok(vm_stats.active_count); memory_stats[3] = pagetok(vm_stats.inactive_count); memory_stats[4] = pagetok(vm_stats.wire_count); if (swappgsin < 0) { memory_stats[5] = 1; memory_stats[6] = 1; } else { memory_stats[5] = pagetok(((vm_stats.pageins - swappgsin))); memory_stats[6] = pagetok(((vm_stats.pageouts - swappgsout))); } swappgsin = vm_stats.pageins; swappgsout = vm_stats.pageouts; } si->cpustates = cpu_states; si->memory = memory_stats; si->last_pid = -1; return; }
std::string mem_string() { std::ostringstream oss; #if defined(BSD_BASED) || (defined(__APPLE__) && defined(__MACH__)) // OSX or BSD based system, use BSD APIs instead #if defined(__APPLE__) && defined(__MACH__) // These values are in bytes int64_t total_mem; int64_t used_mem; int64_t unused_mem; vm_size_t page_size; mach_port_t mach_port; mach_msg_type_number_t count; vm_statistics_data_t vm_stats; // Get total physical memory int mib[2]; mib[0] = CTL_HW; mib[1] = HW_MEMSIZE; size_t length = sizeof(int64_t); sysctl(mib, 2, &total_mem, &length, NULL, 0); mach_port = mach_host_self(); count = sizeof(vm_stats) / sizeof(natural_t); if (KERN_SUCCESS == host_page_size(mach_port, &page_size) && KERN_SUCCESS == host_statistics(mach_port, HOST_VM_INFO, (host_info_t)&vm_stats, &count)) { unused_mem = (int64_t)vm_stats.free_count * (int64_t)page_size; used_mem = ((int64_t)vm_stats.active_count + (int64_t)vm_stats.inactive_count + (int64_t)vm_stats.wire_count) * (int64_t)page_size; } // To kilobytes #endif // Apple // TODO BSD used_mem /= 1024; total_mem /= 1024; #else // Linux unsigned int total_mem = 0; unsigned int used_mem = 0; unsigned int unused_mem = 0; size_t line_start_pos; size_t line_end_pos; std::istringstream iss; std::string mem_line; std::ifstream meminfo_file( "/proc/meminfo" ); while(meminfo_file.good()) { getline( meminfo_file, mem_line ); line_start_pos = mem_line.find_first_of( ':' ); const std::string which = mem_line.substr(0, line_start_pos); if(which != "MemTotal" && which != "MemFree" && which != "Buffers" && which != "Cached") { continue; } line_start_pos++; line_end_pos = mem_line.find_last_of( 'k' ); iss.str( mem_line.substr( line_start_pos, line_end_pos - line_start_pos ) ); if(which == "MemTotal") { iss >> total_mem; } else {
u_char * var_hrstore(struct variable *vp, oid * name, size_t * length, int exact, size_t * var_len, WriteMethod ** write_method) { int store_idx = 0; #if !defined(linux) #if defined(solaris2) int freemem; int swap_total, swap_used; #elif defined(hpux10) || defined(hpux11) struct pst_dynamic pst_buf; #elif defined(darwin8) vm_statistics_data_t vm_stat; int count = HOST_VM_INFO_COUNT; #elif defined(TOTAL_MEMORY_SYMBOL) || defined(USE_SYSCTL_VM) #ifdef VM_UVMEXP struct uvmexp uvmexp_totals; #endif struct vmtotal memory_totals; #endif #if HAVE_KVM_GETSWAPINFO struct kvm_swap swapinfo; static kvm_t *kd = NULL; #endif #if HAVE_SYS_POOL_H struct pool mbpool, mclpool; int i; #endif #ifdef MBSTAT_SYMBOL struct mbstat mbstat; #endif #endif /* !linux */ static char string[1024]; struct HRFS_statfs stat_buf; if (vp->magic == HRSTORE_MEMSIZE) { if (header_hrstore(vp, name, length, exact, var_len, write_method) == MATCH_FAILED) return NULL; } else { really_try_next: store_idx = header_hrstoreEntry(vp, name, length, exact, var_len, write_method); if (store_idx == MATCH_FAILED) return NULL; if (store_idx > HRS_TYPE_FIXED_MAX) { if (HRFS_statfs(HRFS_entry->HRFS_mount, &stat_buf) < 0) { snmp_log_perror(HRFS_entry->HRFS_mount); goto try_next; } } #if !defined(linux) && !defined(solaris2) else switch (store_idx) { case HRS_TYPE_MEM: case HRS_TYPE_SWAP: #ifdef USE_SYSCTL_VM { int mib[2]; size_t len = sizeof(memory_totals); mib[0] = CTL_VM; mib[1] = VM_METER; sysctl(mib, 2, &memory_totals, &len, NULL, 0); #ifdef VM_UVMEXP mib[1] = VM_UVMEXP; len = sizeof(uvmexp_totals); sysctl(mib, 2, &uvmexp_totals, &len, NULL, 0); #endif } #elif defined(darwin8) host_statistics(myHost,HOST_VM_INFO,&vm_stat,&count); #elif defined(hpux10) || defined(hpux11) pstat_getdynamic(&pst_buf, sizeof(struct pst_dynamic), 1, 0); #elif defined(TOTAL_MEMORY_SYMBOL) auto_nlist(TOTAL_MEMORY_SYMBOL, (char *) &memory_totals, sizeof(struct vmtotal)); #endif #if HAVE_KVM_GETSWAPINFO if (kd == NULL) kd = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, NULL); if (!kd) { snmp_log_perror("kvm_openfiles"); goto try_next; } if (kvm_getswapinfo(kd, &swapinfo, 1, 0) < 0) { snmp_log_perror("kvm_getswapinfo"); goto try_next; } #endif break; #if !defined(hpux10) && !defined(hpux11) case HRS_TYPE_MBUF: #if HAVE_SYS_POOL_H auto_nlist(MBPOOL_SYMBOL, (char *) &mbpool, sizeof(mbpool)); auto_nlist(MCLPOOL_SYMBOL, (char *) &mclpool, sizeof(mclpool)); #endif #ifdef MBSTAT_SYMBOL auto_nlist(MBSTAT_SYMBOL, (char *) &mbstat, sizeof(mbstat)); #endif break; #endif /* !hpux10 && !hpux11 */ default: break; } #endif /* !linux && !solaris2 */ } switch (vp->magic) { case HRSTORE_MEMSIZE: long_return = physmem * (pagesize / 1024); return (u_char *) & long_return; case HRSTORE_INDEX: long_return = store_idx; return (u_char *) & long_return; case HRSTORE_TYPE: if (store_idx > HRS_TYPE_FIXED_MAX) if (storageUseNFS && Check_HR_FileSys_NFS()) storage_type_id[storage_type_len - 1] = 10; /* Network Disk */ else storage_type_id[storage_type_len - 1] = 4; /* Assume fixed */ else switch (store_idx) { case HRS_TYPE_MEM: storage_type_id[storage_type_len - 1] = 2; /* RAM */ break; case HRS_TYPE_SWAP: storage_type_id[storage_type_len - 1] = 3; /* Virtual Mem */ break; case HRS_TYPE_MBUF: storage_type_id[storage_type_len - 1] = 1; /* Other */ break; default: storage_type_id[storage_type_len - 1] = 1; /* Other */ break; } *var_len = sizeof(storage_type_id); return (u_char *) storage_type_id; case HRSTORE_DESCR: if (store_idx > HRS_TYPE_FIXED_MAX) { strncpy(string, HRFS_entry->HRFS_mount, sizeof(string)-1); string[ sizeof(string)-1 ] = 0; *var_len = strlen(string); return (u_char *) string; } else { /* store_idx = store_idx - 1; */ *var_len = strlen(hrs_descr[store_idx]); return (u_char *) hrs_descr[store_idx]; } case HRSTORE_UNITS: if (store_idx > HRS_TYPE_FIXED_MAX) #if HRFS_HAS_FRSIZE long_return = stat_buf.f_frsize; #else long_return = stat_buf.f_bsize; #endif else switch (store_idx) { case HRS_TYPE_MEM: case HRS_TYPE_SWAP: #if defined(USE_SYSCTL) || defined(solaris2) long_return = pagesize; #elif defined(NBPG) long_return = NBPG; #else long_return = 1024; /* Report in Kb */ #endif break; case HRS_TYPE_MBUF: #ifdef MSIZE long_return = MSIZE; #elif defined(linux) long_return = 1024; #else long_return = 256; #endif break; default: #if NO_DUMMY_VALUES goto try_next; #endif long_return = 1024; /* As likely as any! */ break; } return (u_char *) & long_return; case HRSTORE_SIZE: if (store_idx > HRS_TYPE_FIXED_MAX) long_return = stat_buf.f_blocks; else switch (store_idx) { #if defined(linux) case HRS_TYPE_MEM: case HRS_TYPE_SWAP: long_return = linux_mem(store_idx, HRSTORE_SIZE); break; #elif defined(solaris2) case HRS_TYPE_MEM: long_return = physmem; break; case HRS_TYPE_SWAP: sol_get_swapinfo(&swap_total, &swap_used); long_return = swap_total; break; #elif defined(hpux10) || defined(hpux11) case HRS_TYPE_MEM: long_return = pst_buf.psd_rm; break; case HRS_TYPE_SWAP: long_return = pst_buf.psd_vm; break; #elif defined(darwin8) case HRS_TYPE_MEM: long_return = physmem; break; case HRS_TYPE_SWAP: long_return = -1; break; #if defined(MBSTAT_SYMBOL) case HRS_TYPE_MBUF: long_return = mbstat.m_mbufs; break; #endif #elif defined(TOTAL_MEMORY_SYMBOL) || defined(USE_SYSCTL_VM) case HRS_TYPE_MEM: long_return = memory_totals.t_rm; break; case HRS_TYPE_SWAP: #if HAVE_KVM_GETSWAPINFO long_return = swapinfo.ksw_total; #elif defined(VM_UVMEXP) long_return = uvmexp_totals.swpages; #else long_return = memory_totals.t_vm; #endif break; #else /* !linux && !solaris2 && !hpux10 && !hpux11 && ... */ case HRS_TYPE_MEM: long_return = physmem; break; case HRS_TYPE_SWAP: #if NO_DUMMY_VALUES goto try_next; #endif long_return = 0; break; #endif /* !linux && !solaris2 && !hpux10 && !hpux11 && ... */ case HRS_TYPE_MBUF: #ifdef linux long_return = linux_mem(store_idx, HRSTORE_SIZE); #elif HAVE_SYS_POOL_H long_return = 0; for (i = 0; i < sizeof(mbstat.m_mtypes) / sizeof(mbstat.m_mtypes[0]); i++) long_return += mbstat.m_mtypes[i]; #elif defined(MBSTAT_SYMBOL) && defined(STRUCT_MBSTAT_HAS_M_MBUFS) long_return = mbstat.m_mbufs; #elif defined(NO_DUMMY_VALUES) goto try_next; #else long_return = 0; #endif break; default: #if NO_DUMMY_VALUES goto try_next; #endif long_return = 1024; break; } return (u_char *) & long_return; case HRSTORE_USED: if (store_idx > HRS_TYPE_FIXED_MAX) long_return = (stat_buf.f_blocks - stat_buf.f_bfree); else switch (store_idx) { #if defined(linux) case HRS_TYPE_MBUF: case HRS_TYPE_MEM: case HRS_TYPE_SWAP: long_return = linux_mem(store_idx, HRSTORE_USED); break; #elif defined(solaris2) case HRS_TYPE_MEM: getKstatInt("unix", "system_pages", "freemem", &freemem); long_return = physmem - freemem; break; case HRS_TYPE_SWAP: sol_get_swapinfo(&swap_total, &swap_used); long_return = swap_used; break; #elif defined(hpux10) || defined(hpux11) case HRS_TYPE_MEM: long_return = pst_buf.psd_arm; break; case HRS_TYPE_SWAP: long_return = pst_buf.psd_avm; break; #elif defined(darwin8) case HRS_TYPE_MEM: long_return = vm_stat.active_count + vm_stat.inactive_count + vm_stat.wire_count; break; case HRS_TYPE_SWAP: long_return = -1; break; #if defined(MBSTAT_SYMBOL) case HRS_TYPE_MBUF: long_return = mbstat.m_mbufs; break; #endif #elif defined(TOTAL_MEMORY_SYMBOL) || defined(USE_SYSCTL_VM) case HRS_TYPE_MEM: long_return = memory_totals.t_arm; break; case HRS_TYPE_SWAP: #if HAVE_KVM_GETSWAPINFO long_return = swapinfo.ksw_used; #elif defined(VM_UVMEXP) long_return = uvmexp_totals.swpginuse; #else long_return = memory_totals.t_avm; #endif break; #endif /* linux || solaris2 || hpux10 || hpux11 || ... */ #if !defined(linux) && !defined(solaris2) && !defined(hpux10) && !defined(hpux11) case HRS_TYPE_MBUF: #if HAVE_SYS_POOL_H long_return = (mbpool.pr_nget - mbpool.pr_nput) * mbpool.pr_size + (mclpool.pr_nget - mclpool.pr_nput) * mclpool.pr_size; #ifdef MSIZE long_return /= MSIZE; #else long_return /= 256; #endif #elif defined(MBSTAT_SYMBOL) && defined(STRUCT_MBSTAT_HAS_M_CLUSTERS) long_return = mbstat.m_clusters - mbstat.m_clfree; /* unlikely, but... */ #elif defined(NO_DUMMY_VALUES) goto try_next; #else long_return = 0; #endif break; #endif /* !linux && !solaris2 && !hpux10 && !hpux11 && ... */ default: #if NO_DUMMY_VALUES goto try_next; #endif long_return = 1024; break; } return (u_char *) & long_return; case HRSTORE_FAILS: if (store_idx > HRS_TYPE_FIXED_MAX) #if NO_DUMMY_VALUES goto try_next; #else long_return = 0; #endif else switch (store_idx) {
static int parse_proc_stat(void) { int age; /* reread every 10 msec only */ age = hash_age(&Stat, NULL); if (age > 0 && age <= 10) return 0; #ifndef __MAC_OS_X_VERSION_10_3 /* Linux Kernel, /proc-filesystem */ if (stream == NULL) stream = fopen("/proc/stat", "r"); if (stream == NULL) { error("fopen(/proc/stat) failed: %s", strerror(errno)); return -1; } rewind(stream); while (!feof(stream)) { char buffer[1024]; if (fgets(buffer, sizeof(buffer), stream) == NULL) break; if (strncmp(buffer, "cpu", 3) == 0) { char *key[] = { "user", "nice", "system", "idle", "iow", "irq", "sirq" }; char delim[] = " \t\n"; char *cpu, *beg, *end; int i; cpu = buffer; /* skip "cpu" or "cpu0" block */ if ((end = strpbrk(buffer, delim)) != NULL) *end = '\0'; beg = end ? end + 1 : NULL; for (i = 0; i < 7 && beg != NULL; i++) { while (strchr(delim, *beg)) beg++; if ((end = strpbrk(beg, delim))) *end = '\0'; hash_put2(cpu, key[i], beg); beg = end ? end + 1 : NULL; } } else if (strncmp(buffer, "page ", 5) == 0) { char *key[] = { "in", "out" }; char delim[] = " \t\n"; char *beg, *end; int i; for (i = 0, beg = buffer + 5; i < 2 && beg != NULL; i++) { while (strchr(delim, *beg)) beg++; if ((end = strpbrk(beg, delim))) *end = '\0'; hash_put2("page", key[i], beg); beg = end ? end + 1 : NULL; } } else if (strncmp(buffer, "swap ", 5) == 0) { char *key[] = { "in", "out" }; char delim[] = " \t\n"; char *beg, *end; int i; for (i = 0, beg = buffer + 5; i < 2 && beg != NULL; i++) { while (strchr(delim, *beg)) beg++; if ((end = strpbrk(beg, delim))) *end = '\0'; hash_put2("swap", key[i], beg); beg = end ? end + 1 : NULL; } } else if (strncmp(buffer, "intr ", 5) == 0) { char delim[] = " \t\n"; char *beg, *end, num[4]; int i; for (i = 0, beg = buffer + 5; i < 17 && beg != NULL; i++) { while (strchr(delim, *beg)) beg++; if ((end = strpbrk(beg, delim))) *end = '\0'; if (i == 0) strcpy(num, "sum"); else qprintf(num, sizeof(num), "%d", i - 1); hash_put2("intr", num, beg); beg = end ? end + 1 : NULL; } } else if (strncmp(buffer, "disk_io:", 8) == 0) { char *key[] = { "io", "rio", "rblk", "wio", "wblk" }; char delim[] = " ():,\t\n"; char *dev, *beg, *end, *p; int i; dev = buffer + 8; while (dev != NULL) { while (strchr(delim, *dev)) dev++; if ((end = strchr(dev, ')'))) *end = '\0'; while ((p = strchr(dev, ',')) != NULL) *p = ':'; beg = end ? end + 1 : NULL; for (i = 0; i < 5 && beg != NULL; i++) { while (strchr(delim, *beg)) beg++; if ((end = strpbrk(beg, delim))) *end = '\0'; hash_put3("disk_io", dev, key[i], beg); beg = end ? end + 1 : NULL; } dev = beg; } } else { char delim[] = " \t\n"; char *beg, *end; beg = buffer; if ((end = strpbrk(beg, delim))) *end = '\0'; beg = end ? end + 1 : NULL; if ((end = strpbrk(beg, delim))) *end = '\0'; while (strchr(delim, *beg)) beg++; hash_put1(buffer, beg); } } #else /* MACH Kernel, MacOS X */ kern_return_t err; mach_msg_type_number_t count; host_info_t r_load; host_cpu_load_info_data_t cpu_load; char s_val[8]; r_load = &cpu_load; count = HOST_CPU_LOAD_INFO_COUNT; err = host_statistics(mach_host_self(), HOST_CPU_LOAD_INFO, r_load, &count); if (KERN_SUCCESS != err) { error("Error getting cpu load"); return -1; } snprintf(s_val, sizeof(s_val), "%d", cpu_load.cpu_ticks[CPU_STATE_USER]); hash_put2("cpu", "user", s_val); snprintf(s_val, sizeof(s_val), "%d", cpu_load.cpu_ticks[CPU_STATE_NICE]); hash_put2("cpu", "nice", s_val); snprintf(s_val, sizeof(s_val), "%d", cpu_load.cpu_ticks[CPU_STATE_SYSTEM]); hash_put2("cpu", "system", s_val); snprintf(s_val, sizeof(s_val), "%d", cpu_load.cpu_ticks[CPU_STATE_IDLE]); hash_put2("cpu", "idle", s_val); #endif return 0; }
std::string MachTask::GetProfileData (DNBProfileDataScanType scanType) { std::string result; static int32_t numCPU = -1; struct host_cpu_load_info host_info; if (scanType & eProfileHostCPU) { int32_t mib[] = {CTL_HW, HW_AVAILCPU}; size_t len = sizeof(numCPU); if (numCPU == -1) { if (sysctl(mib, sizeof(mib) / sizeof(int32_t), &numCPU, &len, NULL, 0) != 0) return result; } mach_port_t localHost = mach_host_self(); mach_msg_type_number_t count = HOST_CPU_LOAD_INFO_COUNT; kern_return_t kr = host_statistics(localHost, HOST_CPU_LOAD_INFO, (host_info_t)&host_info, &count); if (kr != KERN_SUCCESS) return result; } task_t task = TaskPort(); if (task == TASK_NULL) return result; struct task_basic_info task_info; DNBError err; err = BasicInfo(task, &task_info); if (!err.Success()) return result; uint64_t elapsed_usec = 0; uint64_t task_used_usec = 0; if (scanType & eProfileCPU) { // Get current used time. struct timeval current_used_time; struct timeval tv; TIME_VALUE_TO_TIMEVAL(&task_info.user_time, ¤t_used_time); TIME_VALUE_TO_TIMEVAL(&task_info.system_time, &tv); timeradd(¤t_used_time, &tv, ¤t_used_time); task_used_usec = current_used_time.tv_sec * 1000000ULL + current_used_time.tv_usec; struct timeval current_elapsed_time; int res = gettimeofday(¤t_elapsed_time, NULL); if (res == 0) { elapsed_usec = current_elapsed_time.tv_sec * 1000000ULL + current_elapsed_time.tv_usec; } } std::vector<uint64_t> threads_id; std::vector<std::string> threads_name; std::vector<uint64_t> threads_used_usec; if (scanType & eProfileThreadsCPU) { get_threads_profile_data(scanType, task, m_process->ProcessID(), threads_id, threads_name, threads_used_usec); } struct vm_statistics vm_stats; uint64_t physical_memory; mach_vm_size_t rprvt = 0; mach_vm_size_t rsize = 0; mach_vm_size_t vprvt = 0; mach_vm_size_t vsize = 0; mach_vm_size_t dirty_size = 0; mach_vm_size_t purgeable = 0; mach_vm_size_t anonymous = 0; if (m_vm_memory.GetMemoryProfile(scanType, task, task_info, m_process->GetCPUType(), m_process->ProcessID(), vm_stats, physical_memory, rprvt, rsize, vprvt, vsize, dirty_size, purgeable, anonymous)) { std::ostringstream profile_data_stream; if (scanType & eProfileHostCPU) { profile_data_stream << "num_cpu:" << numCPU << ';'; profile_data_stream << "host_user_ticks:" << host_info.cpu_ticks[CPU_STATE_USER] << ';'; profile_data_stream << "host_sys_ticks:" << host_info.cpu_ticks[CPU_STATE_SYSTEM] << ';'; profile_data_stream << "host_idle_ticks:" << host_info.cpu_ticks[CPU_STATE_IDLE] << ';'; } if (scanType & eProfileCPU) { profile_data_stream << "elapsed_usec:" << elapsed_usec << ';'; profile_data_stream << "task_used_usec:" << task_used_usec << ';'; } if (scanType & eProfileThreadsCPU) { int num_threads = threads_id.size(); for (int i=0; i<num_threads; i++) { profile_data_stream << "thread_used_id:" << std::hex << threads_id[i] << std::dec << ';'; profile_data_stream << "thread_used_usec:" << threads_used_usec[i] << ';'; if (scanType & eProfileThreadName) { profile_data_stream << "thread_used_name:"; int len = threads_name[i].size(); if (len) { const char *thread_name = threads_name[i].c_str(); // Make sure that thread name doesn't interfere with our delimiter. profile_data_stream << RAW_HEXBASE << std::setw(2); const uint8_t *ubuf8 = (const uint8_t *)(thread_name); for (int j=0; j<len; j++) { profile_data_stream << (uint32_t)(ubuf8[j]); } // Reset back to DECIMAL. profile_data_stream << DECIMAL; } profile_data_stream << ';'; } } } if (scanType & eProfileHostMemory) profile_data_stream << "total:" << physical_memory << ';'; if (scanType & eProfileMemory) { static vm_size_t pagesize; static bool calculated = false; if (!calculated) { calculated = true; pagesize = PageSize(); } profile_data_stream << "wired:" << vm_stats.wire_count * pagesize << ';'; profile_data_stream << "active:" << vm_stats.active_count * pagesize << ';'; profile_data_stream << "inactive:" << vm_stats.inactive_count * pagesize << ';'; uint64_t total_used_count = vm_stats.wire_count + vm_stats.inactive_count + vm_stats.active_count; profile_data_stream << "used:" << total_used_count * pagesize << ';'; profile_data_stream << "free:" << vm_stats.free_count * pagesize << ';'; profile_data_stream << "rprvt:" << rprvt << ';'; profile_data_stream << "rsize:" << rsize << ';'; profile_data_stream << "vprvt:" << vprvt << ';'; profile_data_stream << "vsize:" << vsize << ';'; if (scanType & eProfileMemoryDirtyPage) profile_data_stream << "dirty:" << dirty_size << ';'; if (scanType & eProfileMemoryAnonymous) { profile_data_stream << "purgeable:" << purgeable << ';'; profile_data_stream << "anonymous:" << anonymous << ';'; } } profile_data_stream << "--end--;"; result = profile_data_stream.str(); } return result; }
/** * @file * @brief * Free Ram * * @details * This function looks up the available ram in bytes. * * @param totalram * Output, passed by reference. On successful return, the value * is set to the free ram (in bytes) available on the system. * * @note * TODO explain "free" * * @return * The return value indicates the status of the function. */ int meminfo_freeram(memsize_t *freeram) { int ret = MEMINFO_OK; *freeram = 0L; #if OS_LINUX struct sysinfo info; int test = sysinfo(&info); chkret(test, FAILURE); *freeram = (memsize_t) info.freeram * info.mem_unit; #elif OS_MAC vm_size_t page_size; mach_port_t mach_port; mach_msg_type_number_t count; vm_statistics_data_t vm_stats; mach_port = mach_host_self(); count = sizeof(vm_stats) / sizeof(natural_t); int test = host_page_size(mach_port, &page_size); if (test != KERN_SUCCESS) return FAILURE; test = host_statistics(mach_port, HOST_VM_INFO, (host_info_t)&vm_stats, &count); if (test != KERN_SUCCESS) return FAILURE; *freeram = (memsize_t) vm_stats.free_count * (memsize_t) page_size; #elif OS_WINDOWS MEMORYSTATUSEX status; status.dwLength = sizeof(status); int test = GlobalMemoryStatusEx(&status); winchkret(test, FAILURE); *freeram = (memsize_t) status.ullAvailPhys; #elif OS_FREEBSD int page = sysconf(_SC_PAGESIZE); if (page == -1) return FAILURE; int test = sysctl_val("vm.stats.vm.v_free_count", freeram); chkret(test, FAILURE); *freeram *= (memsize_t) page; #elif OS_NIX memsize_t pagesize, freepages; pagesize = (memsize_t) sysconf(_SC_PAGESIZE); if (pagesize == FAILURE) return FAILURE; freepages = (memsize_t) sysconf(_SC_AVPHYS_PAGES); if (freepages == FAILURE) return FAILURE; *freeram = pagesize * freepages; #else ret = PLATFORM_ERROR; #endif return ret; }
/* * This function is called very early on in the Mach startup, from the * function start_kernel_threads() in osfmk/kern/startup.c. It's called * in the context of the current (startup) task using a call to the * function kernel_thread_create() to jump into start_kernel_threads(). * Internally, kernel_thread_create() calls thread_create_internal(), * which calls uthread_alloc(). The function of uthread_alloc() is * normally to allocate a uthread structure, and fill out the uu_sigmask, * uu_context fields. It skips filling these out in the case of the "task" * being "kernel_task", because the order of operation is inverted. To * account for that, we need to manually fill in at least the contents * of the uu_context.vc_ucred field so that the uthread structure can be * used like any other. */ void bsd_init(void) { struct uthread *ut; unsigned int i; #if __i386__ || __x86_64__ int error; #endif struct vfs_context context; kern_return_t ret; struct ucred temp_cred; #define bsd_init_kprintf(x...) /* kprintf("bsd_init: " x) */ kernel_flock = funnel_alloc(KERNEL_FUNNEL); if (kernel_flock == (funnel_t *)0 ) { panic("bsd_init: Failed to allocate kernel funnel"); } printf(copyright); bsd_init_kprintf("calling kmeminit\n"); kmeminit(); bsd_init_kprintf("calling parse_bsd_args\n"); parse_bsd_args(); /* Initialize kauth subsystem before instancing the first credential */ bsd_init_kprintf("calling kauth_init\n"); kauth_init(); /* Initialize process and pgrp structures. */ bsd_init_kprintf("calling procinit\n"); procinit(); /* Initialize the ttys (MUST be before kminit()/bsd_autoconf()!)*/ tty_init(); kernproc = &proc0; /* implicitly bzero'ed */ /* kernel_task->proc = kernproc; */ set_bsdtask_info(kernel_task,(void *)kernproc); /* give kernproc a name */ bsd_init_kprintf("calling process_name\n"); process_name("kernel_task", kernproc); /* allocate proc lock group attribute and group */ bsd_init_kprintf("calling lck_grp_attr_alloc_init\n"); proc_lck_grp_attr= lck_grp_attr_alloc_init(); proc_lck_grp = lck_grp_alloc_init("proc", proc_lck_grp_attr); #ifndef CONFIG_EMBEDDED proc_slock_grp = lck_grp_alloc_init("proc-slock", proc_lck_grp_attr); proc_fdmlock_grp = lck_grp_alloc_init("proc-fdmlock", proc_lck_grp_attr); proc_mlock_grp = lck_grp_alloc_init("proc-mlock", proc_lck_grp_attr); #endif /* Allocate proc lock attribute */ proc_lck_attr = lck_attr_alloc_init(); #if 0 #if __PROC_INTERNAL_DEBUG lck_attr_setdebug(proc_lck_attr); #endif #endif #ifdef CONFIG_EMBEDDED proc_list_mlock = lck_mtx_alloc_init(proc_lck_grp, proc_lck_attr); proc_klist_mlock = lck_mtx_alloc_init(proc_lck_grp, proc_lck_attr); lck_mtx_init(&kernproc->p_mlock, proc_lck_grp, proc_lck_attr); lck_mtx_init(&kernproc->p_fdmlock, proc_lck_grp, proc_lck_attr); lck_spin_init(&kernproc->p_slock, proc_lck_grp, proc_lck_attr); #else proc_list_mlock = lck_mtx_alloc_init(proc_mlock_grp, proc_lck_attr); proc_klist_mlock = lck_mtx_alloc_init(proc_mlock_grp, proc_lck_attr); lck_mtx_init(&kernproc->p_mlock, proc_mlock_grp, proc_lck_attr); lck_mtx_init(&kernproc->p_fdmlock, proc_fdmlock_grp, proc_lck_attr); lck_spin_init(&kernproc->p_slock, proc_slock_grp, proc_lck_attr); #endif execargs_cache_lock = lck_mtx_alloc_init(proc_lck_grp, proc_lck_attr); execargs_cache_size = bsd_simul_execs; execargs_free_count = bsd_simul_execs; execargs_cache = (vm_offset_t *)kalloc(bsd_simul_execs * sizeof(vm_offset_t)); bzero(execargs_cache, bsd_simul_execs * sizeof(vm_offset_t)); if (current_task() != kernel_task) printf("bsd_init: We have a problem, " "current task is not kernel task\n"); bsd_init_kprintf("calling get_bsdthread_info\n"); ut = (uthread_t)get_bsdthread_info(current_thread()); #if CONFIG_MACF /* * Initialize the MAC Framework */ mac_policy_initbsd(); kernproc->p_mac_enforce = 0; #endif /* MAC */ /* * Create process 0. */ proc_list_lock(); LIST_INSERT_HEAD(&allproc, kernproc, p_list); kernproc->p_pgrp = &pgrp0; LIST_INSERT_HEAD(PGRPHASH(0), &pgrp0, pg_hash); LIST_INIT(&pgrp0.pg_members); #ifdef CONFIG_EMBEDDED lck_mtx_init(&pgrp0.pg_mlock, proc_lck_grp, proc_lck_attr); #else lck_mtx_init(&pgrp0.pg_mlock, proc_mlock_grp, proc_lck_attr); #endif /* There is no other bsd thread this point and is safe without pgrp lock */ LIST_INSERT_HEAD(&pgrp0.pg_members, kernproc, p_pglist); kernproc->p_listflag |= P_LIST_INPGRP; kernproc->p_pgrpid = 0; pgrp0.pg_session = &session0; pgrp0.pg_membercnt = 1; session0.s_count = 1; session0.s_leader = kernproc; session0.s_listflags = 0; #ifdef CONFIG_EMBEDDED lck_mtx_init(&session0.s_mlock, proc_lck_grp, proc_lck_attr); #else lck_mtx_init(&session0.s_mlock, proc_mlock_grp, proc_lck_attr); #endif LIST_INSERT_HEAD(SESSHASH(0), &session0, s_hash); proc_list_unlock(); #if CONFIG_LCTX kernproc->p_lctx = NULL; #endif kernproc->task = kernel_task; kernproc->p_stat = SRUN; kernproc->p_flag = P_SYSTEM; kernproc->p_nice = NZERO; kernproc->p_pptr = kernproc; TAILQ_INIT(&kernproc->p_uthlist); TAILQ_INSERT_TAIL(&kernproc->p_uthlist, ut, uu_list); kernproc->sigwait = FALSE; kernproc->sigwait_thread = THREAD_NULL; kernproc->exit_thread = THREAD_NULL; kernproc->p_csflags = CS_VALID; /* * Create credential. This also Initializes the audit information. */ bsd_init_kprintf("calling bzero\n"); bzero(&temp_cred, sizeof(temp_cred)); temp_cred.cr_ngroups = 1; temp_cred.cr_audit.as_aia_p = &audit_default_aia; /* XXX the following will go away with cr_au */ temp_cred.cr_au.ai_auid = AU_DEFAUDITID; bsd_init_kprintf("calling kauth_cred_create\n"); kernproc->p_ucred = kauth_cred_create(&temp_cred); /* give the (already exisiting) initial thread a reference on it */ bsd_init_kprintf("calling kauth_cred_ref\n"); kauth_cred_ref(kernproc->p_ucred); ut->uu_context.vc_ucred = kernproc->p_ucred; ut->uu_context.vc_thread = current_thread(); TAILQ_INIT(&kernproc->p_aio_activeq); TAILQ_INIT(&kernproc->p_aio_doneq); kernproc->p_aio_total_count = 0; kernproc->p_aio_active_count = 0; bsd_init_kprintf("calling file_lock_init\n"); file_lock_init(); #if CONFIG_MACF mac_cred_label_associate_kernel(kernproc->p_ucred); mac_task_label_update_cred (kernproc->p_ucred, (struct task *) kernproc->task); #endif /* Create the file descriptor table. */ filedesc0.fd_refcnt = 1+1; /* +1 so shutdown will not _FREE_ZONE */ kernproc->p_fd = &filedesc0; filedesc0.fd_cmask = cmask; filedesc0.fd_knlistsize = -1; filedesc0.fd_knlist = NULL; filedesc0.fd_knhash = NULL; filedesc0.fd_knhashmask = 0; /* Create the limits structures. */ kernproc->p_limit = &limit0; for (i = 0; i < sizeof(kernproc->p_rlimit)/sizeof(kernproc->p_rlimit[0]); i++) limit0.pl_rlimit[i].rlim_cur = limit0.pl_rlimit[i].rlim_max = RLIM_INFINITY; limit0.pl_rlimit[RLIMIT_NOFILE].rlim_cur = NOFILE; limit0.pl_rlimit[RLIMIT_NPROC].rlim_cur = maxprocperuid; limit0.pl_rlimit[RLIMIT_NPROC].rlim_max = maxproc; limit0.pl_rlimit[RLIMIT_STACK] = vm_initial_limit_stack; limit0.pl_rlimit[RLIMIT_DATA] = vm_initial_limit_data; limit0.pl_rlimit[RLIMIT_CORE] = vm_initial_limit_core; limit0.pl_refcnt = 1; kernproc->p_stats = &pstats0; kernproc->p_sigacts = &sigacts0; /* * Charge root for two processes: init and mach_init. */ bsd_init_kprintf("calling chgproccnt\n"); (void)chgproccnt(0, 1); /* * Allocate a kernel submap for pageable memory * for temporary copying (execve()). */ { vm_offset_t minimum; bsd_init_kprintf("calling kmem_suballoc\n"); ret = kmem_suballoc(kernel_map, &minimum, (vm_size_t)bsd_pageable_map_size, TRUE, VM_FLAGS_ANYWHERE, &bsd_pageable_map); if (ret != KERN_SUCCESS) panic("bsd_init: Failed to allocate bsd pageable map"); } /* * Initialize buffers and hash links for buffers * * SIDE EFFECT: Starts a thread for bcleanbuf_thread(), so must * happen after a credential has been associated with * the kernel task. */ bsd_init_kprintf("calling bsd_bufferinit\n"); bsd_bufferinit(); /* Initialize the execve() semaphore */ bsd_init_kprintf("calling semaphore_create\n"); if (ret != KERN_SUCCESS) panic("bsd_init: Failed to create execve semaphore"); /* * Initialize the calendar. */ bsd_init_kprintf("calling IOKitInitializeTime\n"); IOKitInitializeTime(); if (turn_on_log_leaks && !new_nkdbufs) new_nkdbufs = 200000; start_kern_tracing(new_nkdbufs); if (turn_on_log_leaks) log_leaks = 1; bsd_init_kprintf("calling ubc_init\n"); ubc_init(); /* Initialize the file systems. */ bsd_init_kprintf("calling vfsinit\n"); vfsinit(); #if SOCKETS /* Initialize per-CPU cache allocator */ mcache_init(); /* Initialize mbuf's. */ bsd_init_kprintf("calling mbinit\n"); mbinit(); net_str_id_init(); /* for mbuf tags */ #endif /* SOCKETS */ /* * Initializes security event auditing. * XXX: Should/could this occur later? */ #if CONFIG_AUDIT bsd_init_kprintf("calling audit_init\n"); audit_init(); #endif /* Initialize kqueues */ bsd_init_kprintf("calling knote_init\n"); knote_init(); /* Initialize for async IO */ bsd_init_kprintf("calling aio_init\n"); aio_init(); /* Initialize pipes */ bsd_init_kprintf("calling pipeinit\n"); pipeinit(); /* Initialize SysV shm subsystem locks; the subsystem proper is * initialized through a sysctl. */ #if SYSV_SHM bsd_init_kprintf("calling sysv_shm_lock_init\n"); sysv_shm_lock_init(); #endif #if SYSV_SEM bsd_init_kprintf("calling sysv_sem_lock_init\n"); sysv_sem_lock_init(); #endif #if SYSV_MSG bsd_init_kprintf("sysv_msg_lock_init\n"); sysv_msg_lock_init(); #endif bsd_init_kprintf("calling pshm_lock_init\n"); pshm_lock_init(); bsd_init_kprintf("calling psem_lock_init\n"); psem_lock_init(); pthread_init(); /* POSIX Shm and Sem */ bsd_init_kprintf("calling pshm_cache_init\n"); pshm_cache_init(); bsd_init_kprintf("calling psem_cache_init\n"); psem_cache_init(); bsd_init_kprintf("calling time_zone_slock_init\n"); time_zone_slock_init(); /* Stack snapshot facility lock */ stackshot_lock_init(); /* * Initialize protocols. Block reception of incoming packets * until everything is ready. */ bsd_init_kprintf("calling sysctl_register_fixed\n"); sysctl_register_fixed(); bsd_init_kprintf("calling sysctl_mib_init\n"); sysctl_mib_init(); #if NETWORKING bsd_init_kprintf("calling dlil_init\n"); dlil_init(); bsd_init_kprintf("calling proto_kpi_init\n"); proto_kpi_init(); #endif /* NETWORKING */ #if SOCKETS bsd_init_kprintf("calling socketinit\n"); socketinit(); bsd_init_kprintf("calling domaininit\n"); domaininit(); #endif /* SOCKETS */ kernproc->p_fd->fd_cdir = NULL; kernproc->p_fd->fd_rdir = NULL; #if CONFIG_EMBEDDED /* Initialize kernel memory status notifications */ bsd_init_kprintf("calling kern_memorystatus_init\n"); kern_memorystatus_init(); #endif #ifdef GPROF /* Initialize kernel profiling. */ kmstartup(); #endif /* kick off timeout driven events by calling first time */ thread_wakeup(&lbolt); timeout(lightning_bolt, 0, hz); bsd_init_kprintf("calling bsd_autoconf\n"); bsd_autoconf(); #if CONFIG_DTRACE dtrace_postinit(); #endif /* * We attach the loopback interface *way* down here to ensure * it happens after autoconf(), otherwise it becomes the * "primary" interface. */ #include <loop.h> #if NLOOP > 0 bsd_init_kprintf("calling loopattach\n"); loopattach(); /* XXX */ #endif #if PFLOG /* Initialize packet filter log interface */ pfloginit(); #endif /* PFLOG */ #if NETHER > 0 /* Register the built-in dlil ethernet interface family */ bsd_init_kprintf("calling ether_family_init\n"); ether_family_init(); #endif /* ETHER */ #if NETWORKING /* Call any kext code that wants to run just after network init */ bsd_init_kprintf("calling net_init_run\n"); net_init_run(); /* register user tunnel kernel control handler */ utun_register_control(); #endif /* NETWORKING */ bsd_init_kprintf("calling vnode_pager_bootstrap\n"); vnode_pager_bootstrap(); #if 0 /* XXX Hack for early debug stop */ printf("\nabout to sleep for 10 seconds\n"); IOSleep( 10 * 1000 ); /* Debugger("hello"); */ #endif bsd_init_kprintf("calling inittodr\n"); inittodr(0); #if CONFIG_EMBEDDED { /* print out early VM statistics */ kern_return_t kr1; vm_statistics_data_t stat; mach_msg_type_number_t count; count = HOST_VM_INFO_COUNT; kr1 = host_statistics(host_self(), HOST_VM_INFO, (host_info_t)&stat, &count); kprintf("Mach Virtual Memory Statistics (page size of 4096) bytes\n" "Pages free:\t\t\t%u.\n" "Pages active:\t\t\t%u.\n" "Pages inactive:\t\t\t%u.\n" "Pages wired down:\t\t%u.\n" "\"Translation faults\":\t\t%u.\n" "Pages copy-on-write:\t\t%u.\n" "Pages zero filled:\t\t%u.\n" "Pages reactivated:\t\t%u.\n" "Pageins:\t\t\t%u.\n" "Pageouts:\t\t\t%u.\n" "Object cache: %u hits of %u lookups (%d%% hit rate)\n", stat.free_count, stat.active_count, stat.inactive_count, stat.wire_count, stat.faults, stat.cow_faults, stat.zero_fill_count, stat.reactivations, stat.pageins, stat.pageouts, stat.hits, stat.lookups, (stat.hits == 0) ? 100 : ((stat.lookups * 100) / stat.hits)); } #endif /* CONFIG_EMBEDDED */ /* Mount the root file system. */ while( TRUE) { int err; bsd_init_kprintf("calling setconf\n"); setconf(); bsd_init_kprintf("vfs_mountroot\n"); if (0 == (err = vfs_mountroot())) break; rootdevice[0] = '\0'; #if NFSCLIENT if (mountroot == netboot_mountroot) { PE_display_icon( 0, "noroot"); /* XXX a netboot-specific icon would be nicer */ vc_progress_set(FALSE, 0); for (i=1; 1; i*=2) { printf("bsd_init: failed to mount network root, error %d, %s\n", err, PE_boot_args()); printf("We are hanging here...\n"); IOSleep(i*60*1000); } /*NOTREACHED*/ } #endif printf("cannot mount root, errno = %d\n", err); boothowto |= RB_ASKNAME; } IOSecureBSDRoot(rootdevice); context.vc_thread = current_thread(); context.vc_ucred = kernproc->p_ucred; mountlist.tqh_first->mnt_flag |= MNT_ROOTFS; bsd_init_kprintf("calling VFS_ROOT\n"); /* Get the vnode for '/'. Set fdp->fd_fd.fd_cdir to reference it. */ if (VFS_ROOT(mountlist.tqh_first, &rootvnode, &context)) panic("bsd_init: cannot find root vnode: %s", PE_boot_args()); rootvnode->v_flag |= VROOT; (void)vnode_ref(rootvnode); (void)vnode_put(rootvnode); filedesc0.fd_cdir = rootvnode; #if NFSCLIENT if (mountroot == netboot_mountroot) { int err; /* post mount setup */ if ((err = netboot_setup()) != 0) { PE_display_icon( 0, "noroot"); /* XXX a netboot-specific icon would be nicer */ vc_progress_set(FALSE, 0); for (i=1; 1; i*=2) { printf("bsd_init: NetBoot could not find root, error %d: %s\n", err, PE_boot_args()); printf("We are hanging here...\n"); IOSleep(i*60*1000); } /*NOTREACHED*/ } } #endif #if CONFIG_IMAGEBOOT /* * See if a system disk image is present. If so, mount it and * switch the root vnode to point to it */ if(imageboot_needed()) { int err; /* An image was found */ if((err = imageboot_setup())) { /* * this is not fatal. Keep trying to root * off the original media */ printf("%s: imageboot could not find root, %d\n", __FUNCTION__, err); } } #endif /* CONFIG_IMAGEBOOT */ /* set initial time; all other resource data is already zero'ed */ microtime(&kernproc->p_start); kernproc->p_stats->p_start = kernproc->p_start; /* for compat */ #if DEVFS { char mounthere[] = "/dev"; /* !const because of internal casting */ bsd_init_kprintf("calling devfs_kernel_mount\n"); devfs_kernel_mount(mounthere); } #endif /* DEVFS */ /* Initialize signal state for process 0. */ bsd_init_kprintf("calling siginit\n"); siginit(kernproc); bsd_init_kprintf("calling bsd_utaskbootstrap\n"); bsd_utaskbootstrap(); #if defined(__LP64__) kernproc->p_flag |= P_LP64; printf("Kernel is LP64\n"); #endif #if __i386__ || __x86_64__ /* this should be done after the root filesystem is mounted */ error = set_archhandler(kernproc, CPU_TYPE_POWERPC); // 10/30/08 - gab: <rdar://problem/6324501> // if default 'translate' can't be found, see if the understudy is available if (ENOENT == error) { strlcpy(exec_archhandler_ppc.path, kRosettaStandIn_str, MAXPATHLEN); error = set_archhandler(kernproc, CPU_TYPE_POWERPC); } if (error) /* XXX make more generic */ exec_archhandler_ppc.path[0] = 0; #endif bsd_init_kprintf("calling mountroot_post_hook\n"); /* invoke post-root-mount hook */ if (mountroot_post_hook != NULL) mountroot_post_hook(); #if 0 /* not yet */ consider_zone_gc(FALSE); #endif bsd_init_kprintf("done\n"); }
static sg_error sg_get_page_stats_int(sg_page_stats *page_stats_buf){ #ifdef SOLARIS kstat_ctl_t *kc; kstat_t *ksp; cpu_stat_t cs; #elif defined(LINUX) || defined(CYGWIN) FILE *f; #define LINE_BUF_SIZE 256 char line_buf[LINE_BUF_SIZE]; #elif defined(HAVE_HOST_STATISTICS) || defined(HAVE_HOST_STATISTICS64) # if defined(HAVE_HOST_STATISTICS64) struct vm_statistics64 vm_stats; # else struct vm_statistics vm_stats; # endif mach_msg_type_number_t count; kern_return_t rc; #elif defined(HAVE_STRUCT_UVMEXP_SYSCTL) && defined(VM_UVMEXP2) int mib[2]; struct uvmexp_sysctl uvm; size_t size = sizeof(uvm); #elif defined(HAVE_STRUCT_UVMEXP) && defined(VM_UVMEXP) int mib[2]; struct uvmexp uvm; size_t size = sizeof(uvm); #elif defined(FREEBSD) || defined(DFBSD) size_t size; #elif defined(NETBSD) || defined(OPENBSD) int mib[2]; struct uvmexp uvm; size_t size = sizeof(uvm); #elif defined(AIX) perfstat_memory_total_t mem; #elif defined(HPUX) struct pst_vminfo vminfo; #endif page_stats_buf->systime = time(NULL); page_stats_buf->pages_pagein=0; page_stats_buf->pages_pageout=0; #ifdef SOLARIS if ((kc = kstat_open()) == NULL) { RETURN_WITH_SET_ERROR("page", SG_ERROR_KSTAT_OPEN, NULL); } for (ksp = kc->kc_chain; ksp!=NULL; ksp = ksp->ks_next) { if ((strcmp(ksp->ks_module, "cpu_stat")) != 0) continue; if (kstat_read(kc, ksp, &cs) == -1) continue; page_stats_buf->pages_pagein += (long long)cs.cpu_vminfo.pgpgin; page_stats_buf->pages_pageout += (long long)cs.cpu_vminfo.pgpgout; } kstat_close(kc); #elif defined(LINUX) || defined(CYGWIN) if ((f = fopen("/proc/vmstat", "r")) != NULL) { unsigned matches = 0; while( (matches < 2) && (fgets(line_buf, sizeof(line_buf), f) != NULL) ) { unsigned long long value; if (sscanf(line_buf, "%*s %llu", &value) != 1) continue; if (strncmp(line_buf, "pgpgin ", 7) == 0) { page_stats_buf->pages_pagein = value; ++matches; } else if (strncmp(line_buf, "pgpgout ", 8) == 0) { page_stats_buf->pages_pageout = value; ++matches; } } fclose(f); if( matches < 2 ) { RETURN_WITH_SET_ERROR( "page", SG_ERROR_PARSE, "/proc/vmstat" ); } } else if ((f = fopen("/proc/stat", "r")) != NULL) { if (sg_f_read_line(f, line_buf, sizeof(line_buf), "page") == NULL) { fclose(f); RETURN_FROM_PREVIOUS_ERROR( "page", sg_get_error() ); } fclose(f); if( sscanf( line_buf, "page %llu %llu", &page_stats_buf->pages_pagein, &page_stats_buf->pages_pageout ) != 2 ) { RETURN_WITH_SET_ERROR("page", SG_ERROR_PARSE, "page"); } } else { RETURN_WITH_SET_ERROR_WITH_ERRNO("page", SG_ERROR_OPEN, "/proc/stat"); } #elif defined(HAVE_HOST_STATISTICS) || defined(HAVE_HOST_STATISTICS64) self_host_port = mach_host_self(); # if defined(HAVE_HOST_STATISTICS64) count = HOST_VM_INFO64_COUNT; rc = host_statistics64(self_host_port, HOST_VM_INFO64, (host_info64_t)(&vm_stats), &count); # else count = HOST_VM_INFO_COUNT; rc = host_statistics(self_host_port, HOST_VM_INFO, (host_info_t)(&vm_stats), &count); # endif if( rc != KERN_SUCCESS ) { RETURN_WITH_SET_ERROR_WITH_ERRNO_CODE( "mem", SG_ERROR_MACHCALL, rc, "host_statistics" ); } page_stats_buf->pages_pagein = vm_stats.pageins; page_stats_buf->pages_pageout = vm_stats.pageouts; #elif defined(HAVE_STRUCT_UVMEXP_SYSCTL) && defined(VM_UVMEXP2) mib[0] = CTL_VM; mib[1] = VM_UVMEXP2; if (sysctl(mib, 2, &uvm, &size, NULL, 0) < 0) { RETURN_WITH_SET_ERROR_WITH_ERRNO("mem", SG_ERROR_SYSCTL, "CTL_VM.VM_UVMEXP2"); } page_stats_buf->pages_pagein = uvm.pgswapin; page_stats_buf->pages_pageout = uvm.pgswapout; #elif defined(HAVE_STRUCT_UVMEXP) && defined(VM_UVMEXP) mib[0] = CTL_VM; mib[1] = VM_UVMEXP; if (sysctl(mib, 2, &uvm, &size, NULL, 0) < 0) { RETURN_WITH_SET_ERROR_WITH_ERRNO("mem", SG_ERROR_SYSCTL, "CTL_VM.VM_UVMEXP"); } page_stats_buf->pages_pagein = uvm.pgswapin; page_stats_buf->pages_pageout = uvm.pgswapout; #elif defined(FREEBSD) || defined(DFBSD) size = sizeof(page_stats_buf->pages_pagein); if (sysctlbyname("vm.stats.vm.v_swappgsin", &page_stats_buf->pages_pagein, &size, NULL, 0) < 0) { RETURN_WITH_SET_ERROR_WITH_ERRNO("page", SG_ERROR_SYSCTLBYNAME, "vm.stats.vm.v_swappgsin"); } size = sizeof(page_stats_buf->pages_pageout); if (sysctlbyname("vm.stats.vm.v_swappgsout", &page_stats_buf->pages_pageout, &size, NULL, 0) < 0) { RETURN_WITH_SET_ERROR_WITH_ERRNO("page", SG_ERROR_SYSCTLBYNAME, "vm.stats.vm.v_swappgsout"); } #elif defined(AIX) /* return code is number of structures returned */ if(perfstat_memory_total(NULL, &mem, sizeof(perfstat_memory_total_t), 1) != 1) { RETURN_WITH_SET_ERROR_WITH_ERRNO("page", SG_ERROR_SYSCTLBYNAME, "perfstat_memory_total"); } page_stats_buf->pages_pagein = mem.pgins; page_stats_buf->pages_pageout = mem.pgouts; #elif defined(HPUX) if( pstat_getvminfo( &vminfo, sizeof(vminfo), 1, 0 ) == -1 ) { RETURN_WITH_SET_ERROR_WITH_ERRNO("page", SG_ERROR_SYSCTLBYNAME, "pstat_getswap"); } page_stats_buf->pages_pagein = vminfo.psv_spgin; page_stats_buf->pages_pageout = vminfo.psv_spgout; #else RETURN_WITH_SET_ERROR("page", SG_ERROR_UNSUPPORTED, OS_TYPE); #endif return SG_ERROR_NONE; }
static int memory_read (void) { #if HAVE_HOST_STATISTICS kern_return_t status; vm_statistics_data_t vm_data; mach_msg_type_number_t vm_data_len; gauge_t wired; gauge_t active; gauge_t inactive; gauge_t free; if (!port_host || !pagesize) return (-1); vm_data_len = sizeof (vm_data) / sizeof (natural_t); if ((status = host_statistics (port_host, HOST_VM_INFO, (host_info_t) &vm_data, &vm_data_len)) != KERN_SUCCESS) { ERROR ("memory-plugin: host_statistics failed and returned the value %i", (int) status); return (-1); } /* * From <http://docs.info.apple.com/article.html?artnum=107918>: * * Wired memory * This information can't be cached to disk, so it must stay in RAM. * The amount depends on what applications you are using. * * Active memory * This information is currently in RAM and actively being used. * * Inactive memory * This information is no longer being used and has been cached to * disk, but it will remain in RAM until another application needs * the space. Leaving this information in RAM is to your advantage if * you (or a client of your computer) come back to it later. * * Free memory * This memory is not being used. */ wired = (gauge_t) (((uint64_t) vm_data.wire_count) * ((uint64_t) pagesize)); active = (gauge_t) (((uint64_t) vm_data.active_count) * ((uint64_t) pagesize)); inactive = (gauge_t) (((uint64_t) vm_data.inactive_count) * ((uint64_t) pagesize)); free = (gauge_t) (((uint64_t) vm_data.free_count) * ((uint64_t) pagesize)); memory_submit ("wired", wired); memory_submit ("active", active); memory_submit ("inactive", inactive); memory_submit ("free", free); /* #endif HAVE_HOST_STATISTICS */ #elif HAVE_SYSCTLBYNAME /* * vm.stats.vm.v_page_size: 4096 * vm.stats.vm.v_page_count: 246178 * vm.stats.vm.v_free_count: 28760 * vm.stats.vm.v_wire_count: 37526 * vm.stats.vm.v_active_count: 55239 * vm.stats.vm.v_inactive_count: 113730 * vm.stats.vm.v_cache_count: 10809 */ char *sysctl_keys[8] = { "vm.stats.vm.v_page_size", "vm.stats.vm.v_page_count", "vm.stats.vm.v_free_count", "vm.stats.vm.v_wire_count", "vm.stats.vm.v_active_count", "vm.stats.vm.v_inactive_count", "vm.stats.vm.v_cache_count", NULL }; double sysctl_vals[8]; int i; for (i = 0; sysctl_keys[i] != NULL; i++) { int value; size_t value_len = sizeof (value); if (sysctlbyname (sysctl_keys[i], (void *) &value, &value_len, NULL, 0) == 0) { sysctl_vals[i] = value; DEBUG ("memory plugin: %26s: %g", sysctl_keys[i], sysctl_vals[i]); } else { sysctl_vals[i] = NAN; } } /* for (sysctl_keys) */ /* multiply all all page counts with the pagesize */ for (i = 1; sysctl_keys[i] != NULL; i++) if (!isnan (sysctl_vals[i])) sysctl_vals[i] *= sysctl_vals[0]; memory_submit ("free", sysctl_vals[2]); memory_submit ("wired", sysctl_vals[3]); memory_submit ("active", sysctl_vals[4]); memory_submit ("inactive", sysctl_vals[5]); memory_submit ("cache", sysctl_vals[6]); /* #endif HAVE_SYSCTLBYNAME */ #elif KERNEL_LINUX FILE *fh; char buffer[1024]; char *fields[8]; int numfields; long long mem_used = 0; long long mem_buffered = 0; long long mem_cached = 0; long long mem_free = 0; if ((fh = fopen ("/proc/meminfo", "r")) == NULL) { char errbuf[1024]; WARNING ("memory: fopen: %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } while (fgets (buffer, 1024, fh) != NULL) { long long *val = NULL; if (strncasecmp (buffer, "MemTotal:", 9) == 0) val = &mem_used; else if (strncasecmp (buffer, "MemFree:", 8) == 0) val = &mem_free; else if (strncasecmp (buffer, "Buffers:", 8) == 0) val = &mem_buffered; else if (strncasecmp (buffer, "Cached:", 7) == 0) val = &mem_cached; else continue; numfields = strsplit (buffer, fields, 8); if (numfields < 2) continue; *val = atoll (fields[1]) * 1024LL; } if (fclose (fh)) { char errbuf[1024]; WARNING ("memory: fclose: %s", sstrerror (errno, errbuf, sizeof (errbuf))); } if (mem_used >= (mem_free + mem_buffered + mem_cached)) { mem_used -= mem_free + mem_buffered + mem_cached; memory_submit ("used", mem_used); memory_submit ("buffered", mem_buffered); memory_submit ("cached", mem_cached); memory_submit ("free", mem_free); } /* #endif KERNEL_LINUX */ #elif HAVE_LIBKSTAT /* Most of the additions here were taken as-is from the k9toolkit from * Brendan Gregg and are subject to change I guess */ long long mem_used; long long mem_free; long long mem_lock; long long mem_kern; long long mem_unus; long long pp_kernel; long long physmem; long long availrmem; if (ksp == NULL) return (-1); mem_used = get_kstat_value (ksp, "pagestotal"); mem_free = get_kstat_value (ksp, "pagesfree"); mem_lock = get_kstat_value (ksp, "pageslocked"); mem_kern = 0; mem_unus = 0; pp_kernel = get_kstat_value (ksp, "pp_kernel"); physmem = get_kstat_value (ksp, "physmem"); availrmem = get_kstat_value (ksp, "availrmem"); if ((mem_used < 0LL) || (mem_free < 0LL) || (mem_lock < 0LL)) { WARNING ("memory plugin: one of used, free or locked is negative."); return (-1); } mem_unus = physmem - mem_used; if (mem_used < (mem_free + mem_lock)) { /* source: http://wesunsolve.net/bugid/id/4909199 * this seems to happen when swap space is small, e.g. 2G on a 32G system * we will make some assumptions here * educated solaris internals help welcome here */ DEBUG ("memory plugin: pages total is smaller than \"free\" " "+ \"locked\". This is probably due to small " "swap space"); mem_free = availrmem; mem_used = 0; } else { mem_used -= mem_free + mem_lock; } /* mem_kern is accounted for in mem_lock */ if ( pp_kernel < mem_lock ) { mem_kern = pp_kernel; mem_lock -= pp_kernel; } else { mem_kern = mem_lock; mem_lock = 0; } mem_used *= pagesize; /* If this overflows you have some serious */ mem_free *= pagesize; /* memory.. Why not call me up and give me */ mem_lock *= pagesize; /* some? ;) */ mem_kern *= pagesize; /* it's 2011 RAM is cheap */ mem_unus *= pagesize; memory_submit ("used", mem_used); memory_submit ("free", mem_free); memory_submit ("locked", mem_lock); memory_submit ("kernel", mem_kern); memory_submit ("unusable", mem_unus); /* #endif HAVE_LIBKSTAT */ #elif HAVE_SYSCTL int mib[] = {CTL_VM, VM_METER}; struct vmtotal vmtotal; size_t size; memset (&vmtotal, 0, sizeof (vmtotal)); size = sizeof (vmtotal); if (sysctl (mib, 2, &vmtotal, &size, NULL, 0) < 0) { char errbuf[1024]; WARNING ("memory plugin: sysctl failed: %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } assert (pagesize > 0); memory_submit ("active", vmtotal.t_arm * pagesize); memory_submit ("inactive", (vmtotal.t_rm - vmtotal.t_arm) * pagesize); memory_submit ("free", vmtotal.t_free * pagesize); /* #endif HAVE_SYSCTL */ #elif HAVE_LIBSTATGRAB sg_mem_stats *ios; if ((ios = sg_get_mem_stats ()) != NULL) { memory_submit ("used", ios->used); memory_submit ("cached", ios->cache); memory_submit ("free", ios->free); } /* #endif HAVE_LIBSTATGRAB */ #elif HAVE_PERFSTAT if (perfstat_memory_total(NULL, &pmemory, sizeof(perfstat_memory_total_t), 1) < 0) { char errbuf[1024]; WARNING ("memory plugin: perfstat_memory_total failed: %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } memory_submit ("used", pmemory.real_inuse * pagesize); memory_submit ("free", pmemory.real_free * pagesize); memory_submit ("cached", pmemory.numperm * pagesize); memory_submit ("system", pmemory.real_system * pagesize); memory_submit ("user", pmemory.real_process * pagesize); #endif /* HAVE_PERFSTAT */ return (0); }
static int memory_read_internal(value_list_t *vl) { #if HAVE_HOST_STATISTICS kern_return_t status; vm_statistics_data_t vm_data; mach_msg_type_number_t vm_data_len; gauge_t wired; gauge_t active; gauge_t inactive; gauge_t free; if (!port_host || !pagesize) return -1; vm_data_len = sizeof(vm_data) / sizeof(natural_t); if ((status = host_statistics(port_host, HOST_VM_INFO, (host_info_t)&vm_data, &vm_data_len)) != KERN_SUCCESS) { ERROR("memory-plugin: host_statistics failed and returned the value %i", (int)status); return -1; } /* * From <http://docs.info.apple.com/article.html?artnum=107918>: * * Wired memory * This information can't be cached to disk, so it must stay in RAM. * The amount depends on what applications you are using. * * Active memory * This information is currently in RAM and actively being used. * * Inactive memory * This information is no longer being used and has been cached to * disk, but it will remain in RAM until another application needs * the space. Leaving this information in RAM is to your advantage if * you (or a client of your computer) come back to it later. * * Free memory * This memory is not being used. */ wired = (gauge_t)(((uint64_t)vm_data.wire_count) * ((uint64_t)pagesize)); active = (gauge_t)(((uint64_t)vm_data.active_count) * ((uint64_t)pagesize)); inactive = (gauge_t)(((uint64_t)vm_data.inactive_count) * ((uint64_t)pagesize)); free = (gauge_t)(((uint64_t)vm_data.free_count) * ((uint64_t)pagesize)); MEMORY_SUBMIT("wired", wired, "active", active, "inactive", inactive, "free", free); /* #endif HAVE_HOST_STATISTICS */ #elif HAVE_SYSCTLBYNAME /* * vm.stats.vm.v_page_size: 4096 * vm.stats.vm.v_page_count: 246178 * vm.stats.vm.v_free_count: 28760 * vm.stats.vm.v_wire_count: 37526 * vm.stats.vm.v_active_count: 55239 * vm.stats.vm.v_inactive_count: 113730 * vm.stats.vm.v_cache_count: 10809 */ const char *sysctl_keys[8] = { "vm.stats.vm.v_page_size", "vm.stats.vm.v_page_count", "vm.stats.vm.v_free_count", "vm.stats.vm.v_wire_count", "vm.stats.vm.v_active_count", "vm.stats.vm.v_inactive_count", "vm.stats.vm.v_cache_count", NULL}; double sysctl_vals[8]; for (int i = 0; sysctl_keys[i] != NULL; i++) { int value; size_t value_len = sizeof(value); if (sysctlbyname(sysctl_keys[i], (void *)&value, &value_len, NULL, 0) == 0) { sysctl_vals[i] = value; DEBUG("memory plugin: %26s: %g", sysctl_keys[i], sysctl_vals[i]); } else { sysctl_vals[i] = NAN; } } /* for (sysctl_keys) */ /* multiply all all page counts with the pagesize */ for (int i = 1; sysctl_keys[i] != NULL; i++) if (!isnan(sysctl_vals[i])) sysctl_vals[i] *= sysctl_vals[0]; MEMORY_SUBMIT("free", (gauge_t)sysctl_vals[2], "wired", (gauge_t)sysctl_vals[3], "active", (gauge_t)sysctl_vals[4], "inactive", (gauge_t)sysctl_vals[5], "cache", (gauge_t)sysctl_vals[6]); /* #endif HAVE_SYSCTLBYNAME */ #elif KERNEL_LINUX FILE *fh; char buffer[1024]; char *fields[8]; int numfields; bool detailed_slab_info = false; gauge_t mem_total = 0; gauge_t mem_used = 0; gauge_t mem_buffered = 0; gauge_t mem_cached = 0; gauge_t mem_free = 0; gauge_t mem_slab_total = 0; gauge_t mem_slab_reclaimable = 0; gauge_t mem_slab_unreclaimable = 0; if ((fh = fopen("/proc/meminfo", "r")) == NULL) { WARNING("memory: fopen: %s", STRERRNO); return -1; } while (fgets(buffer, sizeof(buffer), fh) != NULL) { gauge_t *val = NULL; if (strncasecmp(buffer, "MemTotal:", 9) == 0) val = &mem_total; else if (strncasecmp(buffer, "MemFree:", 8) == 0) val = &mem_free; else if (strncasecmp(buffer, "Buffers:", 8) == 0) val = &mem_buffered; else if (strncasecmp(buffer, "Cached:", 7) == 0) val = &mem_cached; else if (strncasecmp(buffer, "Slab:", 5) == 0) val = &mem_slab_total; else if (strncasecmp(buffer, "SReclaimable:", 13) == 0) { val = &mem_slab_reclaimable; detailed_slab_info = true; } else if (strncasecmp(buffer, "SUnreclaim:", 11) == 0) { val = &mem_slab_unreclaimable; detailed_slab_info = true; } else continue; numfields = strsplit(buffer, fields, STATIC_ARRAY_SIZE(fields)); if (numfields < 2) continue; *val = 1024.0 * atof(fields[1]); } if (fclose(fh)) { WARNING("memory: fclose: %s", STRERRNO); } if (mem_total < (mem_free + mem_buffered + mem_cached + mem_slab_total)) return -1; mem_used = mem_total - (mem_free + mem_buffered + mem_cached + mem_slab_total); /* SReclaimable and SUnreclaim were introduced in kernel 2.6.19 * They sum up to the value of Slab, which is available on older & newer * kernels. So SReclaimable/SUnreclaim are submitted if available, and Slab * if not. */ if (detailed_slab_info) MEMORY_SUBMIT("used", mem_used, "buffered", mem_buffered, "cached", mem_cached, "free", mem_free, "slab_unrecl", mem_slab_unreclaimable, "slab_recl", mem_slab_reclaimable); else MEMORY_SUBMIT("used", mem_used, "buffered", mem_buffered, "cached", mem_cached, "free", mem_free, "slab", mem_slab_total); /* #endif KERNEL_LINUX */ #elif HAVE_LIBKSTAT /* Most of the additions here were taken as-is from the k9toolkit from * Brendan Gregg and are subject to change I guess */ long long mem_used; long long mem_free; long long mem_lock; long long mem_kern; long long mem_unus; long long arcsize; long long pp_kernel; long long physmem; long long availrmem; if (ksp == NULL) return -1; if (ksz == NULL) return -1; mem_used = get_kstat_value(ksp, "pagestotal"); mem_free = get_kstat_value(ksp, "pagesfree"); mem_lock = get_kstat_value(ksp, "pageslocked"); arcsize = get_kstat_value(ksz, "size"); pp_kernel = get_kstat_value(ksp, "pp_kernel"); physmem = get_kstat_value(ksp, "physmem"); availrmem = get_kstat_value(ksp, "availrmem"); mem_kern = 0; mem_unus = 0; if ((mem_used < 0LL) || (mem_free < 0LL) || (mem_lock < 0LL)) { WARNING("memory plugin: one of used, free or locked is negative."); return -1; } mem_unus = physmem - mem_used; if (mem_used < (mem_free + mem_lock)) { /* source: http://wesunsolve.net/bugid/id/4909199 * this seems to happen when swap space is small, e.g. 2G on a 32G system * we will make some assumptions here * educated solaris internals help welcome here */ DEBUG("memory plugin: pages total is smaller than \"free\" " "+ \"locked\". This is probably due to small " "swap space"); mem_free = availrmem; mem_used = 0; } else { mem_used -= mem_free + mem_lock; } /* mem_kern is accounted for in mem_lock */ if (pp_kernel < mem_lock) { mem_kern = pp_kernel; mem_lock -= pp_kernel; } else { mem_kern = mem_lock; mem_lock = 0; } mem_used *= pagesize; /* If this overflows you have some serious */ mem_free *= pagesize; /* memory.. Why not call me up and give me */ mem_lock *= pagesize; /* some? ;) */ mem_kern *= pagesize; /* it's 2011 RAM is cheap */ mem_unus *= pagesize; mem_kern -= arcsize; MEMORY_SUBMIT("used", (gauge_t)mem_used, "free", (gauge_t)mem_free, "locked", (gauge_t)mem_lock, "kernel", (gauge_t)mem_kern, "arc", (gauge_t)arcsize, "unusable", (gauge_t)mem_unus); /* #endif HAVE_LIBKSTAT */ #elif HAVE_SYSCTL int mib[] = {CTL_VM, VM_METER}; struct vmtotal vmtotal = {0}; gauge_t mem_active; gauge_t mem_inactive; gauge_t mem_free; size_t size; size = sizeof(vmtotal); if (sysctl(mib, 2, &vmtotal, &size, NULL, 0) < 0) { WARNING("memory plugin: sysctl failed: %s", STRERRNO); return -1; } assert(pagesize > 0); mem_active = (gauge_t)(vmtotal.t_arm * pagesize); mem_inactive = (gauge_t)((vmtotal.t_rm - vmtotal.t_arm) * pagesize); mem_free = (gauge_t)(vmtotal.t_free * pagesize); MEMORY_SUBMIT("active", mem_active, "inactive", mem_inactive, "free", mem_free); /* #endif HAVE_SYSCTL */ #elif HAVE_LIBSTATGRAB sg_mem_stats *ios; ios = sg_get_mem_stats(); if (ios == NULL) return -1; MEMORY_SUBMIT("used", (gauge_t)ios->used, "cached", (gauge_t)ios->cache, "free", (gauge_t)ios->free); /* #endif HAVE_LIBSTATGRAB */ #elif HAVE_PERFSTAT perfstat_memory_total_t pmemory = {0}; if (perfstat_memory_total(NULL, &pmemory, sizeof(pmemory), 1) < 0) { WARNING("memory plugin: perfstat_memory_total failed: %s", STRERRNO); return -1; } /* Unfortunately, the AIX documentation is not very clear on how these * numbers relate to one another. The only thing is states explcitly * is: * real_total = real_process + real_free + numperm + real_system * * Another segmentation, which would be closer to the numbers reported * by the "svmon" utility, would be: * real_total = real_free + real_inuse * real_inuse = "active" + real_pinned + numperm */ MEMORY_SUBMIT("free", (gauge_t)(pmemory.real_free * pagesize), "cached", (gauge_t)(pmemory.numperm * pagesize), "system", (gauge_t)(pmemory.real_system * pagesize), "user", (gauge_t)(pmemory.real_process * pagesize)); #endif /* HAVE_PERFSTAT */ return 0; } /* }}} int memory_read_internal */
int getfreememory(void) { #if defined(_MSC_VER) { MEMORYSTATUS stat; GlobalMemoryStatus (&stat); return (int)(stat.dwAvailPhys / kooctet); } #elif defined(hpux) { struct pst_static pst; /* pstat_getstatic(&pst, sizeof(pst), (size_t) 1, 0); memorysizeKO=(pst.psd_free)/kooctet;*/ return 0; } #elif defined(__APPLE__) { vm_statistics_data_t page_info; vm_size_t pagesize; mach_msg_type_number_t count; kern_return_t kret; pagesize = 0; kret = host_page_size (mach_host_self(), &pagesize); count = HOST_VM_INFO_COUNT; kret = host_statistics (mach_host_self(), HOST_VM_INFO, (host_info_t)&page_info, &count); return page_info.free_count * pagesize / 1024; } #elif HAVE_TABLE && defined TBL_VMSTATS { /* This works on Tru64 UNIX V4/5. */ struct tbl_vmstats vmstats; if (table (TBL_VMSTATS, 0, &vmstats, 1, sizeof (vmstats)) == 1) { double pages = vmstats.free_count; double pagesize = vmstats.pagesize; if (0 <= pages && 0 <= pagesize) { return pages * pagesize; } else { return 0; } } } #elif defined(__linux__) { char field[9] = {0}; long long data = 0; char unit[4] = {0}; long long free = -1, buffers = -1, cached = -1; FILE *fp = fopen("/proc/meminfo", "r"); if (fp != NULL) { /* Read Cached, Buffers and MemFree from /proc/meminfo */ while (fscanf(fp, "%8s %lld %3s\n", field, &data, unit) != EOF) { if (!strncmp("MemFree:", field, 8)) { free = data; } else if (!strncmp("Buffers:", field, 8)) { buffers = data; } else if (!strncmp("Cached:", field, 8)) { cached = data; } } fclose(fp); /* Read successful, convert unit and return the result */ if (buffers >= 0 && cached >= 0 && free >= 0) { free += cached + buffers; switch (unit[0]) { case 'g': case 'G': free *= kooctet; case 'm': case 'M': free *= kooctet; break; case 'o': case 'O': free /= kooctet; } return (int)free; } } /* Strange, /proc not mounted ? new and unknown format ? fall back to inaccurate sysconf() */ return (sysconf(_SC_AVPHYS_PAGES) * sysconf(_SC_PAGESIZE)) / kooctet; } #elif defined(__NetBSD__) || defined(__DragonFly__) { /* This works on *bsd. */ int mib[2]; struct uvmexp_sysctl uvmexp; long freemem; size_t lenu = sizeof uvmexp; unsigned int pagesize; static int pageshift = PAGESHIFT_UNDEF; size_t lenp = sizeof pagesize; mib[0] = CTL_HW; if (pageshift == PAGESHIFT_UNDEF) { /* Figure out the page size */ mib[1] = HW_PAGESIZE; if (sysctl (mib, ARRAY_SIZE (mib), &pagesize, &lenp, NULL, 0) != 0 || lenp != sizeof (pagesize) ) { /* sysctl failed -- what to do?? */ return 0; } pageshift = 0; while (pagesize > 1) { pageshift++; pagesize >>= 1; } /* convert to kB */ pageshift -= 10; } mib[0] = CTL_VM; mib[1] = VM_UVMEXP2; if ( (sysctl (mib, ARRAY_SIZE (mib), &uvmexp, &lenu, NULL, 0) == 0) && (lenu == sizeof (uvmexp)) ) { return (uvmexp.free << pageshift); } return 0; }
/*++ Function: GlobalMemoryStatusEx GlobalMemoryStatusEx Retrieves information about the system's current usage of both physical and virtual memory. Return Values This function returns a BOOL to indicate its success status. --*/ BOOL PALAPI GlobalMemoryStatusEx( IN OUT LPMEMORYSTATUSEX lpBuffer) { PERF_ENTRY(GlobalMemoryStatusEx); ENTRY("GlobalMemoryStatusEx (lpBuffer=%p)\n", lpBuffer); lpBuffer->dwMemoryLoad = 0; lpBuffer->ullTotalPhys = 0; lpBuffer->ullAvailPhys = 0; lpBuffer->ullTotalPageFile = 0; lpBuffer->ullAvailPageFile = 0; lpBuffer->ullTotalVirtual = 0; lpBuffer->ullAvailVirtual = 0; lpBuffer->ullAvailExtendedVirtual = 0; BOOL fRetVal = FALSE; // Get the physical memory size #if HAVE_SYSCONF && HAVE__SC_PHYS_PAGES int64_t physical_memory; // Get the Physical memory size physical_memory = sysconf( _SC_PHYS_PAGES ) * sysconf( _SC_PAGE_SIZE ); lpBuffer->ullTotalPhys = (DWORDLONG)physical_memory; fRetVal = TRUE; #elif HAVE_SYSCTL int mib[2]; int64_t physical_memory; size_t length; // Get the Physical memory size mib[0] = CTL_HW; mib[1] = HW_MEMSIZE; length = sizeof(INT64); int rc = sysctl(mib, 2, &physical_memory, &length, NULL, 0); if (rc != 0) { ASSERT("sysctl failed for HW_MEMSIZE (%d)\n", errno); } else { lpBuffer->ullTotalPhys = (DWORDLONG)physical_memory; fRetVal = TRUE; } #elif // HAVE_SYSINFO // TODO: implement getting memory details via sysinfo. On Linux, it provides swap file details that // we can use to fill in the xxxPageFile members. #endif // HAVE_SYSCONF // Get the physical memory in use - from it, we can get the physical memory available. // We do this only when we have the total physical memory available. if (lpBuffer->ullTotalPhys > 0) { #ifndef __APPLE__ lpBuffer->ullAvailPhys = sysconf(SYSCONF_PAGES) * sysconf(_SC_PAGE_SIZE); INT64 used_memory = lpBuffer->ullTotalPhys - lpBuffer->ullAvailPhys; lpBuffer->dwMemoryLoad = (DWORD)((used_memory * 100) / lpBuffer->ullTotalPhys); #else vm_size_t page_size; mach_port_t mach_port; mach_msg_type_number_t count; vm_statistics_data_t vm_stats; mach_port = mach_host_self(); count = sizeof(vm_stats) / sizeof(natural_t); if (KERN_SUCCESS == host_page_size(mach_port, &page_size)) { if (KERN_SUCCESS == host_statistics(mach_port, HOST_VM_INFO, (host_info_t)&vm_stats, &count)) { lpBuffer->ullAvailPhys = (int64_t)vm_stats.free_count * (int64_t)page_size; INT64 used_memory = ((INT64)vm_stats.active_count + (INT64)vm_stats.inactive_count + (INT64)vm_stats.wire_count) * (INT64)page_size; lpBuffer->dwMemoryLoad = (DWORD)((used_memory * 100) / lpBuffer->ullTotalPhys); } } mach_port_deallocate(mach_task_self(), mach_port); #endif // __APPLE__ } // There is no API to get the total virtual address space size on // Unix, so we use a constant value representing 128TB, which is // the approximate size of total user virtual address space on // the currently supported Unix systems. static const UINT64 _128TB = (1ull << 47); lpBuffer->ullTotalVirtual = _128TB; lpBuffer->ullAvailVirtual = lpBuffer->ullAvailPhys; LOGEXIT("GlobalMemoryStatusEx returns %d\n", fRetVal); PERF_EXIT(GlobalMemoryStatusEx); return fRetVal; }
void KCMMemory::fetchValues() { vm_statistics_data_t vm_info; mach_msg_type_number_t info_count; DIR *dirp; struct dirent *dp; t_memsize total; info_count = HOST_VM_INFO_COUNT; if (host_statistics(mach_host_self (), HOST_VM_INFO, (host_info_t)&vm_info, &info_count)) { kDebug() << "could not get memory statistics"; return; } memoryInfos[TOTAL_MEM] = MEMORY(vm_info.active_count + vm_info.inactive_count + vm_info.free_count + vm_info.wire_count) * vm_page_size; memoryInfos[FREE_MEM] = MEMORY(vm_info.free_count) * vm_page_size; memoryInfos[SHARED_MEM] = NO_MEMORY_INFO; memoryInfos[BUFFER_MEM] = NO_MEMORY_INFO; memoryInfos[CACHED_MEM] = NO_MEMORY_INFO; dirp = opendir("/private/var/vm"); if (!dirp) { kDebug() << "unable to open /private/var/vm"; return; } total = 0; while ((dp = readdir (dirp)) != NULL) { struct stat sb; char fname [MAXNAMLEN]; if (strncmp (dp->d_name, "swapfile", 8)) continue; strcpy (fname, "/private/var/vm/"); strcat (fname, dp->d_name); if (stat (fname, &sb) < 0) continue; total += sb.st_size; } closedir (dirp); info_count = HOST_VM_INFO_COUNT; if (host_statistics (mach_host_self (), HOST_VM_INFO, (host_info_t) &vm_info, &info_count)) { kDebug() << "unable to get VM info"; } memoryInfos[SWAP_MEM] = total; // off_t used = (vm_info.pageouts - vm_info.pageins) * vm_page_size; memoryInfos[FREESWAP_MEM] = NO_MEMORY_INFO; /* free = MEMORY(vm_info.free_count) * vm_page_size; used = MEMORY(vm_info.active_count) * vm_page_size; total = MEMORY(vm_info.active_count + vm_info.inactive_count + vm_info.free_count + vm_info.wire_count) * vm_page_size; */ }
void ProcessList_getVMStats(vm_statistics_t p) { mach_msg_type_number_t info_size = HOST_VM_INFO_COUNT; if (host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t)p, &info_size) != 0) CRT_fatalError("Unable to retrieve VM statistics\n"); }
void GlobalMemoryStatusEx(LPMEMORYSTATUSEX lpBuffer) { if (!lpBuffer) return; memset(lpBuffer, 0, sizeof(MEMORYSTATUSEX)); lpBuffer->dwLength = sizeof(MEMORYSTATUSEX); #if defined(TARGET_DARWIN) uint64_t physmem; size_t len = sizeof physmem; int mib[2] = { CTL_HW, HW_MEMSIZE }; size_t miblen = ARRAY_SIZE(mib); // Total physical memory. if (sysctl(mib, miblen, &physmem, &len, NULL, 0) == 0 && len == sizeof (physmem)) lpBuffer->ullTotalPhys = physmem; // Virtual memory. mib[0] = CTL_VM; mib[1] = VM_SWAPUSAGE; struct xsw_usage swap; len = sizeof(struct xsw_usage); if (sysctl(mib, miblen, &swap, &len, NULL, 0) == 0) { lpBuffer->ullAvailPageFile = swap.xsu_avail; lpBuffer->ullTotalVirtual = lpBuffer->ullTotalPhys + swap.xsu_total; } // In use. mach_port_t stat_port = mach_host_self(); vm_statistics_data_t vm_stat; mach_msg_type_number_t count = sizeof(vm_stat) / sizeof(natural_t); if (host_statistics(stat_port, HOST_VM_INFO, (host_info_t)&vm_stat, &count) == 0) { // Find page size. #if defined(TARGET_DARWIN_IOS) // on ios with 64bit ARM CPU the page size is wrongly given as 16K // when using the sysctl approach. We can use the host_page_size // function instead which will give the proper 4k pagesize // on both 32 and 64 bit ARM CPUs vm_size_t pageSize; host_page_size(stat_port, &pageSize); #else int pageSize; mib[0] = CTL_HW; mib[1] = HW_PAGESIZE; len = sizeof(int); if (sysctl(mib, miblen, &pageSize, &len, NULL, 0) == 0) #endif { uint64_t used = (vm_stat.active_count + vm_stat.inactive_count + vm_stat.wire_count) * pageSize; lpBuffer->ullAvailPhys = lpBuffer->ullTotalPhys - used; lpBuffer->ullAvailVirtual = lpBuffer->ullAvailPhys; // FIXME. } } #elif defined(TARGET_FREEBSD) /* sysctl hw.physmem */ size_t physmem = 0, mem_free = 0, pagesize = 0, swap_free = 0; size_t mem_avail = 0, mem_inactive = 0, mem_cache = 0, len = 0; /* physmem */ len = sizeof(physmem); if (sysctlbyname("hw.physmem", &physmem, &len, NULL, 0) == 0) { lpBuffer->ullTotalPhys = physmem; lpBuffer->ullTotalVirtual = physmem; } /* pagesize */ len = sizeof(pagesize); if (sysctlbyname("hw.pagesize", &pagesize, &len, NULL, 0) != 0) pagesize = 4096; /* mem_inactive */ len = sizeof(mem_inactive); if (sysctlbyname("vm.stats.vm.v_inactive_count", &mem_inactive, &len, NULL, 0) == 0) mem_inactive *= pagesize; /* mem_cache */ len = sizeof(mem_cache); if (sysctlbyname("vm.stats.vm.v_cache_count", &mem_cache, &len, NULL, 0) == 0) mem_cache *= pagesize; /* mem_free */ len = sizeof(mem_free); if (sysctlbyname("vm.stats.vm.v_free_count", &mem_free, &len, NULL, 0) == 0) mem_free *= pagesize; /* mem_avail = mem_inactive + mem_cache + mem_free */ lpBuffer->ullAvailPhys = mem_inactive + mem_cache + mem_free; lpBuffer->ullAvailVirtual = mem_inactive + mem_cache + mem_free; if (sysctlbyname("vm.stats.vm.v_swappgsout", &swap_free, &len, NULL, 0) == 0) lpBuffer->ullAvailPageFile = swap_free * pagesize; #else struct sysinfo info; char name[32]; unsigned val; if (!procMeminfoFP && (procMeminfoFP = fopen("/proc/meminfo", "r")) == NULL) sysinfo(&info); else { memset(&info, 0, sizeof(struct sysinfo)); info.mem_unit = 4096; while (fscanf(procMeminfoFP, "%31s %u%*[^\n]\n", name, &val) != EOF) { if (strncmp("MemTotal:", name, 9) == 0) info.totalram = val/4; else if (strncmp("MemFree:", name, 8) == 0) info.freeram = val/4; else if (strncmp("Buffers:", name, 8) == 0) info.bufferram += val/4; else if (strncmp("Cached:", name, 7) == 0) info.bufferram += val/4; else if (strncmp("SwapTotal:", name, 10) == 0) info.totalswap = val/4; else if (strncmp("SwapFree:", name, 9) == 0) info.freeswap = val/4; else if (strncmp("HighTotal:", name, 10) == 0) info.totalhigh = val/4; else if (strncmp("HighFree:", name, 9) == 0) info.freehigh = val/4; } rewind(procMeminfoFP); fflush(procMeminfoFP); } lpBuffer->dwLength = sizeof(MEMORYSTATUSEX); lpBuffer->ullAvailPageFile = (info.freeswap * info.mem_unit); lpBuffer->ullAvailPhys = ((info.freeram + info.bufferram) * info.mem_unit); lpBuffer->ullAvailVirtual = ((info.freeram + info.bufferram) * info.mem_unit); lpBuffer->ullTotalPhys = (info.totalram * info.mem_unit); lpBuffer->ullTotalVirtual = (info.totalram * info.mem_unit); #endif }
kern_return_t host_statistics64( host_t host, host_flavor_t flavor, host_info64_t info, mach_msg_type_number_t *count) { uint32_t i; if (host == HOST_NULL) return (KERN_INVALID_HOST); switch(flavor) { case HOST_VM_INFO64: /* We were asked to get vm_statistics64 */ { register processor_t processor; register vm_statistics64_t stat; vm_statistics64_data_t host_vm_stat; if (*count < HOST_VM_INFO64_COUNT) return (KERN_FAILURE); processor = processor_list; stat = &PROCESSOR_DATA(processor, vm_stat); host_vm_stat = *stat; if (processor_count > 1) { simple_lock(&processor_list_lock); while ((processor = processor->processor_list) != NULL) { stat = &PROCESSOR_DATA(processor, vm_stat); host_vm_stat.zero_fill_count += stat->zero_fill_count; host_vm_stat.reactivations += stat->reactivations; host_vm_stat.pageins += stat->pageins; host_vm_stat.pageouts += stat->pageouts; host_vm_stat.faults += stat->faults; host_vm_stat.cow_faults += stat->cow_faults; host_vm_stat.lookups += stat->lookups; host_vm_stat.hits += stat->hits; } simple_unlock(&processor_list_lock); } stat = (vm_statistics64_t) info; stat->free_count = vm_page_free_count + vm_page_speculative_count; stat->active_count = vm_page_active_count; if (vm_page_local_q) { for (i = 0; i < vm_page_local_q_count; i++) { struct vpl *lq; lq = &vm_page_local_q[i].vpl_un.vpl; stat->active_count += lq->vpl_count; } } stat->inactive_count = vm_page_inactive_count; #if CONFIG_EMBEDDED stat->wire_count = vm_page_wire_count; #else stat->wire_count = vm_page_wire_count + vm_page_throttled_count + vm_lopage_free_count; #endif stat->zero_fill_count = host_vm_stat.zero_fill_count; stat->reactivations = host_vm_stat.reactivations; stat->pageins = host_vm_stat.pageins; stat->pageouts = host_vm_stat.pageouts; stat->faults = host_vm_stat.faults; stat->cow_faults = host_vm_stat.cow_faults; stat->lookups = host_vm_stat.lookups; stat->hits = host_vm_stat.hits; /* rev1 added "purgable" info */ stat->purgeable_count = vm_page_purgeable_count; stat->purges = vm_page_purged_count; /* rev2 added "speculative" info */ stat->speculative_count = vm_page_speculative_count; *count = HOST_VM_INFO64_COUNT; return(KERN_SUCCESS); } case HOST_EXTMOD_INFO64: /* We were asked to get vm_statistics64 */ { vm_extmod_statistics_t out_extmod_statistics; if (*count < HOST_EXTMOD_INFO64_COUNT) return (KERN_FAILURE); out_extmod_statistics = (vm_extmod_statistics_t) info; *out_extmod_statistics = host_extmod_statistics; *count = HOST_EXTMOD_INFO64_COUNT; return(KERN_SUCCESS); } default: /* If we didn't recognize the flavor, send to host_statistics */ return(host_statistics(host, flavor, (host_info_t) info, count)); } }
static sg_error sg_get_mem_stats_int(sg_mem_stats *mem_stats_buf) { #ifdef HPUX struct pst_static pstat_static; struct pst_dynamic pstat_dynamic; #elif defined(SOLARIS) # ifdef _SC_PHYS_PAGES long phystotal; long physav; # else kstat_ctl_t *kc; kstat_t *ksp; kstat_named_t *kn; # endif #elif defined(LINUX) || defined(CYGWIN) #define LINE_BUF_SIZE 256 char *line_ptr, line_buf[LINE_BUF_SIZE]; long long value; FILE *f; #elif defined(HAVE_HOST_STATISTICS) || defined(HAVE_HOST_STATISTICS64) # if defined(HAVE_HOST_STATISTICS64) struct vm_statistics64 vm_stats; # else struct vm_statistics vm_stats; # endif mach_msg_type_number_t count; kern_return_t rc; #elif defined(HAVE_STRUCT_UVMEXP_SYSCTL) && defined(VM_UVMEXP2) int mib[2]; struct uvmexp_sysctl uvm; size_t size = sizeof(uvm); #elif defined(HAVE_STRUCT_UVMEXP) && defined(VM_UVMEXP) int mib[2]; struct uvmexp uvm; size_t size = sizeof(uvm); #elif defined(FREEBSD) || defined(DFBSD) size_t size; unsigned int total_count; unsigned int free_count; unsigned int cache_count; unsigned int inactive_count; #elif defined(HAVE_STRUCT_VMTOTAL) struct vmtotal vmtotal; size_t size; #if defined(HW_PHYSMEM) || defined(HW_USERMEM) int mib[2]; # if defined(HW_PHYSMEM) u_long total_mem; # endif # if defined(HW_USERMEM) u_long user_mem; # endif #endif #elif defined(AIX) perfstat_memory_total_t mem; #elif defined(WIN32) MEMORYSTATUSEX memstats; #endif #if defined(HPUX) if (pstat_getdynamic(&pstat_dynamic, sizeof(pstat_dynamic), 1, 0) == -1) { RETURN_WITH_SET_ERROR_WITH_ERRNO("mem", SG_ERROR_PSTAT, "pstat_dynamic"); } /* * from man pstat_getstatic: * * pstat_getstatic() returns information about the system. Although * this data usually does not change frequently, it may change while * the system is running due to manually or automatically generated * administrative changes in the associated kernel tunables, online * addition/deletion of resources, or other events. There is one * global instance of this context. * * ==> Can't hold this value globally static. */ if( pstat_getstatic(&pstat_static, sizeof(pstat_static), 1, 0) == -1 ) { RETURN_WITH_SET_ERROR_WITH_ERRNO("mem", SG_ERROR_PSTAT, "pstat_static"); } mem_stats_buf->total = ((long long) pstat_static.physical_memory) * pstat_static.page_size; mem_stats_buf->free = ((long long) pstat_dynamic.psd_free) * pstat_static.page_size; mem_stats_buf->used = mem_stats_buf->total - mem_stats_buf->free; #elif defined(AIX) /* return code is number of structures returned */ if(perfstat_memory_total(NULL, &mem, sizeof(perfstat_memory_total_t), 1) != 1) { RETURN_WITH_SET_ERROR_WITH_ERRNO("mem", SG_ERROR_SYSCTLBYNAME, "perfstat_memory_total"); } mem_stats_buf->total = (unsigned long long) mem.real_total; mem_stats_buf->total *= sys_page_size; mem_stats_buf->used = (unsigned long long) mem.real_inuse; mem_stats_buf->used *= sys_page_size; mem_stats_buf->cache = (unsigned long long) mem.numperm; mem_stats_buf->cache *= sys_page_size; mem_stats_buf->free = (unsigned long long) mem.real_free; mem_stats_buf->free *= sys_page_size; #elif defined(SOLARIS) # ifdef _SC_PHYS_PAGES if( ( phystotal = sysconf(_SC_PHYS_PAGES) ) < 0 ) { RETURN_WITH_SET_ERROR_WITH_ERRNO("mem", SG_ERROR_SYSCONF, "_SC_PHYS_PAGES"); } if( ( physav = sysconf(_SC_AVPHYS_PAGES) ) < 0 ) { RETURN_WITH_SET_ERROR_WITH_ERRNO("mem", SG_ERROR_SYSCONF, "_SC_AVPHYS_PAGES"); } mem_stats_buf->total = ((unsigned long long)phystotal) * ((unsigned long long)sys_page_size); mem_stats_buf->free = ((unsigned long long)physav) * ((unsigned long long)sys_page_size); # else if( (kc = kstat_open()) == NULL ) { RETURN_WITH_SET_ERROR("mem", SG_ERROR_KSTAT_OPEN, NULL); } if((ksp=kstat_lookup(kc, "unix", 0, "system_pages")) == NULL) { RETURN_WITH_SET_ERROR("mem", SG_ERROR_KSTAT_LOOKUP, "unix,0,system_pages"); } if (kstat_read(kc, ksp, 0) == -1) { RETURN_WITH_SET_ERROR("mem", SG_ERROR_KSTAT_READ, NULL); } if((kn=kstat_data_lookup(ksp, "physmem")) == NULL) { RETURN_WITH_SET_ERROR("mem", SG_ERROR_KSTAT_DATA_LOOKUP, "physmem"); } mem_stats_buf->total = ((unsigned long long)kn->value.ul) * ((unsigned long long)sys_page_size); if((kn=kstat_data_lookup(ksp, "freemem")) == NULL) { RETURN_WITH_SET_ERROR("mem", SG_ERROR_KSTAT_DATA_LOOKUP, "freemem"); } mem_stats_buf->free = ((unsigned long long)kn->value.ul) * ((unsigned long long)sys_page_size); kstat_close(kc); # endif mem_stats_buf->used = mem_stats_buf->total - mem_stats_buf->free; mem_stats_buf->cache = 0; #elif defined(LINUX) || defined(CYGWIN) if ((f = fopen("/proc/meminfo", "r")) == NULL) { RETURN_WITH_SET_ERROR_WITH_ERRNO("mem", SG_ERROR_OPEN, "/proc/meminfo"); } #define MEM_TOTAL_PREFIX "MemTotal:" #define MEM_FREE_PREFIX "MemFree:" #define MEM_CACHED_PREFIX "Cached:" while ((line_ptr = fgets(line_buf, sizeof(line_buf), f)) != NULL) { if ( sscanf(line_buf, "%*s %lld kB", &value) != 1) continue; if (strncmp(line_buf, MEM_TOTAL_PREFIX, sizeof(MEM_TOTAL_PREFIX) - 1) == 0) mem_stats_buf->total = value; else if (strncmp(line_buf, MEM_FREE_PREFIX, sizeof(MEM_FREE_PREFIX) - 1) == 0) mem_stats_buf->free = value; else if (strncmp(line_buf, MEM_CACHED_PREFIX, sizeof(MEM_CACHED_PREFIX) - 1) == 0) mem_stats_buf->cache = value; } mem_stats_buf->free += mem_stats_buf->cache; mem_stats_buf->total *= 1024; mem_stats_buf->free *= 1024; mem_stats_buf->cache *= 1024; #undef MEM_TOTAL_PREFIX #undef MEM_FREE_PREFIX #undef MEM_CACHED_PREFIX fclose(f); mem_stats_buf->used = mem_stats_buf->total - mem_stats_buf->free; #elif defined(HAVE_STRUCT_UVMEXP_SYSCTL) && defined(VM_UVMEXP2) mib[0] = CTL_VM; mib[1] = VM_UVMEXP2; if (sysctl(mib, 2, &uvm, &size, NULL, 0) < 0) { RETURN_WITH_SET_ERROR_WITH_ERRNO("mem", SG_ERROR_SYSCTL, "CTL_VM.VM_UVMEXP2"); } mem_stats_buf->total = uvm.npages; mem_stats_buf->cache = uvm.filepages + uvm.execpages; mem_stats_buf->free = uvm.free + mem_stats_buf->cache; mem_stats_buf->total *= uvm.pagesize; mem_stats_buf->cache *= uvm.pagesize; mem_stats_buf->free *= uvm.pagesize; mem_stats_buf->used = mem_stats_buf->total - mem_stats_buf->free; #elif defined(HAVE_STRUCT_UVMEXP) && defined(VM_UVMEXP) mib[0] = CTL_VM; mib[1] = VM_UVMEXP; if (sysctl(mib, 2, &uvm, &size, NULL, 0) < 0) { RETURN_WITH_SET_ERROR_WITH_ERRNO("mem", SG_ERROR_SYSCTL, "CTL_VM.VM_UVMEXP"); } mem_stats_buf->total = uvm.npages; mem_stats_buf->cache = 0; # if defined(HAVE_STRUCT_UVMEXP_FILEPAGES) mem_stats_buf->cache += uvm.filepages; # endif # if defined(HAVE_STRUCT_UVMEXP_EXECPAGES) mem_stats_buf->cache += uvm.execpages; # endif mem_stats_buf->free = uvm.free + mem_stats_buf->cache; mem_stats_buf->total *= uvm.pagesize; mem_stats_buf->cache *= uvm.pagesize; mem_stats_buf->free *= uvm.pagesize; mem_stats_buf->used = mem_stats_buf->total - mem_stats_buf->free; #elif defined(HAVE_HOST_STATISTICS) || defined(HAVE_HOST_STATISTICS64) # if defined(HAVE_HOST_STATISTICS64) count = HOST_VM_INFO64_COUNT; rc = host_statistics64(self_host_port, HOST_VM_INFO64, (host_info64_t)(&vm_stats), &count); # else count = HOST_VM_INFO_COUNT; rc = host_statistics(self_host_port, HOST_VM_INFO, (host_info_t)(&vm_stats), &count); # endif if( rc != KERN_SUCCESS ) { RETURN_WITH_SET_ERROR_WITH_ERRNO_CODE( "mem", SG_ERROR_MACHCALL, rc, "host_statistics" ); } /* * XXX check host_info(host_basic_info) ... for memory_size */ mem_stats_buf->free = vm_stats.free_count - vm_stats.speculative_count; mem_stats_buf->free += vm_stats.inactive_count; mem_stats_buf->free *= (size_t)sys_page_size; mem_stats_buf->total = vm_stats.active_count + vm_stats.wire_count + vm_stats.inactive_count + vm_stats.free_count; mem_stats_buf->total *= (size_t)sys_page_size; mem_stats_buf->used = mem_stats_buf->total - mem_stats_buf->free; mem_stats_buf->cache = 0; #elif defined(FREEBSD) || defined(DFBSD) /*returns pages*/ size = sizeof(total_count); if (sysctlbyname("vm.stats.vm.v_page_count", &total_count, &size, NULL, 0) < 0) { RETURN_WITH_SET_ERROR_WITH_ERRNO("mem", SG_ERROR_SYSCTLBYNAME, "vm.stats.vm.v_page_count"); } /*returns pages*/ size = sizeof(free_count); if (sysctlbyname("vm.stats.vm.v_free_count", &free_count, &size, NULL, 0) < 0) { RETURN_WITH_SET_ERROR_WITH_ERRNO("mem", SG_ERROR_SYSCTLBYNAME, "vm.stats.vm.v_free_count"); } size = sizeof(inactive_count); if (sysctlbyname("vm.stats.vm.v_inactive_count", &inactive_count , &size, NULL, 0) < 0) { RETURN_WITH_SET_ERROR_WITH_ERRNO("mem", SG_ERROR_SYSCTLBYNAME, "vm.stats.vm.v_inactive_count"); } size = sizeof(cache_count); if (sysctlbyname("vm.stats.vm.v_cache_count", &cache_count, &size, NULL, 0) < 0) { RETURN_WITH_SET_ERROR_WITH_ERRNO("mem", SG_ERROR_SYSCTLBYNAME, "vm.stats.vm.v_cache_count"); } /* Of couse nothing is ever that simple :) And I have inactive pages to * deal with too. So I'm going to add them to free memory :) */ mem_stats_buf->cache = (size_t)cache_count; mem_stats_buf->cache *= (size_t)sys_page_size; mem_stats_buf->total = (size_t)total_count; mem_stats_buf->total *= (size_t)sys_page_size; mem_stats_buf->free = (size_t)free_count + inactive_count + cache_count; mem_stats_buf->free *= (size_t)sys_page_size; mem_stats_buf->used = mem_stats_buf->total - mem_stats_buf->free; #elif defined(WIN32) memstats.dwLength = sizeof(memstats); if (!GlobalMemoryStatusEx(&memstats)) { RETURN_WITH_SET_ERROR_WITH_ERRNO("mem", SG_ERROR_MEMSTATUS, NULL); } mem_stats_buf->free = memstats.ullAvailPhys; mem_stats_buf->total = memstats.ullTotalPhys; mem_stats_buf->used = mem_stat.total - mem_stat.free; if(read_counter_large(SG_WIN32_MEM_CACHE, &mem_stats_buf->cache)) mem_stats_buf->cache = 0; #elif defined(HAVE_STRUCT_VMTOTAL) /* The code in this section is based on the code in the OpenBSD * top utility, located at src/usr.bin/top/machine.c in the * OpenBSD source tree. * * For fun, and like OpenBSD top, we will do the multiplication * converting the memory stats in pages to bytes in base 2. */ size = sizeof(vmtotal); if (sysctl(vmtotal_mib, 2, &vmtotal, &size, NULL, 0) < 0) { RETURN_WITH_SET_ERROR_WITH_ERRNO("mem", SG_ERROR_SYSCTLBYNAME, "vm.vmtotal"); } /* Convert the raw stats to bytes, and return these to the caller */ mem_stats_buf->used = (unsigned long long)vmtotal.t_rm; /* total real mem in use */ mem_stats_buf->used *= sys_page_size; /* XXX scan top source to look how it determines cache size */ mem_stats_buf->cache = 0; /* no cache stats */ mem_stats_buf->free = (unsigned long long)vmtotal.t_free; /* free memory pages */ mem_stats_buf->free *= sys_page_size; # ifdef HW_PHYSMEM mib[0] = CTL_HW; mib[1] = HW_PHYSMEM; size = sizeof(total_mem); if (sysctl(mib, 2, &total_mem, &size, NULL, 0) < 0) { RETURN_WITH_SET_ERROR_WITH_ERRNO("mem", SG_ERROR_SYSCTL, "CTL_HW.HW_PHYSMEM"); } mem_stats_buf->total = total_mem; # else mem_stats_buf->total = (mem_stats_buf->used + mem_stats_buf->free); # endif # ifdef HW_USERMEM mib[0] = CTL_HW; mib[1] = HW_USERMEM; size = sizeof(user_mem); if (sysctl(mib, 2, &user_mem, &size, NULL, 0) < 0) { RETURN_WITH_SET_ERROR_WITH_ERRNO("mem", SG_ERROR_SYSCTL, "CTL_HW.HW_USERMEM"); } mem_stats_buf->used += total_mem - user_mem; # endif #else RETURN_WITH_SET_ERROR("mem", SG_ERROR_UNSUPPORTED, OS_TYPE); #endif mem_stats_buf->systime = time(NULL); return SG_ERROR_NONE; }
size_t smf_get_freemem ( double *mbytes, size_t * pagesize, int64_t * physsize, int * status ) { int64_t mem_used = 0; int64_t mem_free = 0; int64_t mem_total = 0; double freembytes = 0.0; if (*status != SAI__OK) return mem_free; # if HAVE_MACH_VM { mach_port_t host_port; mach_msg_type_number_t host_size; vm_size_t vmpagesize; vm_statistics_data_t vm_stat; host_port = mach_host_self(); host_size = sizeof(vm_statistics_data_t) / sizeof(integer_t); host_page_size(host_port, &vmpagesize); if (pagesize) *pagesize = vmpagesize; if (host_statistics(host_port, HOST_VM_INFO, (host_info_t)&vm_stat, &host_size) == KERN_SUCCESS) { /* Stats in bytes */ mem_used = (vm_stat.active_count + vm_stat.inactive_count + vm_stat.wire_count) * vmpagesize; mem_free = vm_stat.free_count * vmpagesize; mem_total = mem_used + mem_free; } } #else #ifdef _SC_AVPHYS_PAGES /* Figure out available physical memory from sysconf */ { size_t mypagesize; mypagesize = sysconf(_SC_PAGE_SIZE); mem_free = sysconf(_SC_AVPHYS_PAGES) * mypagesize; mem_total = sysconf(_SC_PHYS_PAGES) * mypagesize; mem_used = mem_total - mem_free; if (pagesize) *pagesize = mypagesize; } #endif /* SC_AVPHYS_PAGES */ #endif /* MACH_VM */ if (mem_free > 0) { freembytes = (double) mem_free / (double)SMF__MIB; msgOutiff( MSG__DEBUG, "", "Free memory: %g MB Used Memory: %g MB Total Memory: %g MB", status, freembytes, (double)mem_used/(double)SMF__MIB, (double)mem_total/(double)SMF__MIB ); } else { msgOutif( MSG__DEBUG,"", "Unable to determine free memory", status ); } /* sort out return values */ if (mbytes) *mbytes = freembytes; if (physsize) *physsize = mem_total; return mem_free; }
static void quartzgen_begin_page(GVJ_t *job) { CGRect bounds = CGRectMake(0.0, 0.0, job->width, job->height); if (!job->context) { switch (job->device.id) { case FORMAT_PDF: { /* create the auxiliary info for PDF content, author and title */ CFStringRef auxiliaryKeys[] = { kCGPDFContextCreator, kCGPDFContextTitle }; CFStringRef auxiliaryValues[] = { CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%s %s"), job->common->info[0], job->common->info[1]), job->obj->type == ROOTGRAPH_OBJTYPE ? CFStringCreateWithBytesNoCopy(kCFAllocatorDefault, (const UInt8 *)job->obj->u.g->name, strlen(job->obj->u.g->name), kCFStringEncodingUTF8, false, kCFAllocatorNull) : CFSTR("") }; CFDictionaryRef auxiliaryInfo = CFDictionaryCreate( kCFAllocatorDefault, (const void **)&auxiliaryKeys, (const void **)&auxiliaryValues, sizeof(auxiliaryValues)/sizeof(auxiliaryValues[0]), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks ); /* create a PDF for drawing into */ CGDataConsumerRef data_consumer = CGDataConsumerCreate(job, &device_data_consumer_callbacks); job->context = CGPDFContextCreate(data_consumer, &bounds, auxiliaryInfo); /* clean up */ CGDataConsumerRelease(data_consumer); CFRelease(auxiliaryInfo); int i; for (i = 0; i < sizeof(auxiliaryValues)/sizeof(auxiliaryValues[0]); ++i) CFRelease(auxiliaryValues[i]); } break; default: /* bitmap formats */ { size_t bytes_per_row = (job->width * BYTES_PER_PIXEL + BYTE_ALIGN) & ~BYTE_ALIGN; void* buffer = NULL; #if __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ >= 20000 /* iPhoneOS has no swap files for memory, so if we're short of memory we need to make our own temp scratch file to back it */ size_t buffer_size = job->height * bytes_per_row; mach_msg_type_number_t vm_info_size = HOST_VM_INFO_COUNT; vm_statistics_data_t vm_info; if (host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t)&vm_info, &vm_info_size) != KERN_SUCCESS || buffer_size * 2 > vm_info.free_count * vm_page_size) { FILE* temp_file = tmpfile(); if (temp_file) { int temp_file_descriptor = fileno(temp_file); if (temp_file_descriptor >= 0 && ftruncate(temp_file_descriptor, buffer_size) == 0) { buffer = mmap( NULL, buffer_size, PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, temp_file_descriptor, 0); if (buffer == (void*)-1) buffer = NULL; } fclose(temp_file); } } if (!buffer) buffer = mmap( NULL, buffer_size, PROT_READ | PROT_WRITE, MAP_ANON| MAP_SHARED, -1, 0); #endif /* create a true color bitmap for drawing into */ CGColorSpaceRef color_space = CGColorSpaceCreateDeviceRGB(); job->context = CGBitmapContextCreate( buffer, /* data: MacOSX lets system allocate, iPhoneOS use manual memory mapping */ job->width, /* width in pixels */ job->height, /* height in pixels */ BITS_PER_COMPONENT, /* bits per component */ bytes_per_row, /* bytes per row: align to 16 byte boundary */ color_space, /* color space: device RGB */ kCGImageAlphaPremultipliedFirst /* bitmap info: premul ARGB has best support in OS X */ ); job->imagedata = CGBitmapContextGetData((CGContextRef)job->context); /* clean up */ CGColorSpaceRelease(color_space); } break; } } /* start the page (if this is a paged context) and graphics state */ CGContextRef context = (CGContextRef)job->context; CGContextBeginPage(context, &bounds); CGContextSaveGState(context); CGContextSetMiterLimit(context, 1.0); CGContextSetLineJoin(context, kCGLineJoinRound); /* set up the context transformation */ CGContextScaleCTM(context, job->scale.x, job->scale.y); CGContextRotateCTM(context, -job->rotation * M_PI / 180.0); CGContextTranslateCTM(context, job->translation.x, job->translation.y); }
int do_macos_mach_smi(int update_every, usec_t dt) { (void)dt; static int do_cpu = -1, do_ram = - 1, do_swapio = -1, do_pgfaults = -1; if (unlikely(do_cpu == -1)) { do_cpu = config_get_boolean("plugin:macos:mach_smi", "cpu utilization", 1); do_ram = config_get_boolean("plugin:macos:mach_smi", "system ram", 1); do_swapio = config_get_boolean("plugin:macos:mach_smi", "swap i/o", 1); do_pgfaults = config_get_boolean("plugin:macos:mach_smi", "memory page faults", 1); } RRDSET *st; kern_return_t kr; mach_msg_type_number_t count; host_t host; vm_size_t system_pagesize; // NEEDED BY: do_cpu natural_t cp_time[CPU_STATE_MAX]; // NEEDED BY: do_ram, do_swapio, do_pgfaults vm_statistics64_data_t vm_statistics; host = mach_host_self(); kr = host_page_size(host, &system_pagesize); if (unlikely(kr != KERN_SUCCESS)) return -1; // -------------------------------------------------------------------- if (likely(do_cpu)) { if (unlikely(HOST_CPU_LOAD_INFO_COUNT != 4)) { error("MACOS: There are %d CPU states (4 was expected)", HOST_CPU_LOAD_INFO_COUNT); do_cpu = 0; error("DISABLED: system.cpu"); } else { count = HOST_CPU_LOAD_INFO_COUNT; kr = host_statistics(host, HOST_CPU_LOAD_INFO, (host_info_t)cp_time, &count); if (unlikely(kr != KERN_SUCCESS)) { error("MACOS: host_statistics() failed: %s", mach_error_string(kr)); do_cpu = 0; error("DISABLED: system.cpu"); } else { st = rrdset_find_bytype("system", "cpu"); if (unlikely(!st)) { st = rrdset_create("system", "cpu", NULL, "cpu", "system.cpu", "Total CPU utilization", "percentage", 100, update_every, RRDSET_TYPE_STACKED); rrddim_add(st, "user", NULL, 1, 1, RRDDIM_PCENT_OVER_DIFF_TOTAL); rrddim_add(st, "nice", NULL, 1, 1, RRDDIM_PCENT_OVER_DIFF_TOTAL); rrddim_add(st, "system", NULL, 1, 1, RRDDIM_PCENT_OVER_DIFF_TOTAL); rrddim_add(st, "idle", NULL, 1, 1, RRDDIM_PCENT_OVER_DIFF_TOTAL); rrddim_hide(st, "idle"); } else rrdset_next(st); rrddim_set(st, "user", cp_time[CPU_STATE_USER]); rrddim_set(st, "nice", cp_time[CPU_STATE_NICE]); rrddim_set(st, "system", cp_time[CPU_STATE_SYSTEM]); rrddim_set(st, "idle", cp_time[CPU_STATE_IDLE]); rrdset_done(st); } } } // -------------------------------------------------------------------- if (likely(do_ram || do_swapio || do_pgfaults)) { count = sizeof(vm_statistics64_data_t); kr = host_statistics64(host, HOST_VM_INFO64, (host_info64_t)&vm_statistics, &count); if (unlikely(kr != KERN_SUCCESS)) { error("MACOS: host_statistics64() failed: %s", mach_error_string(kr)); do_ram = 0; error("DISABLED: system.ram"); do_swapio = 0; error("DISABLED: system.swapio"); do_pgfaults = 0; error("DISABLED: mem.pgfaults"); } else { if (likely(do_ram)) { st = rrdset_find("system.ram"); if (unlikely(!st)) { st = rrdset_create("system", "ram", NULL, "ram", NULL, "System RAM", "MB", 200, update_every, RRDSET_TYPE_STACKED); rrddim_add(st, "active", NULL, system_pagesize, 1048576, RRDDIM_ABSOLUTE); rrddim_add(st, "wired", NULL, system_pagesize, 1048576, RRDDIM_ABSOLUTE); rrddim_add(st, "throttled", NULL, system_pagesize, 1048576, RRDDIM_ABSOLUTE); rrddim_add(st, "compressor", NULL, system_pagesize, 1048576, RRDDIM_ABSOLUTE); rrddim_add(st, "inactive", NULL, system_pagesize, 1048576, RRDDIM_ABSOLUTE); rrddim_add(st, "purgeable", NULL, system_pagesize, 1048576, RRDDIM_ABSOLUTE); rrddim_add(st, "speculative", NULL, system_pagesize, 1048576, RRDDIM_ABSOLUTE); rrddim_add(st, "free", NULL, system_pagesize, 1048576, RRDDIM_ABSOLUTE); } else rrdset_next(st); rrddim_set(st, "active", vm_statistics.active_count); rrddim_set(st, "wired", vm_statistics.wire_count); rrddim_set(st, "throttled", vm_statistics.throttled_count); rrddim_set(st, "compressor", vm_statistics.compressor_page_count); rrddim_set(st, "inactive", vm_statistics.inactive_count); rrddim_set(st, "purgeable", vm_statistics.purgeable_count); rrddim_set(st, "speculative", vm_statistics.speculative_count); rrddim_set(st, "free", (vm_statistics.free_count - vm_statistics.speculative_count)); rrdset_done(st); } // -------------------------------------------------------------------- if (likely(do_swapio)) { st = rrdset_find("system.swapio"); if (unlikely(!st)) { st = rrdset_create("system", "swapio", NULL, "swap", NULL, "Swap I/O", "kilobytes/s", 250, update_every, RRDSET_TYPE_AREA); rrddim_add(st, "in", NULL, system_pagesize, 1024, RRDDIM_INCREMENTAL); rrddim_add(st, "out", NULL, -system_pagesize, 1024, RRDDIM_INCREMENTAL); } else rrdset_next(st); rrddim_set(st, "in", vm_statistics.swapins); rrddim_set(st, "out", vm_statistics.swapouts); rrdset_done(st); } // -------------------------------------------------------------------- if (likely(do_pgfaults)) { st = rrdset_find("mem.pgfaults"); if (unlikely(!st)) { st = rrdset_create("mem", "pgfaults", NULL, "system", NULL, "Memory Page Faults", "page faults/s", 500, update_every, RRDSET_TYPE_LINE); st->isdetail = 1; rrddim_add(st, "memory", NULL, 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "cow", NULL, 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "pagein", NULL, 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "pageout", NULL, 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "compress", NULL, 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "decompress", NULL, 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "zero_fill", NULL, 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "reactivate", NULL, 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "purge", NULL, 1, 1, RRDDIM_INCREMENTAL); } else rrdset_next(st); rrddim_set(st, "memory", vm_statistics.faults); rrddim_set(st, "cow", vm_statistics.cow_faults); rrddim_set(st, "pagein", vm_statistics.pageins); rrddim_set(st, "pageout", vm_statistics.pageouts); rrddim_set(st, "compress", vm_statistics.compressions); rrddim_set(st, "decompress", vm_statistics.decompressions); rrddim_set(st, "zero_fill", vm_statistics.zero_fill_count); rrddim_set(st, "reactivate", vm_statistics.reactivations); rrddim_set(st, "purge", vm_statistics.purges); rrdset_done(st); } } } // -------------------------------------------------------------------- return 0; }