void *_sbrk(ptrdiff_t increment)
{
	extern char _end;
	static char *heap_end = 0;
	char *prev_heap_end;
	char register *stack_ptr asm("sp");

	if (heap_end == 0) {
		heap_end = &_end;
	}
	prev_heap_end = heap_end;
	if ((heap_end + increment) > stack_ptr) {
		PUTS("sp=");
		PUTP(stack_ptr);
		PUTS("\n");
		PUTS("heap=");
		PUTP(heap_end);
		PUTS("\n");
		PUTS("sbrk: no more heap\n");
		errno = ENOMEM;
		return (void*)-1;
	}
	heap_end += increment;
	return prev_heap_end;
}
Example #2
0
/*
 * Reads the memory info and displays it.  Returns the total memory
 * available, for use in percent memory usage calculations.
 */
unsigned show_meminfo(void)
{
    unsigned long long **mem = get_meminfo();	/* read+parse /proc/meminfo */
    
    if (!mem ||	mem[meminfo_main][meminfo_total] == 0) {	/* cannot normalize mem usage */
	fprintf(stderr, "Cannot get size of memory from /proc/meminfo\n");
	error_end(1);
    }
    if (show_memory) {
	printf("Mem:  %7LdK av, %7LdK used, %7LdK free, %7LdK shrd, %7LdK buff",
	       mem[meminfo_main][meminfo_total] >> 10,
	       mem[meminfo_main][meminfo_used] >> 10,
	       mem[meminfo_main][meminfo_free] >> 10,
	       mem[meminfo_main][meminfo_shared] >> 10,
	       mem[meminfo_main][meminfo_buffers] >> 10);
	PUTP(top_clrtoeol);
	putchar('\n');
	printf("Swap: %7LdK av, %7LdK used, %7LdK free                 %7LdK cached",
	       mem[meminfo_swap][meminfo_total] >> 10,
	       mem[meminfo_swap][meminfo_used] >> 10,
	       mem[meminfo_swap][meminfo_free] >> 10,
	       mem[meminfo_total][meminfo_cached] >> 10);
	PUTP(top_clrtoeol);
	putchar('\n');
    }
    PUTP(me);
    PUTP(top_clrtoeol);
    putchar('\n');
    return mem[meminfo_main][meminfo_total] >> 10;
}
Example #3
0
        /*
	 * Display the specification line of all fields. Upper case indicates
	 * a displayed field, display order is according to the order of the 
	 * letters. A short description of each field is shown as well.
	 * The description of a displayed field is marked by a leading 
	 * asterisk (*).
	 */
void show_fields(void)
{
    int i, row, col;
    char *p;

    clear_screen();
    PUTP(tgoto(cm, 3, 0));
    printf("Current Field Order: %s\n", Fields);
    for (i = 0; i < sizeof headers / sizeof headers[0]; ++i) {
	row = i % (Lines - 3) + 3;
	col = i / (Lines - 3) * 40;
	PUTP(tgoto(cm, col, row));
	for (p = headers[i]; *p == ' '; ++p);
	printf("%c %c: %-10s = %s", (strchr(Fields, i + 'A') != NULL) ? '*' : ' ', i + 'A',
	       p, headers2[i]);
    }
}
Example #4
0
File: mm.c Project: horf31/ece454
/**********************************************************
 * delete_from_list
 * Place the free block ptr bp on the appropriated
 * segregated free list
 * Insert at the first element of the list
 **********************************************************/
void delete_from_list(void *bp) {
	// If the block is allocated, cannot be freed
	if (GET_ALLOC(HDRP(bp))) {
		return;
	}

	// If it does not have next element
	if (*(char*) bp == 0) {
		// Set previous block ptr in the previous element to 0
		PUT(PREVB(bp), 0);
	} else { // If it has next element
		// Set next block ptr in the prev element to current's next element
		PUTP(PREVB(bp), NEXTB(bp));
		// Set prev block ptr in the next element to current's prev element
		PUTP(PREVP(NEXTB(bp)), PREVB(bp));
	}
}
Example #5
0
/*
	 * Normal end of execution.
	 */
void sig_end(int signo)
{
    if (psdbsucc)
	close_psdb();
    if (!Batch)
	tcsetattr(0, TCSAFLUSH, &Savetty);
    PUTP(tgoto(cm, 0, Lines - 1));
    fputs("\r\n", stdout);
    exit(0);
}
Example #6
0
File: mm.c Project: horf31/ece454
/**********************************************************
 * insert_freelist
 * Place the free block ptr bp on the appropriated
 * segregated free list
 * Insert at the first element of the list
 **********************************************************/
void insert_freelist(intptr_t * bp) {
	// Find out which list should the free block insert to
	int index = size_to_index(GET_SIZE(HDRP(bp)));

	// Head of the list
	intptr_t * listp = seg_free_list[index];

	// Set the prev_ptr and next_ptr of the current block
	PUT(bp, GET(seg_free_list[index]));	// next
	PUTP(PREVP(bp), listp);             // prev

	// If the list previously has elements inside
	if (GET(listp) != 0) {
		// Set the next element to point to the current bp
		PUTP(PREVP(*listp), bp);
	}
	//Set head to point to the current bp
	PUTP(listp, bp);
}
Example #7
0
/*
	 * SIGTSTP catcher.
	 */
void sig_stop(int signo)
{
    /* Reset terminal. */
    if (!Batch)
	tcsetattr(0, TCSAFLUSH, &Savetty);
    PUTP(tgoto(cm, 0, Lines - 3));
    fflush(stdout);
    raise(SIGSTOP);
    /* Later... */
    if (!Batch)
	tcsetattr (0, TCSAFLUSH, &Rawtty);
}
Example #8
0
/*
	 * toggle displayed fields
	 */
void change_fields(void)
{
    int i, changed = 0;
    int row, col;
    char c, *p;
    char tmp[2] = " ";

    show_fields();
    for (;;) {
	PUTP(tgoto(cm, 0, 0));
	PUTP(top_clrtoeol);
	PUTP(tgoto(cm, 3, 0));
	PUTP(mr);
	printf("Current Field Order: %s", Fields);
	PUTP(me);
	putchar('\n');
	PUTP(tgoto(cm, 0, 1));
	printf("Toggle fields with a-x, any other key to return: ");
	fflush(stdout);
	if (!Batch) { /* should always be true, but... */
	    tcsetattr(0, TCSAFLUSH, &Rawtty);
	    read(0, &c, 1);
	    tcsetattr(0, TCSAFLUSH, &Savetty);
	}
	i = toupper(c) - 'A';
	if (i >= 0 && i < sizeof headers / sizeof headers[0]) {
	    row = i % (Lines - 3) + 3;
	    col = i / (Lines - 3) * 40;
	    PUTP(tgoto(cm, col, row));
	    if ((p = strchr(Fields, i + 'A')) != NULL) {	/* deselect Field */
		*p = i + 'a';
		putchar(' ');
	    } else if ((p = strchr(Fields, i + 'a')) != NULL) {		/* select previously */
		*p = i + 'A';	/* deselected field */
		putchar('*');
	    } else {		/* select new field */
		tmp[0] = i + 'A';
		strcat(Fields, tmp);
		putchar('*');
	    }
	    changed = 1;
	    fflush(stdout);
	} else
	    break;
    }
    if (changed)
	Numfields = make_header();
}
Example #9
0
/*
	 * change order of displayed fields
	 */
void change_order(void)
{
    char c, ch, *p;
    int i;

    show_fields();
    for (;;) {
	PUTP(tgoto(cm, 0, 0));
	PUTP(top_clrtoeol);
	PUTP(tgoto(cm, 3, 0));
	PUTP(mr);
	printf("Current Field Order: %s", Fields);
	PUTP(me);
	putchar('\n');
	PUTP(tgoto(cm, 0, 1));
	printf("Upper case characters move a field to the left, lower case to the right");
	fflush(stdout);
	if (!Batch) { /* should always be true, but... */
	    tcsetattr(0, TCSAFLUSH, &Rawtty);
	    read(0, &c, 1);
	    tcsetattr(0, TCSAFLUSH, &Savetty);
	}
	i = toupper(c) - 'A';
	if ((p = strchr(Fields, i + 'A')) != NULL) {
	    if (isupper(c))
		p--;
	    if ((p[1] != '\0') && (p >= Fields)) {
		ch = p[0];
		p[0] = p[1];
		p[1] = ch;
	    }
	} else if ((p = strchr(Fields, i + 'a')) != NULL) {
	    if (isupper(c))
		p--;
	    if ((p[1] != '\0') && (p >= Fields)) {
		ch = p[0];
		p[0] = p[1];
		p[1] = ch;
	    }
	} else {
	    break;
	}
    }
    Numfields = make_header();
}
Example #10
0
/*
 * Process keyboard input during the main loop
 */
void do_key(char c)
{
    int numinput, i;
    char rcfile[MAXNAMELEN];
    FILE *fp;

    /*
     * First the commands which don't require a terminal mode switch.
     */
    if (c == 'q')
	sig_end(0);
    else if (c == ' ')
        return;
    else if (c == 12) {
	clear_screen();
	return;
    } else if (c == 'I') {
	Irixmode=(Irixmode) ? 0 : 1;
	return;
    }

    /*
     * Switch the terminal to normal mode.  (Will the original
     * attributes always be normal?  Does it matter?  I suppose the
     * shell will be set up the way the user wants it.)
     */
    if (!Batch) tcsetattr(0, TCSANOW, &Savetty);

    /*
     * Handle the rest of the commands.
     */
    switch (c) {
      case '?':
      case 'h':
	PUTP(cl); PUTP(ho); putchar('\n'); PUTP(mr);
	printf("Proc-Top Revision 1.2");
	PUTP(me); putchar('\n');
	printf("Secure mode ");
	PUTP(md);
	fputs(Secure ? "on" : "off", stdout);
	PUTP(me);
	fputs("; cumulative mode ", stdout);
	PUTP(md);
	fputs(Cumulative ? "on" : "off", stdout);
	PUTP(me);
	fputs("; noidle mode ", stdout);
	PUTP(md);
	fputs(Noidle ? "on" : "off", stdout);
	PUTP(me);
	fputs("\n\n", stdout);
	printf("%s\n\nPress any key to continue", Secure ? SECURE_HELP_SCREEN : HELP_SCREEN);
	if (!Batch) tcsetattr(0, TCSANOW, &Rawtty);
	(void) getchar();
	break;
      case 'i':
	Noidle = !Noidle;
	SHOWMESSAGE(("No-idle mode %s", Noidle ? "on" : "off"));
	break;
      case 'u':
	SHOWMESSAGE(("Which User (Blank for All): "));
	strcpy(CurrUser,getstr());
	break;
      case 'k':
	if (Secure)
	    SHOWMESSAGE(("\aCan't kill in secure mode"));
	else {
	    int pid, signal;
	    PUTP(md);
	    SHOWMESSAGE(("PID to kill: "));
	    pid = getint();
	    if (pid == BAD_INPUT)
		break;
	    PUTP(top_clrtoeol);
	    SHOWMESSAGE(("Kill PID %d with signal [15]: ", pid));
	    PUTP(me);
	    signal = getsig();
	    if (signal == -1)
		signal = SIGTERM;
	    if (kill(pid, signal))
		SHOWMESSAGE(("\aKill of PID %d with %d failed: %s",
			     pid, signal, strerror(errno)));
	}
	break;
      case 'l':
	SHOWMESSAGE(("Display load average %s", !show_loadav ? "on" : "off"));
	if (show_loadav) {
	    show_loadav = 0;
	    header_lines--;
	} else {
	    show_loadav = 1;
	    header_lines++;
	}
	Numfields = make_header();
	break;
      case 'm':
	SHOWMESSAGE(("Display memory information %s", !show_memory ? "on" : "off"));
	if (show_memory) {
	    show_memory = 0;
	    header_lines -= 2;
	} else {
	    show_memory = 1;
	    header_lines += 2;
	}
	Numfields = make_header();
	break;
      case 'M':
        SHOWMESSAGE(("Sort by memory usage"));
	sort_type = S_MEM;
	reset_sort_options();
	register_sort_function(-1, (cmp_t)mem_sort);
	break;
      case 'n':
      case '#':
	printf("Processes to display (0 for unlimited): ");
	numinput = getint();
	if (numinput != BAD_INPUT) {
	    Display_procs = numinput;
	    window_size(0);
	}
	break;
      case 'r':
	if (Secure)
	    SHOWMESSAGE(("\aCan't renice in secure mode"));
	else {
	    int pid, val;

	    printf("PID to renice: ");
	    pid = getint();
	    if (pid == BAD_INPUT)
		break;
	    PUTP(tgoto(cm, 0, header_lines - 2));
	    PUTP(top_clrtoeol);
	    printf("Renice PID %d to value: ", pid);
	    val = getint();
	    if (val == BAD_INPUT)
		val = 10;
	    if (setpriority(PRIO_PROCESS, pid, val))
		SHOWMESSAGE(("\aRenice of PID %d to %d failed: %s",
			     pid, val, strerror(errno)));
	}
	break;
      case 'P':
        SHOWMESSAGE(("Sort by CPU usage"));
	sort_type = S_PCPU;
	reset_sort_options();
	register_sort_function(-1, (cmp_t)pcpu_sort);
	break;
      case 'A':
	SHOWMESSAGE(("Sort by age"));
	sort_type = S_AGE;
	reset_sort_options();
	register_sort_function(-1, (cmp_t)age_sort);
	break;
      case 'N':
	SHOWMESSAGE(("Sort numerically by pid"));
	sort_type = S_NONE;
	reset_sort_options();
	break;
    case 'c':
        show_cmd = !show_cmd;
	SHOWMESSAGE(("Show %s", show_cmd ? "command names" : "command line"));
	break;
      case 'S':
	Cumulative = !Cumulative;
	SHOWMESSAGE(("Cumulative mode %s", Cumulative ? "on" : "off"));
	if (Cumulative)
	    headers[22][1] = 'C';
	else
	    headers[22][1] = ' ';
	Numfields = make_header();
	break;
      case 's':
	if (Secure)
	    SHOWMESSAGE(("\aCan't change delay in secure mode"));
	else {
	    double tmp;
	    printf("Delay between updates: ");
	    tmp = getfloat();
	    if (!(tmp < 0))
		Sleeptime = tmp;
	}
	break;
      case 't':
	SHOWMESSAGE(("Display summary information %s", !show_stats ? "on" : "off"));
	if (show_stats) {
	    show_stats = 0;
	    header_lines -= 2;
	} else {
	    show_stats = 1;
	    header_lines += 2;
	}
	Numfields = make_header();
	break;
      case 'T':
	SHOWMESSAGE(("Sort by %stime", Cumulative ? "cumulative " : ""));
	sort_type = S_TIME;
	reset_sort_options();
	register_sort_function( -1, (cmp_t)time_sort);	
	break;
      case 'f':
      case 'F':
	change_fields();
	break;
      case 'o':
      case 'O':
	change_order();
	break;
      case 'W':
	if (getenv("HOME")) {
	    strcpy(rcfile, getenv("HOME"));
	    strcat(rcfile, "/");
	    strcat(rcfile, RCFILE);
	    fp = fopen(rcfile, "w");
	    if (fp != NULL) {
		fprintf(fp, "%s\n", Fields);
		i = (int) Sleeptime;
		if (i < 2)
		    i = 2;
		if (i > 9)
		    i = 9;
		fprintf(fp, "%d", i);
		if (Secure)
		    fprintf(fp, "%c", 's');
		if (Cumulative)
		    fprintf(fp, "%c", 'S');
		if (!show_cmd)
		    fprintf(fp, "%c", 'c');
		if (Noidle)
		    fprintf(fp, "%c", 'i');
		if (!show_memory)
		    fprintf(fp, "%c", 'm');
		if (!show_loadav)
		    fprintf(fp, "%c", 'l');
		if (!show_stats)
		    fprintf(fp, "%c", 't');
		if (!Irixmode)
		    fprintf(fp, "%c", 'I');
		fprintf(fp, "\n");
		fclose(fp);
		SHOWMESSAGE(("Wrote configuration to %s", rcfile));
	    } else {
		SHOWMESSAGE(("Couldn't open %s", rcfile));
	    }
	} else {
	    SHOWMESSAGE(("Couldn't get $HOME -- not saving"));
	}
	break;
      default:
	SHOWMESSAGE(("\aUnknown command `%c' -- hit `h' for help", c));
    }

    /*
     * Return to raw mode.
     */
    if (!Batch) tcsetattr(0, TCSANOW, &Rawtty);
    return;
}
Example #11
0
/*
 * Calculates the number of tasks in each state (running, sleeping, etc.).
 * Calculates the CPU time in each state (system, user, nice, etc).
 * Calculates percent cpu usage for each task.
 */
void do_stats(proc_t** p, float elapsed_time, int pass)
{
    proc_t *this;
    int index, total_time, cpumap, i, n = 0;
    int sleeping = 0, stopped = 0, zombie = 0, running = 0;
    unsigned long system_ticks = 0, user_ticks = 0, nice_ticks = 0, idle_ticks;
    static int prev_count = 0;
    int stime, utime;

    /* start with one 4K page as a reasonable allocate size */
    static int save_history_size = sizeof(struct save_hist) * 204;
    static struct save_hist *save_history;
    struct save_hist *New_save_hist;
    static int *s_ticks_o = NULL, *u_ticks_o = NULL,
               *n_ticks_o = NULL, *i_ticks_o = NULL;
    int s_ticks, u_ticks, n_ticks, i_ticks, t_ticks;
    char str[128];
    FILE *file;


    if (!save_history)
	save_history = xcalloc(NULL, save_history_size);
    New_save_hist = xcalloc(NULL, save_history_size);

    if(s_ticks_o == NULL) {
      s_ticks_o = (int *)malloc(nr_cpu * sizeof(int));
      u_ticks_o = (int *)malloc(nr_cpu * sizeof(int));
      n_ticks_o = (int *)malloc(nr_cpu * sizeof(int));
      i_ticks_o = (int *)malloc(nr_cpu * sizeof(int));
    }
    idle_ticks = 1000 * nr_cpu;

    /*
     * Make a pass through the data to get stats.
     */
    index = 0;
    while (p[n]->pid != -1) {
	this = p[n];
	switch (this->state) {
	  case 'S':
	  case 'D':
	    sleeping++;
	    break;
	  case 'T':
	    stopped++;
	    break;
	  case 'Z':
	    zombie++;
	    break;
	  case 'R':
	    running++;
	    break;
	  default:
	    /* Don't know how to handle this one. */
	    break;
        }

	/*
	 * Calculate time in this process.  Time is sum of user time
	 * (utime) plus system time (stime).
	 */
	total_time = this->utime + this->stime;
	if (index * sizeof(struct save_hist) >= save_history_size) {
	    save_history_size *= 2;
	    save_history = xrealloc(save_history, save_history_size);
	    New_save_hist = xrealloc(New_save_hist, save_history_size);
	}
	New_save_hist[index].ticks = total_time;
	New_save_hist[index].pid = this->pid;
	stime = this->stime;
	utime = this->utime;
	New_save_hist[index].stime = stime;
	New_save_hist[index].utime = utime;

	/* find matching entry from previous pass */
	for (i = 0; i < prev_count; i++) {
	    if (save_history[i].pid == this->pid) {
		total_time -= save_history[i].ticks;
		stime -= save_history[i].stime;
		utime -= save_history[i].utime;

		i = prev_count;
	    }
	}

	/*
	 * Calculate percent cpu time for this task.
	 */
	this->pcpu = (total_time * 10 * 100/Hertz) / elapsed_time;
	if (this->pcpu > 999)
	    this->pcpu = 999;

	/*
	 * Calculate time in idle, system, user and niced tasks.
	 */
	idle_ticks -= this->pcpu;
	system_ticks += stime;
	user_ticks += utime;
	if (this->nice > 0)
	    nice_ticks += this->pcpu;

	/*
	 * If in Sun-mode, adjust cpu percentage not only for
	 * the cpu the process is running on, but for all cpu together.
	 */
	if(!Irixmode) {
	  this->pcpu /= nr_cpu;
	  }
	
	index++;
	n++;
    }

    if (idle_ticks < 0)
	idle_ticks = 0;
    system_ticks = (system_ticks * 10 * 100/Hertz) / elapsed_time;
    user_ticks = (user_ticks * 10 * 100/Hertz) / elapsed_time;

    /*
     * Display stats.
     */
    if (pass > 0 && show_stats) {
	printf("%d processes: %d sleeping, %d running, %d zombie, "
	       "%d stopped",
	       n, sleeping, running, zombie, stopped);
	PUTP(top_clrtoeol);
	putchar('\n');
	if (nr_cpu == 1 || CPU_states) {
	  /* BEGIN EXPERIMENTAL CODE */
	  /* Throw out the calculation above... TODO: remove calculation. */
	  four_cpu_numbers(&user_ticks,&nice_ticks,&system_ticks,&idle_ticks);
	  do{
	    unsigned long sum;
	    sum = user_ticks+nice_ticks+system_ticks+idle_ticks;
	    user_ticks   = (user_ticks   * 1000) / sum;
	    system_ticks = (system_ticks * 1000) / sum;
	    nice_ticks   = (nice_ticks   * 1000) / sum;
	    idle_ticks   = (idle_ticks   * 1000) / sum;
	  }while(0);
	  /* END EXPERIMENTAL CODE */
	  if (Irixmode) {
	    user_ticks *= nr_cpu;
	    system_ticks *= nr_cpu;
	    nice_ticks *= nr_cpu;
	    idle_ticks *= nr_cpu;
	  }
	  printf("CPU states:"
		 " %2ld.%ld%% user, %2ld.%ld%% system,"
		 " %2ld.%ld%% nice, %2ld.%ld%% idle",
		 user_ticks / 10UL, user_ticks % 10UL,
		 system_ticks / 10UL, system_ticks % 10UL,
		 nice_ticks / 10UL, nice_ticks % 10UL,
		 idle_ticks / 10UL, idle_ticks % 10UL);
	  PUTP(top_clrtoeol);
	  putchar('\n');
	}
	/*
         * Calculate stats for all cpus
         */
	if(nr_cpu > 1) {
	  file = fopen("/proc/stat", "r");
	  if(file == NULL) {
	    fprintf(stderr, "fopen failed on /proc/stat\n");
	  }
	  else {
	    /* Skip the total CPU states. */
	    if(fgets(str, 128, file) == NULL) {
	      fprintf(stderr, "fgets failed on /proc/stat\n");
	    }
	    else {
	      for(i = 0; i < nr_cpu; i++) {
		if(fscanf(file, "cpu%*d %d %d %d %d\n",
			  &u_ticks, &n_ticks, &s_ticks, &i_ticks) != 4) {
		  fprintf(stderr, "fscanf failed on /proc/stat for cpu %d\n", i);
		  break;
		}
		else  {
		  t_ticks = (u_ticks + s_ticks + i_ticks + n_ticks)
		  	    - (u_ticks_o[i] + s_ticks_o[i]
			       + i_ticks_o[i] + n_ticks_o[i]);
		  if (Irixmode) cpumap=i;
		  else cpumap=cpu_mapping[i];
		  printf ("CPU%d states: %2d.%-d%% user, %2d.%-d%% system,"
			  " %2d.%-d%% nice, %2d.%-d%% idle",
			  cpumap,
			  (u_ticks - u_ticks_o[i] + n_ticks - n_ticks_o[i]) * 100 / t_ticks,
			  (u_ticks - u_ticks_o[i]) * 100 % t_ticks / 100,
			  (s_ticks - s_ticks_o[i]) * 100 / t_ticks,
			  (s_ticks - s_ticks_o[i]) * 100 % t_ticks / 100,
			  (n_ticks - n_ticks_o[i]) * 100 / t_ticks,
			  (n_ticks - n_ticks_o[i]) * 100 % t_ticks / 100,
			  (i_ticks - i_ticks_o[i]) * 100 / t_ticks,
			  (i_ticks - i_ticks_o[i]) * 100 % t_ticks / 100);
		  s_ticks_o[i] = s_ticks;
		  u_ticks_o[i] = u_ticks;
		  n_ticks_o[i] = n_ticks;
		  i_ticks_o[i] = i_ticks;
		  PUTP (top_clrtoeol);
		  putchar ('\n');
		}
	      }
	    }
	    fclose(file);
	  }
	}
    } else {
      /*
       * During the first pass, get the information for the
       * different CPUs.
       */
      if(nr_cpu > 1) {
       file = fopen("/proc/stat", "r");
       if(file == NULL) {
         puts("open");
       }
       if(fgets(str, 128, file) == NULL) {
         fprintf(stderr, "fgets failed on /proc/stat\n");
       }
       for(i = 0; i < nr_cpu; i++) {
         if(fscanf(file, "cpu%*d %d %d %d %d\n",
                   &u_ticks_o[i], &n_ticks_o[i], &s_ticks_o[i],
                   &i_ticks_o[i]) != 4) {
           fprintf(stderr, "fscanf failed on /proc/stat for cpu %d\n", i);
         }
       }
       fclose(file);
      }
    }
    /*
     * Save this frame's information.
     */
    for (i = 0; i < n; i++) {
	/* copy the relevant info for the next pass */
 	save_history[i].pid = New_save_hist[i].pid;
	save_history[i].ticks = New_save_hist[i].ticks;
	save_history[i].stime = New_save_hist[i].stime;
	save_history[i].utime = New_save_hist[i].utime;
    }
    free(New_save_hist);

    prev_count = n;
    qsort(p, n, sizeof(proc_t*), (void*)mult_lvl_cmp);
}
Example #12
0
/*
 * This is the real program!  Read process info and display it.
 * One could differentiate options of readproctable2, perhaps it
 * would be useful to support the PROC_UID and PROC_TTY
 * as command line options.
 */
void show_procs(void)
{
    static proc_t **p_table=NULL;
    static int proc_flags;
    int count;
    int ActualLines;
    float elapsed_time;
    unsigned int main_mem;
    static int first=0;

    if (first==0) {
	proc_flags=PROC_FILLMEM|PROC_FILLCMD|PROC_FILLUSR;
	if (monpids_index)
	    proc_flags |= PROC_PID;
	p_table=readproctab2(proc_flags, p_table, monpids);
	elapsed_time = get_elapsed_time();
	do_stats(p_table, elapsed_time, 0);
	sleep(1);
	first=1;
    }
    if (first && Batch)
	    fputs("\n\n",stdout);
    /* Display the load averages. */
    PUTP(ho);
    PUTP(md);
    if (show_loadav) {
	printf("%s", sprint_uptime());
	PUTP(top_clrtoeol);
	putchar('\n');
    }
    p_table=readproctab2(proc_flags, p_table, monpids);
    /* Immediately find out the elapsed time for the frame. */
    elapsed_time = get_elapsed_time();
    /* Display the system stats, calculate percent CPU time
     * and sort the list. */
    do_stats(p_table, elapsed_time,1);
    /* Display the memory and swap space usage. */
    main_mem = show_meminfo();
    if (strlen(Header) + 2 > Cols)
	Header[Cols - 2] = 0;
    PUTP(mr);
    fputs(Header, stdout);
    PUTP(top_clrtoeol);
    PUTP(me);

    /*
     * Finally!  Loop through to find the top task, and display it.
     * Lather, rinse, repeat.
     */
    count = 0;
    ActualLines = 0;
    while ((ActualLines < Maxlines) && (p_table[count]->pid!=-1)) {
	int pmem;
	char stat;

	stat = p_table[count]->state;

	if ( (!Noidle || (stat != 'S' && stat != 'Z')) &&
	     ( (CurrUser[0] == '\0') ||
	      (!strcmp((char *)CurrUser,p_table[count]->euser) ) ) ) {

	    /*
	     * Show task info.
	     */
	    pmem = p_table[count]->resident * 1000 / (main_mem / 4);
	    show_task_info(p_table[count], pmem);
	    if (!Batch)
	    	ActualLines++;
	}
	count++;
    }
    PUTP(top_clrtobot);
    PUTP(tgoto(cm, 0, header_lines - 2));
    fflush(stdout);
}
Example #13
0
	/*
	 * Displays infos for a single task
	 */
void show_task_info(proc_t *task, int pmem)
{
    int i,j;
    unsigned int t;
    char *cmdptr;
    char tmp[2048], tmp2[2048] = "", tmp3[2048] = "", *p;

    for (i = 0; i < Numfields; i++) {
	tmp[0] = 0;
	switch (pflags[i]) {
	  case P_PID:
	    sprintf(tmp, "%5d ", task->pid);
	    break;
	  case P_PPID:
	    sprintf(tmp, "%5d ", task->ppid);
	    break;
	  case P_EUID:
	    sprintf(tmp, "%4d ", task->euid);
	    break;
	  case P_EUSER:
	    sprintf(tmp, "%-8.8s ", task->euser);
	    break;
	  case P_PCPU:
	    sprintf(tmp, "%4.1f ", (float)task->pcpu / 10);
	    break;
	  case P_LCPU:
	    sprintf(tmp, "%2d ", task->lproc);
	    break;
	  case P_PMEM:
	    sprintf(tmp, "%4.1f ", (float)pmem / 10);
	    break;
	  case P_TTY: {
	      char outbuf[9];
	      dev_to_tty(outbuf, 8, task->tty, task->pid, ABBREV_DEV);
	      sprintf(tmp, "%-8.8s ", outbuf);
	    }
	    break;
	  case P_PRI:
	    sprintf(tmp, "%3.3s ", scale_k(task->priority, 3, 0));
	    break;
	  case P_NICE:
	    sprintf(tmp, "%3.3s ", scale_k(task->nice, 3, 0));
	    break;
	  case P_PAGEIN:
	    sprintf(tmp, "%6.6s ", scale_k(task->maj_flt, 6, 0));
	    break;
	  case P_TSIZ:
	    sprintf(tmp, "%5.5s ",
		scale_k(((task->end_code - task->start_code) / 1024), 5, 1));
	    break;
	  case P_DSIZ:
	    sprintf(tmp, "%5.5s ",
		scale_k(((task->vsize - task->end_code) / 1024), 5, 1));
	    break;
	  case P_SIZE:
	    sprintf(tmp, "%5.5s ", scale_k((task->size << CL_pg_shift), 5, 1));
	    break;
	  case P_TRS:
	    sprintf(tmp, "%4.4s ", scale_k((task->trs << CL_pg_shift), 4, 1));
	    break;
	  case P_SWAP:
	    sprintf(tmp, "%4.4s ",
		scale_k(((task->size - task->resident) << CL_pg_shift), 4, 1));
	    break;
	  case P_SHARE:
	    sprintf(tmp, "%5.5s ", scale_k((task->share << CL_pg_shift), 5, 1));
	    break;
	  case P_A:
	    sprintf(tmp, "%3.3s ", "NYI");
	    break;
	  case P_WP:
	    sprintf(tmp, "%3.3s ", "NYI");
	    break;
	  case P_DT:
	    sprintf(tmp, "%3.3s ", scale_k(task->dt, 3, 0));
	    break;
	  case P_RSS:	/* resident not rss, it seems to be more correct. */
	    sprintf(tmp, "%4.4s ",
		scale_k((task->resident << CL_pg_shift), 4, 1));
	    break;
	  case P_WCHAN:
	    if (!CL_wchan_nout)
		sprintf(tmp, "%-9.9s ", wchan(task->wchan));
	    else
		sprintf(tmp, "%-9lx", task->wchan);
	    break;
	  case P_STAT:
	    sprintf(tmp, "%-4.4s ", status(task));
	    break;
	  case P_TIME:
	    t = (task->utime + task->stime) / Hertz;
	    if (Cumulative)
		t += (task->cutime + task->cstime) / Hertz;
	    sprintf(tmp, "%6.6s ", scale_time(t,6));
	    break;
	  case P_COMMAND:
	    if (!show_cmd && task->cmdline && *(task->cmdline)) {
	        j=0;
	        while(((task->cmdline)[j] != NULL) && (strlen(tmp3)<1020)){
/* #if 0 */ /* This is useless? FIXME */
		    if (j > 0)
			strcat(tmp3, " ");
/* #endif */
		    strncat(tmp3, (task->cmdline)[j], 1000);
		    j++; 
	        }
	        cmdptr = tmp3;
	    } else {
		cmdptr = task->cmd;
	    }
	    if (strlen(cmdptr) > Maxcmd)
		cmdptr[Maxcmd - 1] = 0;
	    sprintf(tmp, "%s", cmdptr);
	    tmp3[0]=0;
	    break;
	  case P_FLAGS:
	    sprintf(tmp, "%8lx ", task->flags);
	    break;
	}
	strcat(tmp2, tmp);
    }
    if (strlen(tmp2) > Cols - 1)
	tmp2[Cols - 1] = 0;

    /* take care of cases like:
       perl -e 'foo
          bar foo bar
          foo
          # end of perl script'
    */
    for (p=tmp2;*p;++p)
        if (!isgraph(*p))
            *p=' ';

    printf("\n%s", tmp2);
    PUTP(top_clrtoeol);
}
Example #14
0
File: top.c Project: AnthraX1/rk
	/*
	 * Displays infos for a single task
	 */
void show_task_info(proc_t *task, int pmem)
{
    int i,j;
    unsigned int t;
    char *cmdptr;
    char tmp[2048], tmp2[2048] = "", tmp3[2048] = "";

    for (i = 0; i < Numfields; i++) {
	tmp[0] = 0;
	switch (pflags[i]) {
	  case P_PID:
	    sprintf(tmp, "%5d ", task->pid);
	    break;
	  case P_PPID:
	    sprintf(tmp, "%5d ", task->ppid);
	    break;
	  case P_UID:
	    sprintf(tmp, "%4d ", task->uid);
	    break;
	  case P_USER:
	    sprintf(tmp, "%-8.8s ", task->user);
	    break;
	  case P_PCPU:
	    sprintf(tmp, "%2d.%1d ", task->pcpu / 10, task->pcpu % 10);
	    break;
	  case P_PMEM:
	    sprintf(tmp, "%2d.%1d ", pmem / 10, pmem % 10);
	    break;
	  case P_TTY:
	    sprintf(tmp, "%-3.3s ", task->ttyc);
	    break;
	  case P_PRI:
	    sprintf(tmp, "%3d ", task->priority);
	    break;
	  case P_NICE:
	    sprintf(tmp, "%3d ", task->nice);
	    break;
	  case P_PAGEIN:
	    sprintf(tmp, "%6d ", task->maj_flt);
	    break;
	  case P_TSIZ:
	    sprintf(tmp, "%5d ", (task->end_code - task->start_code) / 1024);
	    break;
	  case P_DSIZ:
	    sprintf(tmp, "%5d ", (task->vsize - task->end_code) / 1024);
	    break;
	  case P_SIZE:
	    sprintf(tmp, "%5d ", task->size << CL_pg_shift);
	    break;
	  case P_TRS:
	    sprintf(tmp, "%4d ", task->trs << CL_pg_shift);
	    break;
	  case P_SWAP:
	    sprintf(tmp, "%4d ", (task->size - task->resident) << CL_pg_shift);
	    break;
	  case P_SHARE:
	    sprintf(tmp, "%5d ", task->share << CL_pg_shift);
	    break;
	  case P_A:
	    sprintf(tmp, "%3.3s ", "NYI");
	    break;
	  case P_WP:
	    sprintf(tmp, "%3.3s ", "NYI");
	    break;
	  case P_DT:
	    sprintf(tmp, "%3d ", task->dt);
	    break;
	  case P_RSS:	/* resident not rss, it seems to be more correct. */
	    sprintf(tmp, "%4d ", task->resident << CL_pg_shift);
	    break;
	  case P_WCHAN:
	    if (!CL_wchan_nout)
		sprintf(tmp, "%-9.9s ", wchan(task->wchan));
	    else
		sprintf(tmp, "%-9x", task->wchan);
	    break;
	  case P_STAT:
	    sprintf(tmp, "%-4.4s ", status(task));
	    break;
	  case P_TIME:
	    t = (task->utime + task->stime) / HZ;
	    if (Cumulative)
		t += (task->cutime + task->cstime) / HZ;
	    sprintf(tmp, "%3d:%02d ", t / 60, t % 60);
	    break;
	  case P_COMMAND:
	    if (!show_cmd && task->cmdline && *(task->cmdline)) {
	        j=0;
	        while(((task->cmdline)[j] != NULL) && (strlen(tmp3)<1024)){
		    strcat(tmp3,(task->cmdline)[j]);
		    j++; 
	        }
	        cmdptr = tmp3;
	    } else {
		cmdptr = task->cmd;
	    }
	    if (strlen(cmdptr) > Maxcmd)
		cmdptr[Maxcmd - 1] = 0;
	    sprintf(tmp, "%s", cmdptr);
	    tmp3[0]=0;
	    break;
	  case P_LTR:
	    sprintf(tmp, "%4d ", task->lrs << CL_pg_shift);
	    break;
	  case P_FLAGS:
	    sprintf(tmp, "%8x ", task->flags);
	    break;
	}
	strcat(tmp2, tmp);
    }
    if (strlen(tmp2) > Cols - 1)
	tmp2[Cols - 1] = 0;
    printf("\n%s", tmp2);
    PUTP(top_clrtoeol);
}
Example #15
0
File: top.c Project: AnthraX1/rk
int main(int argc, char **argv)
{
    /* For select(2). */
    struct timeval tv;
    fd_set in;
    /* For parsing arguments. */
    char *cp;
    /* The key read in. */
    char c;

    get_options();
    /*
     * Parse arguments.
     */
    argv++;
    while (*argv) {
	cp = *argv++;
	while (*cp) {
	    switch (*cp) {
	      case 'd':
	        if (cp[1]) {
		    if (sscanf(++cp, "%f", &Sleeptime) != 1) {
			fprintf(stderr, PROGNAME ": Bad delay time `%s'\n", cp);
			exit(1);
		    }
		    goto breakargv;
		} else if (*argv) { /* last char in an argv, use next as arg */
		    if (sscanf(cp = *argv++, "%f", &Sleeptime) != 1) {
			fprintf(stderr, PROGNAME ": Bad delay time `%s'\n", cp);
			exit(1);
		    }
		    goto breakargv;
		} else {
		    fprintf(stderr, "-d requires an argument\n");
		    exit(1);
		}
		break;
	      case 'q':
		if (!getuid())
		    /* set priority to -10 in order to stay above kswapd */
		    if (setpriority(PRIO_PROCESS, getpid(), -10)) {
			/* We check this just for paranoia.  It's not
			   fatal, and shouldn't happen. */
			perror(PROGNAME ": setpriority() failed");
		    }
		Sleeptime = 0;
		break;
	      case 'c':
	        show_cmd = !show_cmd;
		break;
	      case 'S':
		Cumulative = 1;
		break;
	      case 'i':
		Noidle = 1;
		break;
	      case 's':
		Secure = 1;
		break;
	      case '-':
		break;		/* Just ignore it */
#if defined (SHOWFLAG)
              case '/': showall++;
#endif
	      default:
		fprintf(stderr, PROGNAME ": Unknown argument `%c'\n", *cp);
		exit(1);
	    }
	    cp++;
	}
    breakargv:
    }
    
    /* set to PCPU sorting */
    register_sort_function( -1, (cmp_t)pcpu_sort);
    
    /* for correct handling of some fields, we have to do distinguish 
  * between kernel versions */
    set_linux_version();
    /* get kernel symbol table, if needed */
    if (!CL_wchan_nout) {
	if (open_psdb()) {
	    CL_wchan_nout = 1;
	} else {
	    psdbsucc = 1;
	}
    }

    setup_terminal();
    window_size();
    /*
     * calculate header size, length of cmdline field ...
     */
    Numfields = make_header();
    /*
     * Set up signal handlers.
     */
    signal(SIGHUP, (void *) (int) end);
    signal(SIGINT, (void *) (int) end);
    signal(SIGQUIT, (void *) (int) end);
    signal(SIGTSTP, (void *) (int) stop);
    signal(SIGWINCH, (void *) (int) window_size);

    /* loop, collecting process info and sleeping */
    while (1) {
	if (setjmp(redraw_jmp))
	    clear_screen();

	/* display the tasks */
	show_procs();
	/* sleep & wait for keyboard input */
	tv.tv_sec = Sleeptime;
	tv.tv_usec = (Sleeptime - (int) Sleeptime) * 1000000;
	FD_ZERO(&in);
	FD_SET(0, &in);
	if (select(16, &in, 0, 0, &tv) > 0 && read(0, &c, 1) == 1)
	    do_key(c);
    }
}

/*#######################################################################
 *#### Signal handled routines: error_end, end, stop, window_size     ###
 *#### Small utilities: make_header, getstr, getint, getfloat, getsig ###
 *#######################################################################
 */


	/*
	 *  end when exiting with an error.
	 */
void error_end(int rno)
{
    if (psdbsucc)
        close_psdb();
    ioctl(0, TCSETAF, &Savetty);
    PUTP(tgoto(cm, 0, Lines - 1));
    fputs("\r\n", stdout);
    exit(rno);
}
/*
	 * Normal end of execution.
	 */
void end(void)
{
    if (psdbsucc)
	close_psdb();
    ioctl(0, TCSETAF, &Savetty);
    PUTP(tgoto(cm, 0, Lines - 1));
    fputs("\r\n", stdout);
    exit(0);
}

/*
	 * SIGTSTP catcher.
	 */
void stop(void)
{
    /* Reset terminal. */
    if (psdbsucc)
	close_psdb();
    ioctl(0, TCSETAF, &Savetty);
    PUTP(tgoto(cm, 0, Lines - 3));
    fflush(stdout);
    raise(SIGTSTP);
    /* Later... */
    ioctl(0, TCSETAF, &Rawtty);
    signal(SIGTSTP, (void *) (int) stop);
    longjmp(redraw_jmp, 1);
}

/*
       * Reads the window size and clear the window.  This is called on setup,
       * and also catches SIGWINCHs, and adjusts Maxlines.  Basically, this is
       * the central place for window size stuff.
       */
void window_size(void)
{
    struct winsize ws;

    if (ioctl(1, TIOCGWINSZ, &ws) != -1) {
	Cols = ws.ws_col;
	Lines = ws.ws_row;
    } else {
	Cols = tgetnum("co");
	Lines = tgetnum("li");
    }
    clear_screen();
}
/*
       * this adjusts the lines needed for the header to the current value
       */
int make_header(void)
{
    int i, j;

    j = 0;
    for (i = 0; i < strlen(Fields); i++) {
	if (isupper(Fields[i])) {
	    pflags[j++] = Fields[i] - 'A';
	}
    }
    strcpy(Header, "");
    for (i = 0; i < j; i++)
	strcat(Header, headers[pflags[i]]);
    /* readjust window size ... */
    Maxcmd = Cols - strlen(Header) + 7;
    Maxlines = Display_procs ? Display_procs : Lines - header_lines;
    if (Maxlines > Lines - header_lines)
	Maxlines = Lines - header_lines;
    return (j);
}
Example #16
0
File: top.c Project: AnthraX1/rk
/*
 * Calculates the number of tasks in each state (running, sleeping, etc.).
 * Calculates the CPU time in each state (system, user, nice, etc).
 * Calculates percent cpu usage for each task.
 */
void do_stats(proc_t** p, float elapsed_time, int pass)
{
    proc_t *this;
    int index, total_time, i, n = 0;
    int sleeping = 0, stopped = 0, zombie = 0, running = 0;
    int system_ticks = 0, user_ticks = 0, nice_ticks = 0, idle_ticks = 1000;
    static int prev_count = 0;
    int stime, utime;
    static struct save_hist save_history[NR_TASKS];
    struct save_hist New_save_hist[NR_TASKS];

    /*
     * Make a pass through the data to get stats.
     */
    index = 0;
    while (p[n]->pid != -1) {
	this = p[n];
	switch (this->state) {
	  case 'S':
	  case 'D':
	    sleeping++;
	    break;
	  case 'T':
	    stopped++;
	    break;
	  case 'Z':
	    zombie++;
	    break;
	  case 'R':
	    running++;
	    break;
	  default:
	    /* Don't know how to handle this one. */
	    break;
        }

	/*
	 * Calculate time in this process.  Time is sum of user time
	 * (utime) plus system time (stime).
	 */
	total_time = this->utime + this->stime;
	New_save_hist[index].ticks = total_time;
	New_save_hist[index].pid = this->pid;
	stime = this->stime;
	utime = this->utime;
	New_save_hist[index].stime = stime;
	New_save_hist[index].utime = utime;
	/* find matching entry from previous pass */
	i = 0;
	while (i < prev_count) {
	    if (save_history[i].pid == this->pid) {
		total_time -= save_history[i].ticks;
		stime -= save_history[i].stime;
		utime -= save_history[i].utime;

		i = NR_TASKS;
	    }
	    i++;
	}

	/*
	 * Calculate percent cpu time for this task.
	 */
	this->pcpu = (total_time * 10 * 100/HZ) / elapsed_time;
	if (this->pcpu > 999)
	    this->pcpu = 999;

	/*
	 * Calculate time in idle, system, user and niced tasks.
	 */
	idle_ticks -= this->pcpu;
	system_ticks += stime;
	user_ticks += utime;
	if (this->priority > 0)
	    nice_ticks += this->pcpu;

	index++;
	n++;
	if (n > NR_TASKS) {
	    printf(PROGNAME ": Help!  Too many tasks!\n");
	    end();
	}
    }

    if (idle_ticks < 0)
	idle_ticks = 0;
    system_ticks = (system_ticks * 10 * 100/HZ) / elapsed_time;
    user_ticks = (user_ticks * 10 * 100/HZ) / elapsed_time;

    /*
     * Display stats.
     */
    if (pass > 0 && show_stats) {
	printf("%d processes: %d sleeping, %d running, %d zombie, "
	       "%d stopped",
	       n, sleeping, running, zombie, stopped);
	PUTP(top_clrtoeol);
	putchar('\n');
	printf("CPU states: %2d.%d%% user, %2d.%d%% system,"
	       " %2d.%d%% nice, %2d.%d%% idle",
	       user_ticks / 10, user_ticks % 10,
	       system_ticks / 10, system_ticks % 10,
	       nice_ticks / 10, nice_ticks % 10,
	       idle_ticks / 10, idle_ticks % 10);
	PUTP(top_clrtoeol);
	putchar('\n');
    }
    /*
     * Save this frame's information.
     */
    for (i = 0; i < n; i++) {
	/* copy the relevant info for the next pass */
 	save_history[i].pid = New_save_hist[i].pid;
	save_history[i].ticks = New_save_hist[i].ticks;
	save_history[i].stime = New_save_hist[i].stime;
	save_history[i].utime = New_save_hist[i].utime;
    }
    prev_count = n;
    qsort(p, n, sizeof(proc_t*), (void*)mult_lvl_cmp);
}