blob: 8efd82d8990a697df6ac791e63a9b3e2f66575bf [file] [log] [blame] [raw]
/*
htop - freebsd/FreeBSDDisk.c
Copyright 2015-2022 Rivoreo
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
/*{
#include "Disk.h"
#include "Settings.h"
#include <sys/time.h>
#include <stdint.h>
#define HTOP_DISK_CAM_PATH_FLAG (1 << 7)
typedef enum {
// Add platform-specific fields here, with ids >= 100
HTOP_DISK_BUSY_TIME_FIELD = 100,
HTOP_DISK_PERCENT_BUSY_FIELD,
HTOP_DISK_CAM_PATH_FIELD,
HTOP_FREEBSD_DISK_FIELD_COUNT
} FreeBSDDiskField;
typedef struct {
Disk super;
struct timeval duration;
uint64_t busy_time; // In 10-millisecond
float percent_busy;
char *cam_path;
} FreeBSDDisk;
}*/
#include "FreeBSDDisk.h"
#include "CRT.h"
#include <stdio.h>
const FieldData Disk_fields[] = {
[0] = { .name = "", .title = NULL, .description = NULL, .flags = 0 },
[HTOP_DISK_NAME_FIELD] = { .name = "NAME", .title = "NAME ", .description = "Canonical device name", .flags = 0 },
[HTOP_DISK_PHYS_PATH_FIELD] = { .name = "PHYS_PATH", .title = "PHYS_PATH ", .description = "Predictable device name based on phyiscal location", .flags = HTOP_DISK_PHYS_PATH_FLAG },
[HTOP_DISK_DEVID_FIELD] = { .name = "DEVID", .title = "DEVID ", .description = "Predictable device name based on model and serial number", .flags = HTOP_DISK_DEVID_FLAG },
[HTOP_DISK_BLOCK_SIZE_FIELD] = { .name = "BLOCK_SIZE", .title = " BLKSZ ", .description = "I/O block size", .flags = 0 },
[HTOP_DISK_QUEUE_LENGTH_FIELD] = { .name = "QUEUE_LENGTH", .title = "QUEUE ", .description = "Request queue length", .flags = 0 },
[HTOP_DISK_OPERATIONS_FIELD] = { .name = "OPERATIONS", .title = " OPS ", .description = "Total operations performed", .flags = 0 },
[HTOP_DISK_READ_OPS_FIELD] = { .name = "READ_OPERATIONS", .title = " R_OPS ", .description = "Total read operations performed", .flags = 0 },
[HTOP_DISK_WRITE_OPS_FIELD] = { .name = "WRITE_OPERATIONS", .title = " W_OPS ", .description = "Total write operations performed", .flags = 0 },
[HTOP_DISK_READ_BLOCKS_FIELD] = { .name = "READ_BLOCKS", .title = "R_BLKS ", .description = "Total blocks readen", .flags = 0 },
[HTOP_DISK_WRITE_BLOCKS_FIELD] = { .name = "WRITE_BLOCKS", .title = "W_BLKS ", .description = "Total blocks written", .flags = 0 },
[HTOP_DISK_READ_BYTES_FIELD] = { .name = "READ_BYTES", .title = " RBYTES ", .description = "Total bytes readon", .flags = 0 },
[HTOP_DISK_WRITE_BYTES_FIELD] = { .name = "WRITE_BYTES", .title = " WBYTES ", .description = "Total bytes written", .flags = 0 },
[HTOP_DISK_OPER_TIME_FIELD] = { .name = "OPER_TIME", .title = "OPERTIME ", .description = "Total time of transactions", .flags = 0 },
[HTOP_DISK_BUSY_TIME_FIELD] = { .name = "BUSY_TIME", .title = "BUSYTIME ", .description = "Total time of when the disk had one or more outstanding transactions", .flags = 0 },
[HTOP_DISK_CREATION_TIME_FIELD] = { .name = "CREATION_TIME", .title = "BTIME ", .description = "Time when the disk appeared", .flags = 0 },
[HTOP_DISK_OPERATION_RATE_FIELD] = { .name = "OPERATION_RATE", .title = " OPS/S ", .description = "Operations per second", .flags = 0 },
[HTOP_DISK_READ_OPERATION_RATE_FIELD] = { .name = "READ_OPERATION_RATE", .title = "ROPS/S ", .description = "Read operations per second", .flags = 0 },
[HTOP_DISK_WRITE_OPERATION_RATE_FIELD] = { .name = "WRITE_OPERATION_RATE", .title = "WOPS/S ", .description = "Write operations per second", .flags = 0 },
[HTOP_DISK_READ_BLOCK_RATE_FIELD] = { .name = "READ_BLOCK_RATE", .title = " RBLK/S ", .description = "Read blocks per second", .flags = 0 },
[HTOP_DISK_WRITE_BLOCK_RATE_FIELD] = { .name = "WRITE_BLOCK_RATE", .title = " WBLK/S ", .description = "Write blocks per second", .flags = 0 },
[HTOP_DISK_READ_BYTE_RATE_FIELD] = { .name = "READ_BYTE_RATE", .title = "RBYTE/S ", .description = "Read bytes per second", .flags = 0 },
[HTOP_DISK_WRITE_BYTE_RATE_FIELD] = { .name = "WRITE_BYTE_RATE", .title = "WBYTE/S ", .description = "Write bytes per second", .flags = 0 },
[HTOP_DISK_PERCENT_UTIL_FIELD] = { .name = "PERCENT_UTIL", .title = "UTIL% ", .description = "Percentage of time during transactions", .flags = HTOP_DISK_PERCENT_UTIL_FLAG },
[HTOP_DISK_PERCENT_BUSY_FIELD] = { .name = "PERCENT_BUSY", .title = "BUSY% ", .description = "Percentage of time the disk had one or more transactions outstanding", .flags = 0 },
[HTOP_DISK_BLOCK_COUNT_FIELD] = { .name = "BLOCK_COUNT", .title = "BLOCKS ", .description = "Total capacity in blocks", .flags = HTOP_DISK_CAPACITY_FLAG },
[HTOP_DISK_BYTE_COUNT_FIELD] = { .name = "BYTE_COUNT", .title = " BYTES ", .description = "Total capacity in bytes", .flags = HTOP_DISK_CAPACITY_FLAG },
[HTOP_DISK_CAM_PATH_FIELD] = { .name = "CAM_PATH", .title = "CAM_PATH ", .description = "Device path in CAM subsystem", .flags = HTOP_DISK_CAM_PATH_FLAG },
[HTOP_FREEBSD_DISK_FIELD_COUNT] = { .name = "*** report bug! ***", .title = NULL, .description = NULL, .flags = 0 }
};
const unsigned int Disk_field_count = HTOP_FREEBSD_DISK_FIELD_COUNT;
const DiskField Disk_default_fields[] = {
HTOP_DISK_QUEUE_LENGTH_FIELD,
HTOP_DISK_OPERATION_RATE_FIELD,
HTOP_DISK_READ_OPERATION_RATE_FIELD,
HTOP_DISK_READ_BYTE_RATE_FIELD,
HTOP_DISK_WRITE_OPERATION_RATE_FIELD,
HTOP_DISK_WRITE_BYTE_RATE_FIELD,
HTOP_DISK_PERCENT_UTIL_FIELD,
(DiskField)HTOP_DISK_PERCENT_BUSY_FIELD,
HTOP_DISK_NAME_FIELD,
HTOP_DISK_PHYS_PATH_FIELD,
0
};
static void FreeBSDDisk_writeField(const Disk *super, RichString *s, DiskField field) {
const FreeBSDDisk *this = (const FreeBSDDisk *)super;
char buffer[256];
int attr = CRT_colors[HTOP_DEFAULT_COLOR];
switch((unsigned int)field) {
case HTOP_DISK_BUSY_TIME_FIELD:
CRT_printTime(s, this->busy_time);
return;
case HTOP_DISK_PERCENT_BUSY_FIELD:
Disk_printPercent(s, this->percent_busy);
return;
case HTOP_DISK_CAM_PATH_FIELD:
xSnprintf(buffer, sizeof buffer, "%-40s ", this->cam_path ? : "-");
break;
default:
base_Disk_writeField(super, s, field);
return;
}
RichString_append(s, attr, buffer);
}
static long int FreeBSDDisk_compare(const void *o1, const void *o2) {
const FreeBSDDisk *d1;
const FreeBSDDisk *d2;
const Settings *settings = ((const Disk *)o1)->settings;
if(settings->direction == 1) {
d1 = o1;
d2 = o2;
} else {
d2 = o1;
d1 = o2;
}
switch((unsigned int)settings->disk_sort_key) {
case HTOP_DISK_BUSY_TIME_FIELD:
return uintcmp(d2->busy_time, d1->busy_time);
case HTOP_DISK_PERCENT_BUSY_FIELD:
return d2->percent_busy - d1->percent_busy;
case HTOP_DISK_CAM_PATH_FIELD:
return settings->sort_strcmp(d1->cam_path ? : "", d2->cam_path ? : "");
default:
return Disk_compare(o1, o2);
}
}
DiskClass FreeBSDDisk_class = {
.super = {
.extends = Class(Disk),
.delete = FreeBSDDisk_delete,
.compare = FreeBSDDisk_compare
},
.writeField = FreeBSDDisk_writeField
};
FreeBSDDisk *FreeBSDDisk_new(const Settings *settings) {
FreeBSDDisk *this = xCalloc(1, sizeof(FreeBSDDisk));
Object_setClass(this, Class(FreeBSDDisk));
Disk_init(&this->super, settings);
return this;
}
void FreeBSDDisk_delete(Object *super) {
FreeBSDDisk *this = (FreeBSDDisk *)super;
Disk_done((Disk *)super);
free(this->cam_path);
free(this);
}