Back to index

libdrm  2.4.37
Defines | Functions | Variables
drmstat.c File Reference
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/mman.h>
#include <getopt.h>
#include <strings.h>
#include <errno.h>
#include <signal.h>
#include <fcntl.h>
#include "xf86drm.h"

Go to the source code of this file.

Defines

#define __FUNCTION__   __func__ /* C99 */
#define HISTOSIZE   9

Functions

static double usec (struct timeval *end, struct timeval *start)
static void getversion (int fd)
void handler (int fd, void *oldctx, void *newctx)
void process_sigio (char *device)
int main (int argc, char **argv)
void xf86VDrvMsgVerb (int scrnIndex, int type, int verb, const char *format, va_list args)

Variables

int sigio_fd
int xf86ConfigDRI [10]

Define Documentation

#define __FUNCTION__   __func__ /* C99 */

Definition at line 51 of file drmstat.c.

#define HISTOSIZE   9

Function Documentation

static void getversion ( int  fd) [static]

Definition at line 64 of file drmstat.c.

{
    drmVersionPtr version;
    
    version = drmGetVersion(fd);
    if (version) {
       printf( "Name: %s\n", version->name ? version->name : "?" );
       printf( "    Version: %d.%d.%d\n",
              version->version_major,
              version->version_minor,
              version->version_patchlevel );
       printf( "    Date: %s\n", version->date ? version->date : "?" );
       printf( "    Desc: %s\n", version->desc ? version->desc : "?" );
       drmFreeVersion(version);
    } else {
       printf( "No driver available\n" );
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void handler ( int  fd,
void *  oldctx,
void *  newctx 
)

Definition at line 83 of file drmstat.c.

{
    printf("Got fd %d\n", fd);
}
int main ( int  argc,
char **  argv 
)

Definition at line 102 of file drmstat.c.

{
    int            c;
    int            r  = 0;
    int            fd = -1;
    drm_handle_t      handle;
    void           *address;
    char           *pt;
    unsigned long  count;
    unsigned long  offset;
    unsigned long  size;
    drm_context_t  context;
    int            loops;
    char           buf[1024];
    int            i;
    drmBufInfoPtr  info;
    drmBufMapPtr   bufs;
    drmLockPtr     lock;
    int            secs;

    while ((c = getopt(argc, argv,
                     "lc:vo:O:f:s:w:W:b:r:R:P:L:C:XS:B:F:")) != EOF)
       switch (c) {
       case 'F':
           count  = strtoul(optarg, NULL, 0);
           if (!fork()) {
              dup(fd);
              sleep(count);
           }
           close(fd);
           break;
       case 'v': getversion(fd);                                        break;
       case 'X':
           if ((r = drmCreateContext(fd, &context))) {
              drmError(r, argv[0]);
              return 1;
           }
           printf( "Got %d\n", context);
           break;
       case 'S':
           process_sigio(optarg);
           break;
       case 'C':
           if ((r = drmSwitchToContext(fd, strtoul(optarg, NULL, 0)))) {
              drmError(r, argv[0]);
              return 1;
           }
           break;
       case 'c':
           if ((r = drmSetBusid(fd,optarg))) {
              drmError(r, argv[0]);
              return 1;
           }
           break;
       case 'o':
           if ((fd = drmOpen(optarg, NULL)) < 0) {
              drmError(fd, argv[0]);
              return 1;
           }
           break;
       case 'O':
           if ((fd = drmOpen(NULL, optarg)) < 0) {
              drmError(fd, argv[0]);
              return 1;
           }
           break;
       case 'B':            /* Test buffer allocation */
           count  = strtoul(optarg, &pt, 0);
           size   = strtoul(pt+1, &pt, 0);
           secs   = strtoul(pt+1, NULL, 0);
           {
              drmDMAReq      dma;
              int            *indices, *sizes;

              indices = alloca(sizeof(*indices) * count);
              sizes   = alloca(sizeof(*sizes)   * count);
              dma.context         = context;
              dma.send_count      = 0;
              dma.request_count   = count;
              dma.request_size    = size;
              dma.request_list    = indices;
              dma.request_sizes   = sizes;
              dma.flags           = DRM_DMA_WAIT;
              if ((r = drmDMA(fd, &dma))) {
                  drmError(r, argv[0]);
                  return 1;
              }
              for (i = 0; i < dma.granted_count; i++) {
                  printf("%5d: index = %d, size = %d\n",
                        i, dma.request_list[i], dma.request_sizes[i]);
              }
              sleep(secs);
              drmFreeBufs(fd, dma.granted_count, indices);
           }
           break;
       case 'b':
           count   = strtoul(optarg, &pt, 0);
           size    = strtoul(pt+1, NULL, 0);
           if ((r = drmAddBufs(fd, count, size, 0, 65536)) < 0) {
              drmError(r, argv[0]);
              return 1;
           }
           if (!(info = drmGetBufInfo(fd))) {
              drmError(0, argv[0]);
              return 1;
           }
           for (i = 0; i < info->count; i++) {
              printf("%5d buffers of size %6d (low = %d, high = %d)\n",
                     info->list[i].count,
                     info->list[i].size,
                     info->list[i].low_mark,
                     info->list[i].high_mark);
           }
           if ((r = drmMarkBufs(fd, 0.50, 0.80))) {
              drmError(r, argv[0]);
              return 1;
           }
           if (!(info = drmGetBufInfo(fd))) {
              drmError(0, argv[0]);
              return 1;
           }
           for (i = 0; i < info->count; i++) {
              printf("%5d buffers of size %6d (low = %d, high = %d)\n",
                     info->list[i].count,
                     info->list[i].size,
                     info->list[i].low_mark,
                     info->list[i].high_mark);
           }
           printf("===== /proc/dri/0/mem =====\n");
           sprintf(buf, "cat /proc/dri/0/mem");
           system(buf);
#if 1
           if (!(bufs = drmMapBufs(fd))) {
              drmError(0, argv[0]);
              return 1;
           }
           printf("===============================\n");
           printf( "%d bufs\n", bufs->count);
           for (i = 0; i < bufs->count; i++) {
              printf( "  %4d: %8d bytes at %p\n",
                     i,
                     bufs->list[i].total,
                     bufs->list[i].address);
           }
           printf("===== /proc/dri/0/vma =====\n");
           sprintf(buf, "cat /proc/dri/0/vma");
           system(buf);
#endif
           break;
       case 'f':
           offset  = strtoul(optarg, &pt, 0);
           size    = strtoul(pt+1, NULL, 0);
           handle  = 0;
           if ((r = drmAddMap(fd, offset, size,
                            DRM_FRAME_BUFFER, 0, &handle))) {
              drmError(r, argv[0]);
              return 1;
           }
           printf("0x%08lx:0x%04lx added\n", offset, size);
           printf("===== /proc/dri/0/mem =====\n");
           sprintf(buf, "cat /proc/dri/0/mem");
           system(buf);
           break;
       case 'r':
       case 'R':
           offset  = strtoul(optarg, &pt, 0);
           size    = strtoul(pt+1, NULL, 0);
           handle  = 0;
           if ((r = drmAddMap(fd, offset, size,
                            DRM_REGISTERS,
                            c == 'R' ? DRM_READ_ONLY : 0,
                            &handle))) {
              drmError(r, argv[0]);
              return 1;
           }
           printf("0x%08lx:0x%04lx added\n", offset, size);
           printf("===== /proc/dri/0/mem =====\n");
           sprintf(buf, "cat /proc/dri/0/mem");
           system(buf);
           break;
       case 's':
           size = strtoul(optarg, &pt, 0);
           handle = 0;
           if ((r = drmAddMap(fd, 0, size,
                            DRM_SHM, DRM_CONTAINS_LOCK,
                            &handle))) {
              drmError(r, argv[0]);
              return 1;
           }
           printf("0x%04lx byte shm added at 0x%08lx\n", size, handle);
           sprintf(buf, "cat /proc/dri/0/vm");
           system(buf);
           break;
       case 'P':
           offset  = strtoul(optarg, &pt, 0);
           size    = strtoul(pt+1, NULL, 0);
           address = NULL;
           if ((r = drmMap(fd, offset, size, &address))) {
              drmError(r, argv[0]);
              return 1;
           }
           printf("0x%08lx:0x%04lx mapped at %p for pid %d\n",
                 offset, size, address, getpid());
           printf("===== /proc/dri/0/vma =====\n");
           sprintf(buf, "cat /proc/dri/0/vma");
           system(buf);
           mprotect((void *)offset, size, PROT_READ);
           printf("===== /proc/dri/0/vma =====\n");
           sprintf(buf, "cat /proc/dri/0/vma");
           system(buf);
           break;
       case 'w':
       case 'W':
           offset  = strtoul(optarg, &pt, 0);
           size    = strtoul(pt+1, NULL, 0);
           address = NULL;
           if ((r = drmMap(fd, offset, size, &address))) {
              drmError(r, argv[0]);
              return 1;
           }
           printf("0x%08lx:0x%04lx mapped at %p for pid %d\n",
                 offset, size, address, getpid());
           printf("===== /proc/%d/maps =====\n", getpid());
           sprintf(buf, "cat /proc/%d/maps", getpid());
           system(buf);
           printf("===== /proc/dri/0/mem =====\n");
           sprintf(buf, "cat /proc/dri/0/mem");
           system(buf);
           printf("===== /proc/dri/0/vma =====\n");
           sprintf(buf, "cat /proc/dri/0/vma");
           system(buf);
           printf("===== READING =====\n");
           for (i = 0; i < 0x10; i++)
              printf("%02x ", (unsigned int)((unsigned char *)address)[i]);
           printf("\n");
           if (c == 'w') {
              printf("===== WRITING =====\n");
              for (i = 0; i < size; i+=2) {
                  ((char *)address)[i]   = i & 0xff;
                  ((char *)address)[i+1] = i & 0xff;
              }
           }
           printf("===== READING =====\n");
           for (i = 0; i < 0x10; i++)
              printf("%02x ", (unsigned int)((unsigned char *)address)[i]);
           printf("\n");
           printf("===== /proc/dri/0/vma =====\n");
           sprintf(buf, "cat /proc/dri/0/vma");
           system(buf);
           break;
       case 'L':
           context = strtoul(optarg, &pt, 0);
           offset  = strtoul(pt+1, &pt, 0);
           size    = strtoul(pt+1, &pt, 0);
           loops   = strtoul(pt+1, NULL, 0);
           address = NULL;
           if ((r = drmMap(fd, offset, size, &address))) {
              drmError(r, argv[0]);
              return 1;
           }
           lock       = address;
#if 1
           {
              int            counter = 0;
              struct timeval loop_start, loop_end;
              struct timeval lock_start, lock_end;
              double         wt;
#define HISTOSIZE 9
              int            histo[HISTOSIZE];
              int            output = 0;
              int            fast   = 0;

              if (loops < 0) {
                  loops = -loops;
                  ++output;
              }

              for (i = 0; i < HISTOSIZE; i++) histo[i] = 0;

              gettimeofday(&loop_start, NULL);
              for (i = 0; i < loops; i++) {
                  gettimeofday(&lock_start, NULL);
                  DRM_LIGHT_LOCK_COUNT(fd,lock,context,fast);
                  gettimeofday(&lock_end, NULL);
                  DRM_UNLOCK(fd,lock,context);
                  ++counter;
                  wt = usec(&lock_end, &lock_start);
                  if      (wt <=      2.5) ++histo[8];
                  if      (wt <       5.0) ++histo[0];
                  else if (wt <      50.0) ++histo[1];
                  else if (wt <     500.0) ++histo[2];
                  else if (wt <    5000.0) ++histo[3];
                  else if (wt <   50000.0) ++histo[4];
                  else if (wt <  500000.0) ++histo[5];
                  else if (wt < 5000000.0) ++histo[6];
                  else                     ++histo[7];
                  if (output) printf( "%.2f uSec, %d fast\n", wt, fast);
              }
              gettimeofday(&loop_end, NULL);
              printf( "Average wait time = %.2f usec, %d fast\n",
                     usec(&loop_end, &loop_start) /  counter, fast);
              printf( "%9d <=     2.5 uS\n", histo[8]);
              printf( "%9d <        5 uS\n", histo[0]);
              printf( "%9d <       50 uS\n", histo[1]);
              printf( "%9d <      500 uS\n", histo[2]);
              printf( "%9d <     5000 uS\n", histo[3]);
              printf( "%9d <    50000 uS\n", histo[4]);
              printf( "%9d <   500000 uS\n", histo[5]);
              printf( "%9d <  5000000 uS\n", histo[6]);
              printf( "%9d >= 5000000 uS\n", histo[7]);
           }
#else
           printf( "before lock: 0x%08x\n", lock->lock);
           printf( "lock: 0x%08x\n", lock->lock);
           sleep(5);
           printf( "unlock: 0x%08x\n", lock->lock);
#endif
           break;
       default:
           fprintf( stderr, "Usage: drmstat [options]\n" );
           return 1;
       }

    return r; 
}

Here is the call graph for this function:

void process_sigio ( char *  device)

Definition at line 88 of file drmstat.c.

{
    int              fd;

    if ((fd = open(device, 0)) < 0) {
       drmError(-errno, __FUNCTION__);
       exit(1);
    }

    sigio_fd = fd;
    /*  drmInstallSIGIOHandler(fd, handler); */
    for (;;) sleep(60);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static double usec ( struct timeval *  end,
struct timeval *  start 
) [static]

Definition at line 56 of file drmstat.c.

{
    double e = end->tv_sec   * 1000000 + end->tv_usec;
    double s = start->tv_sec * 1000000 + start->tv_usec;

    return e - s;
}

Here is the caller graph for this function:

void xf86VDrvMsgVerb ( int  scrnIndex,
int  type,
int  verb,
const char *  format,
va_list  args 
)

Definition at line 429 of file drmstat.c.

{
       vfprintf(stderr, format, args);
}

Variable Documentation

int sigio_fd

Definition at line 54 of file drmstat.c.

int xf86ConfigDRI[10]

Definition at line 435 of file drmstat.c.