Exemplo n.º 1
0
/*===========================================================================*
 *				printmemstats				     *
 *===========================================================================*/
void printmemstats(void)
{
	int nodes, pages, largest;
        memstats(&nodes, &pages, &largest);
        printf("%d blocks, %d pages (%lukB) free, largest %d pages (%lukB)\n",
                nodes, pages, (unsigned long) pages * (VM_PAGE_SIZE/1024),
		largest, (unsigned long) largest * (VM_PAGE_SIZE/1024));
}
/*===========================================================================*
 *                              do_info                                      *
 *===========================================================================*/
int do_info(message *m)
{
	struct vm_stats_info vsi;
	struct vm_usage_info vui;
	static struct vm_region_info vri[MAX_VRI_COUNT];
	struct vmproc *vmp;
	vir_bytes addr, size, next, ptr;
	int r, pr, dummy, count, free_pages, largest_contig;

	if (vm_isokendpt(m->m_source, &pr) != OK)
		return EINVAL;
	vmp = &vmproc[pr];

	ptr = (vir_bytes) m->m_lsys_vm_info.ptr;

	switch(m->m_lsys_vm_info.what) {
	case VMIW_STATS:
		vsi.vsi_pagesize = VM_PAGE_SIZE;
		vsi.vsi_total = total_pages;
		memstats(&dummy, &free_pages, &largest_contig);
		vsi.vsi_free = free_pages;
		vsi.vsi_largest = largest_contig;

		get_stats_info(&vsi);

		addr = (vir_bytes) &vsi;
		size = sizeof(vsi);

		break;

	case VMIW_USAGE:
		if(m->m_lsys_vm_info.ep < 0)
			get_usage_info_kernel(&vui);
		else if (vm_isokendpt(m->m_lsys_vm_info.ep, &pr) != OK)
			return EINVAL;
		else get_usage_info(&vmproc[pr], &vui);

		addr = (vir_bytes) &vui;
		size = sizeof(vui);

		break;

	case VMIW_REGION:
		if(m->m_lsys_vm_info.ep == SELF) {
			m->m_lsys_vm_info.ep = m->m_source;
		}
		if (vm_isokendpt(m->m_lsys_vm_info.ep, &pr) != OK)
			return EINVAL;

		count = MIN(m->m_lsys_vm_info.count, MAX_VRI_COUNT);
		next = m->m_lsys_vm_info.next;

		count = get_region_info(&vmproc[pr], vri, count, &next);

		m->m_lsys_vm_info.count = count;
		m->m_lsys_vm_info.next = next;

		addr = (vir_bytes) vri;
		size = sizeof(vri[0]) * count;

		break;

	default:
		return EINVAL;
	}

	if (size == 0)
		return OK;

	/* Make sure that no page faults can occur while copying out. A page
	 * fault would cause the kernel to send a notify to us, while we would
	 * be waiting for the result of the copy system call, resulting in a
	 * deadlock. Note that no memory mapping can be undone without the
	 * involvement of VM, so we are safe until we're done.
	 */
	r = handle_memory_once(vmp, ptr, size, 1 /*wrflag*/);
	if (r != OK) return r;

	/* Now that we know the copy out will succeed, perform the actual copy
	 * operation.
	 */
	return sys_datacopy(SELF, addr,
		(vir_bytes) vmp->vm_endpoint, ptr, size);
}
Exemplo n.º 3
0
int main(int argc, char** argv) {
    bool cpu_stats = false;
    bool mem_stats = false;
    zx_duration_t delay = ZX_SEC(1);
    int num_loops = -1;
    bool timestamp = false;

    int c;
    while ((c = getopt(argc, argv, "cd:n:hmt")) > 0) {
        switch (c) {
            case 'c':
                cpu_stats = true;
                break;
            case 'd':
                delay = ZX_SEC(atoi(optarg));
                if (delay == 0) {
                    fprintf(stderr, "Bad -d value '%s'\n", optarg);
                    print_help(stderr);
                    return 1;
                }
                break;
            case 'n':
                num_loops = atoi(optarg);
                if (num_loops == 0) {
                    fprintf(stderr, "Bad -n value '%s'\n", optarg);
                    print_help(stderr);
                    return 1;
                }
                break;
            case 'h':
                print_help(stdout);
                return 0;
            case 'm':
                mem_stats = true;
                break;
            case 't':
                timestamp = true;
                break;
            default:
                fprintf(stderr, "Unknown option\n");
                print_help(stderr);
                return 1;
        }
    }

    if (!cpu_stats && !mem_stats) {
        fprintf(stderr, "No statistics selected\n");
        print_help(stderr);
        return 1;
    }

    zx_handle_t root_resource;
    zx_status_t ret = get_root_resource(&root_resource);
    if (ret != ZX_OK) {
        return ret;
    }

    // set stdin to non blocking so we can intercept ctrl-c.
    // TODO: remove once ctrl-c works in the shell
    fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK);

    for (;;) {
        zx_time_t next_deadline = zx_deadline_after(delay);

        // Print the current UTC time with milliseconds as
        // an ISO 8601 string.
        if (timestamp) {
            struct timespec now;
            timespec_get(&now, TIME_UTC);
            struct tm nowtm;
            gmtime_r(&now.tv_sec, &nowtm);
            char tbuf[40];
            strftime(tbuf, sizeof(tbuf), "%FT%T", &nowtm);
            printf("\n--- %s.%03ldZ ---\n", tbuf, now.tv_nsec / (1000 * 1000));
        }

        if (cpu_stats) {
            ret |= cpustats(root_resource, delay);
        }
        if (mem_stats) {
            ret |= memstats(root_resource);
        }

        if (ret != ZX_OK)
            break;

        if (num_loops > 0) {
            if (--num_loops == 0) {
                break;
            }
        } else {
            // TODO: replace once ctrl-c works in the shell
            char c;
            int err;
            while ((err = read(STDIN_FILENO, &c, 1)) > 0) {
                if (c == 0x3)
                    return 0;
            }
        }

        zx_nanosleep(next_deadline);
    }

    zx_handle_close(root_resource);

    return ret;
}