コード例 #1
0
ファイル: sllist.c プロジェクト: pascal-p/c
int list_ins_next(sllist_t *lst, sllistItm_t *itm, const void *data) {
  //sllistItm_t *plitm = (sllistItm_t *) malloc(sizeof(sllistItm_t));
  sllistItm_t *plitm = xmalloc0(sizeof(sllistItm_t));

  // test that allocation was successful, if not return -1
  if (plitm == NULL) return -1;

  // OK now, cast to avoid warning: assigning to 'void *' from 'const void *' discards qualifiers
  plitm->data = (void *) data;

  // insertion - 4 cases
  if (lst->size == 0) {
    // (1) empty list, so actually itm is NULL
    plitm->next = lst->tail;
    lst->tail = lst->head = plitm;
  } 
  else if (itm == NULL) {
    // (2) list_size >0 => list is not empty, but itm == NULL
    //     => insertion at the head
    plitm->next = lst->head;
    lst->head   = plitm;
  }
  else {
    // (3) and (4)
    plitm->next = itm->next;
    itm->next   = plitm;
    if (plitm->next == NULL) lst->tail = plitm;
  }
  // insertion OK, increase the size list by 1
  lst->size++;
  return 0;
}
コード例 #2
0
ファイル: img.c プロジェクト: apetrunev/imgalg-opencl
struct img_ctx *img_ctx_new(int w, int h, img_type_t type, color_type_t color)
{
	struct img_ctx *c;
	int len;

	c = xmalloc(sizeof(*c));
	
	c->type = type;
	c->w = w;
	c->h = h;

	len = w*h;
		
	switch (type) {
	case TYPE_GRAY:
		c->pix = xmalloc0(len*sizeof(*(c->pix)));
		/* initialize pixels to spcified color */
		if (color != C_NONE)
			memset(c->pix, color, len*sizeof(*(c->pix)));
		break;
	case TYPE_RGB:
		c->r = xmalloc(len*sizeof(*(c->r)));
		c->g = xmalloc(len*sizeof(*(c->g)));
		c->b = xmalloc(len*sizeof(*(c->b)));
		break;
	default:
		abort();	 
	}	

	return c;
}
コード例 #3
0
struct gputop_hash_table *
gputop_hash_table_create(void *mem_ctx,
                         uint32_t (*key_hash_function)(const void *key),
                         bool (*key_equals_function)(const void *a,
                                                     const void *b))
{
    struct gputop_hash_table *ht;

    ht = xmalloc(sizeof(struct gputop_hash_table));
    if (ht == NULL)
        return NULL;

    ht->size_index = 0;
    ht->size = hash_sizes[ht->size_index].size;
    ht->rehash = hash_sizes[ht->size_index].rehash;
    ht->max_entries = hash_sizes[ht->size_index].max_entries;
    ht->key_hash_function = key_hash_function;
    ht->key_equals_function = key_equals_function;
    ht->table = xmalloc0(sizeof (struct gputop_hash_entry) * ht->size);
    ht->entries = 0;
    ht->deleted_entries = 0;
    ht->deleted_key = &deleted_key_value;

    if (ht->table == NULL) {
        free(ht);
        return NULL;
    }

    return ht;
}
コード例 #4
0
ファイル: gputop-perf.c プロジェクト: sergioamr/gputop
bool
gputop_perf_oa_trace_open(gputop_perf_query_type_t query_type)
{
    int period_exponent;
    double duration = 5.0; /* seconds */
    uint64_t period_ns;
    uint64_t n_samples;
    char *error = NULL;

    assert(gputop_current_perf_query == NULL);

    if (!gputop_perf_initialize())
	return false;

    current_user = &trace_user;

    gputop_current_perf_query = &perf_queries[query_type];

    /* The timestamp for HSW+ increments every 80ns
     *
     * The period_exponent gives a sampling period as follows:
     *   sample_period = 80ns * 2^(period_exponent + 1)
     *
     * Sample ~ every 1 millisecond...
     */
    period_exponent = 11;

    gputop_current_perf_stream =
	gputop_perf_open_i915_oa_query(gputop_current_perf_query,
				       period_exponent,
				       32 * page_size,
				       perf_ready_cb,
				       false,
				       &error);
    if (!gputop_current_perf_stream) {
	gputop_log(GPUTOP_LOG_LEVEL_HIGH, error, -1);
	free(error);

	gputop_current_perf_query = NULL;
	return false;
    }

    period_ns = 80 * (2 << period_exponent);
    n_samples = (duration  * 1000000000.0) / period_ns;
    n_samples *= 1.25; /* a bit of leeway */

    gputop_perf_trace_buffer_size = n_samples * gputop_current_perf_query->perf_raw_size;
    gputop_perf_trace_buffer = xmalloc0(gputop_perf_trace_buffer_size);
    gputop_perf_trace_head = gputop_perf_trace_buffer;
    gputop_perf_trace_empty = true;
    gputop_perf_trace_full = false;

    return true;
}
コード例 #5
0
ファイル: rtorrent-cli.c プロジェクト: dkasak/rtorrent-cli
static torrent_array *torrent_array_new(size_t size) {
    torrent_array *array = xmalloc(sizeof(torrent_array));

    array->torrents = xmalloc(sizeof(torrent_info*)*size);

    for (size_t i = 0; i < size; ++i) {
        array->torrents[i] = xmalloc0(sizeof(torrent_info));
    }
    array->size = size;
    return array;
}
コード例 #6
0
ファイル: sllist.c プロジェクト: pascal-p/c
int list_new(sllist_t **lst, 
             int (*match)(const void *k1, const void *k2), 
             void (*destroy)(void *data),
             void (*cb)(const void *data)) {
  /*
   *lst = (sllist_t *) malloc(sizeof(sllist_t));

   if (*lst == NULL)
     return -1;    // fail to allocate space for the new list
  */
  *lst = xmalloc0(sizeof(sllist_t));

  list_init(*lst, match, destroy, cb);
  return 0;
}
コード例 #7
0
ファイル: database.c プロジェクト: jens-na/abook-call
static void
adjust_list_capacity()
{
	if(list_capacity < 1)
		list_capacity = INITIAL_LIST_CAPACITY;
	else if(items >= list_capacity)
		list_capacity *= 2;
	else if(list_capacity / 2 > items)
		list_capacity /= 2;
	else
		return;

	if(database)
		database = xrealloc(database,sizeof(list_item) * list_capacity);
	else /* allocate memory _and_ initialize pointers to NULL */
		database = xmalloc0(sizeof(list_item) * list_capacity);

	selected = xrealloc(selected, list_capacity);
}
コード例 #8
0
ファイル: pg_basebackup.c プロジェクト: Epictetus/postgres
/*
 * Initiate background process for receiving xlog during the backup.
 * The background stream will use its own database connection so we can
 * stream the logfile in parallel with the backups.
 */
static void
StartLogStreamer(char *startpos, uint32 timeline, char *sysidentifier)
{
	logstreamer_param *param;

	param = xmalloc0(sizeof(logstreamer_param));
	param->timeline = timeline;
	param->sysidentifier = sysidentifier;

	/* Convert the starting position */
	if (sscanf(startpos, "%X/%X", &param->startptr.xlogid, &param->startptr.xrecoff) != 2)
	{
		fprintf(stderr, _("%s: invalid format of xlog location: %s\n"),
				progname, startpos);
		disconnect_and_exit(1);
	}
	/* Round off to even segment position */
	param->startptr.xrecoff -= param->startptr.xrecoff % XLOG_SEG_SIZE;

#ifndef WIN32
	/* Create our background pipe */
	if (pgpipe(bgpipe) < 0)
	{
		fprintf(stderr, _("%s: could not create pipe for background process: %s\n"),
				progname, strerror(errno));
		disconnect_and_exit(1);
	}
#endif

	/* Get a second connection */
	param->bgconn = GetConnection();

	/*
	 * Always in plain format, so we can write to basedir/pg_xlog. But the
	 * directory entry in the tar file may arrive later, so make sure it's
	 * created before we start.
	 */
	snprintf(param->xlogdir, sizeof(param->xlogdir), "%s/pg_xlog", basedir);
	verify_dir_is_empty_or_create(param->xlogdir);

	/*
	 * Start a child process and tell it to start streaming. On Unix, this is
	 * a fork(). On Windows, we create a thread.
	 */
#ifndef WIN32
	bgchild = fork();
	if (bgchild == 0)
	{
		/* in child process */
		exit(LogStreamerMain(param));
	}
	else if (bgchild < 0)
	{
		fprintf(stderr, _("%s: could not create background process: %s\n"),
				progname, strerror(errno));
		disconnect_and_exit(1);
	}

	/*
	 * Else we are in the parent process and all is well.
	 */
#else							/* WIN32 */
	bgchild = _beginthreadex(NULL, 0, (void *) LogStreamerMain, param, 0, NULL);
	if (bgchild == 0)
	{
		fprintf(stderr, _("%s: could not create background thread: %s\n"),
				progname, strerror(errno));
		disconnect_and_exit(1);
	}
#endif
}
コード例 #9
0
ファイル: receivelog.c プロジェクト: AllenDou/postgresql
/*
 * Open a new WAL file in the specified directory. Store the name
 * (not including the full directory) in namebuf. Assumes there is
 * enough room in this buffer...
 *
 * The file will be padded to 16Mb with zeroes.
 */
static int
open_walfile(XLogRecPtr startpoint, uint32 timeline, char *basedir,
			 char *namebuf)
{
	int			f;
	char		fn[MAXPGPATH];
	struct stat statbuf;
	char	   *zerobuf;
	int			bytes;

	XLogFileName(namebuf, timeline, startpoint.xlogid,
				 startpoint.xrecoff / XLOG_SEG_SIZE);

	snprintf(fn, sizeof(fn), "%s/%s.partial", basedir, namebuf);
	f = open(fn, O_WRONLY | O_CREAT | PG_BINARY, S_IRUSR | S_IWUSR);
	if (f == -1)
	{
		fprintf(stderr,
				_("%s: could not open transaction log file \"%s\": %s\n"),
				progname, fn, strerror(errno));
		return -1;
	}

	/*
	 * Verify that the file is either empty (just created), or a complete
	 * XLogSegSize segment. Anything in between indicates a corrupt file.
	 */
	if (fstat(f, &statbuf) != 0)
	{
		fprintf(stderr,
				_("%s: could not stat transaction log file \"%s\": %s\n"),
				progname, fn, strerror(errno));
		close(f);
		return -1;
	}
	if (statbuf.st_size == XLogSegSize)
		return f;				/* File is open and ready to use */
	if (statbuf.st_size != 0)
	{
		fprintf(stderr,
				_("%s: transaction log file \"%s\" has %d bytes, should be 0 or %d\n"),
				progname, fn, (int) statbuf.st_size, XLogSegSize);
		close(f);
		return -1;
	}

	/* New, empty, file. So pad it to 16Mb with zeroes */
	zerobuf = xmalloc0(XLOG_BLCKSZ);
	for (bytes = 0; bytes < XLogSegSize; bytes += XLOG_BLCKSZ)
	{
		if (write(f, zerobuf, XLOG_BLCKSZ) != XLOG_BLCKSZ)
		{
			fprintf(stderr,
					_("%s: could not pad transaction log file \"%s\": %s\n"),
					progname, fn, strerror(errno));
			free(zerobuf);
			close(f);
			unlink(fn);
			return -1;
		}
	}
	free(zerobuf);

	if (lseek(f, SEEK_SET, 0) != 0)
	{
		fprintf(stderr,
				_("%s: could not seek to beginning of transaction log file \"%s\": %s\n"),
				progname, fn, strerror(errno));
		close(f);
		return -1;
	}
	return f;
}
コード例 #10
0
ファイル: streamutil.c プロジェクト: lhcezar/postgres
/*
 * Connect to the server. Returns a valid PGconn pointer if connected,
 * or NULL on non-permanent error. On permanent error, the function will
 * call exit(1) directly.
 */
PGconn *
GetConnection(void)
{
	PGconn	   *tmpconn;
	int			argcount = 4;	/* dbname, replication, fallback_app_name,
								 * password */
	int			i;
	const char **keywords;
	const char **values;
	char	   *password = NULL;
	const char *tmpparam;

	if (dbhost)
		argcount++;
	if (dbuser)
		argcount++;
	if (dbport)
		argcount++;

	keywords = xmalloc0((argcount + 1) * sizeof(*keywords));
	values = xmalloc0((argcount + 1) * sizeof(*values));

	keywords[0] = "dbname";
	values[0] = "replication";
	keywords[1] = "replication";
	values[1] = "true";
	keywords[2] = "fallback_application_name";
	values[2] = progname;
	i = 3;
	if (dbhost)
	{
		keywords[i] = "host";
		values[i] = dbhost;
		i++;
	}
	if (dbuser)
	{
		keywords[i] = "user";
		values[i] = dbuser;
		i++;
	}
	if (dbport)
	{
		keywords[i] = "port";
		values[i] = dbport;
		i++;
	}

	while (true)
	{
		if (password)
			free(password);

		if (dbpassword)
		{
			/*
			 * We've saved a password when a previous connection succeeded,
			 * meaning this is the call for a second session to the same
			 * database, so just forcibly reuse that password.
			 */
			keywords[argcount - 1] = "password";
			values[argcount - 1] = dbpassword;
			dbgetpassword = -1; /* Don't try again if this fails */
		}
		else if (dbgetpassword == 1)
		{
			password = simple_prompt(_("Password: "******"password";
			values[argcount - 1] = password;
		}

		tmpconn = PQconnectdbParams(keywords, values, true);

		/*
		 * If there is too little memory even to allocate the PGconn object
		 * and PQconnectdbParams returns NULL, we call exit(1) directly.
		 */
		if (!tmpconn)
		{
			fprintf(stderr, _("%s: could not connect to server\n"),
					progname);
			exit(1);
		}

		if (PQstatus(tmpconn) == CONNECTION_BAD &&
			PQconnectionNeedsPassword(tmpconn) &&
			dbgetpassword != -1)
		{
			dbgetpassword = 1;	/* ask for password next time */
			PQfinish(tmpconn);
			continue;
		}

		if (PQstatus(tmpconn) != CONNECTION_OK)
		{
			fprintf(stderr, _("%s: could not connect to server: %s\n"),
					progname, PQerrorMessage(tmpconn));
			PQfinish(tmpconn);
			free(values);
			free(keywords);
			return NULL;
		}

		/* Connection ok! */
		free(values);
		free(keywords);

		/*
		 * Ensure we have the same value of integer timestamps as the server
		 * we are connecting to.
		 */
		tmpparam = PQparameterStatus(tmpconn, "integer_datetimes");
		if (!tmpparam)
		{
			fprintf(stderr, _("%s: could not determine server setting for integer_datetimes\n"),
					progname);
			PQfinish(tmpconn);
			exit(1);
		}

#ifdef HAVE_INT64_TIMESTAMP
		if (strcmp(tmpparam, "on") != 0)
#else
		if (strcmp(tmpparam, "off") != 0)
#endif
		{
			fprintf(stderr, _("%s: integer_datetimes compile flag does not match server\n"),
					progname);
			PQfinish(tmpconn);
			exit(1);
		}

		/* Store the password for next run */
		if (password)
			dbpassword = password;
		return tmpconn;
	}
}
コード例 #11
0
ファイル: gputop-perf.c プロジェクト: sergioamr/gputop
struct gputop_perf_stream *
gputop_perf_open_generic_counter(int pid,
				 int cpu,
				 uint64_t type,
				 uint64_t config,
				 size_t perf_buffer_size,
				 void (*ready_cb)(uv_poll_t *poll, int status, int events),
				 bool overwrite,
				 char **error)
{
    struct gputop_perf_stream *stream;
    struct perf_event_attr attr;
    int event_fd;
    uint8_t *mmap_base;
    int expected_max_samples;
    size_t sample_size = 0;

    memset(&attr, 0, sizeof(attr));
    attr.size = sizeof(attr);
    attr.type = type;
    attr.config = config;

    attr.sample_type = PERF_SAMPLE_READ | PERF_SAMPLE_TIME;
    attr.sample_period = 1;

    attr.watermark = true;
    attr.wakeup_watermark = perf_buffer_size / 4;

    event_fd = perf_event_open(&attr,
			       pid,
			       cpu,
			       -1, /* group fd */
			       PERF_FLAG_FD_CLOEXEC); /* flags */
    if (event_fd == -1) {
	asprintf(error, "Error opening i915_oa perf event: %m\n");
	return NULL;
    }

    /* NB: A read-write mapping ensures the kernel will stop writing data when
     * the buffer is full, and will report samples as lost. */
    mmap_base = mmap(NULL,
		     perf_buffer_size + page_size,
		     PROT_READ | PROT_WRITE, MAP_SHARED, event_fd, 0);
    if (mmap_base == MAP_FAILED) {
	asprintf(error, "Error mapping circular buffer, %m\n");
	close (event_fd);
	return NULL;
    }

    stream = xmalloc0(sizeof(*stream));
    stream->type = GPUTOP_STREAM_PERF;
    stream->ref_count = 1;
    stream->fd = event_fd;
    stream->perf.buffer = mmap_base + page_size;
    stream->perf.buffer_size = perf_buffer_size;
    stream->perf.mmap_page = (void *)mmap_base;

    sample_size =
	sizeof(struct perf_event_header) +
	8; /* _TIME */
    expected_max_samples = (stream->perf.buffer_size / sample_size) * 1.2;

    memset(&stream->perf.header_buf, 0, sizeof(stream->perf.header_buf));

    stream->overwrite = overwrite;
    if (overwrite) {
	stream->perf.header_buf.len = expected_max_samples;
	stream->perf.header_buf.offsets =
	    xmalloc(sizeof(uint32_t) * expected_max_samples);
    }

    stream->fd_poll.data = stream;
    uv_poll_init(gputop_ui_loop, &stream->fd_poll, stream->fd);
    uv_poll_start(&stream->fd_poll, UV_READABLE, ready_cb);

    return stream;
}
コード例 #12
0
ファイル: gputop-perf.c プロジェクト: sergioamr/gputop
struct gputop_perf_stream *
gputop_perf_open_trace(int pid,
		       int cpu,
		       const char *system,
		       const char *event,
		       size_t trace_struct_size,
		       size_t perf_buffer_size,
		       void (*ready_cb)(uv_poll_t *poll, int status, int events),
		       bool overwrite,
		       char **error)
{
    struct gputop_perf_stream *stream;
    struct perf_event_attr attr;
    int event_fd;
    uint8_t *mmap_base;
    int expected_max_samples;
    char *filename = NULL;
    int id = 0;
    size_t sample_size = 0;

    asprintf(&filename, "/sys/kernel/debug/tracing/events/%s/%s/id", system, event);
    if (filename) {
	struct stat st;

	if (stat(filename, &st) < 0) {
	    int err = errno;

	    free(filename);
	    filename = NULL;

	    if (err == EPERM) {
		asprintf(error, "Permission denied to open tracepoint %s:%s"
			 " (Linux tracepoints require root privileges)",
			 system, event);
		return NULL;
	    } else {
		asprintf(error, "Failed to open tracepoint %s:%s: %s",
			 system, event,
			 strerror(err));
		return NULL;
	    }
	}
    }

    id = read_file_uint64(filename);
    free(filename);
    filename = NULL;

    memset(&attr, 0, sizeof(attr));
    attr.size = sizeof(attr);
    attr.type = PERF_TYPE_TRACEPOINT;
    attr.config = id;

    attr.sample_type = PERF_SAMPLE_RAW | PERF_SAMPLE_TIME;
    attr.sample_period = 1;

    attr.watermark = true;
    attr.wakeup_watermark = perf_buffer_size / 4;

    event_fd = perf_event_open(&attr,
			       pid,
			       cpu,
			       -1, /* group fd */
			       PERF_FLAG_FD_CLOEXEC); /* flags */
    if (event_fd == -1) {
	asprintf(error, "Error opening i915_oa perf event: %m\n");
	return NULL;
    }

    /* NB: A read-write mapping ensures the kernel will stop writing data when
     * the buffer is full, and will report samples as lost. */
    mmap_base = mmap(NULL,
		     perf_buffer_size + page_size,
		     PROT_READ | PROT_WRITE, MAP_SHARED, event_fd, 0);
    if (mmap_base == MAP_FAILED) {
	asprintf(error, "Error mapping circular buffer, %m\n");
	close (event_fd);
	return NULL;
    }

    stream = xmalloc0(sizeof(*stream));
    stream->type = GPUTOP_STREAM_PERF;
    stream->ref_count = 1;
    stream->fd = event_fd;
    stream->perf.buffer = mmap_base + page_size;
    stream->perf.buffer_size = perf_buffer_size;
    stream->perf.mmap_page = (void *)mmap_base;

    sample_size =
	sizeof(struct perf_event_header) +
	8 /* _TIME */ +
	trace_struct_size; /* _RAW */

    expected_max_samples = (stream->perf.buffer_size / sample_size) * 1.2;

    memset(&stream->perf.header_buf, 0, sizeof(stream->perf.header_buf));

    stream->overwrite = overwrite;
    if (overwrite) {
	stream->perf.header_buf.len = expected_max_samples;
	stream->perf.header_buf.offsets =
	    xmalloc(sizeof(uint32_t) * expected_max_samples);
    }

    stream->fd_poll.data = stream;
    uv_poll_init(gputop_ui_loop, &stream->fd_poll, stream->fd);
    uv_poll_start(&stream->fd_poll, UV_READABLE, ready_cb);

    return stream;
}
コード例 #13
0
ファイル: gputop-perf.c プロジェクト: sergioamr/gputop
struct gputop_perf_stream *
gputop_open_i915_perf_oa_query(struct gputop_perf_query *query,
			       int period_exponent,
			       size_t perf_buffer_size,
			       void (*ready_cb)(uv_poll_t *poll, int status, int events),
			       bool overwrite,
			       char **error)
{
    struct gputop_perf_stream *stream;
    struct i915_perf_open_param param;
    struct i915_perf_oa_attr oa_attr;
    int ret;

    memset(&param, 0, sizeof(param));
    memset(&oa_attr, 0, sizeof(oa_attr));

    param.type = I915_PERF_OA_EVENT;

    param.flags = 0;
    param.flags |= I915_PERF_FLAG_FD_CLOEXEC;
    param.flags |= I915_PERF_FLAG_FD_NONBLOCK;

    param.sample_flags = I915_PERF_SAMPLE_OA_REPORT;

    oa_attr.size = sizeof(oa_attr);
    oa_attr.flags |= I915_OA_FLAG_PERIODIC;
    oa_attr.oa_format = query->perf_oa_format;
    oa_attr.metrics_set = query->perf_oa_metrics_set;
    oa_attr.oa_timer_exponent = period_exponent;
    param.attr = (uintptr_t)&oa_attr;

    ret = perf_ioctl(drm_fd, I915_IOCTL_PERF_OPEN, &param);

    if (ret == -1) {
	asprintf(error, "Error opening i915_oa perf event: %m\n");
	return NULL;
    }

    stream = xmalloc0(sizeof(*stream));
    stream->type = GPUTOP_STREAM_I915_PERF;
    stream->ref_count = 1;
    stream->query = query;

    stream->fd = param.fd;

    /* We double buffer the samples we read from the kernel so
     * we can maintain a stream->last pointer for calculating
     * counter deltas */
    stream->oa.buf_sizes = MAX_I915_PERF_OA_SAMPLE_SIZE * 100;
    stream->oa.bufs[0] = xmalloc0(stream->oa.buf_sizes);
    stream->oa.bufs[1] = xmalloc0(stream->oa.buf_sizes);

    stream->overwrite = overwrite;
    if (overwrite) {
#warning "TODO: support flight-recorder mode"
	assert(0);
    }

    stream->fd_poll.data = stream;
    uv_poll_init(gputop_ui_loop, &stream->fd_poll, stream->fd);
    uv_poll_start(&stream->fd_poll, UV_READABLE, ready_cb);

    return stream;
}
コード例 #14
0
ファイル: gputop-perf.c プロジェクト: sergioamr/gputop
struct gputop_perf_stream *
gputop_perf_open_i915_oa_query(struct gputop_perf_query *query,
			       int period_exponent,
			       size_t perf_buffer_size,
			       void (*ready_cb)(uv_poll_t *poll, int status, int events),
			       bool overwrite,
			       char **error)
{
    struct gputop_perf_stream *stream;
    i915_oa_attr_t oa_attr;
    struct perf_event_attr attr;
    int event_fd;
    uint8_t *mmap_base;
    int expected_max_samples;

    memset(&attr, 0, sizeof(attr));
    attr.size = sizeof(attr);
    attr.type = lookup_i915_oa_id();

    attr.sample_type = PERF_SAMPLE_RAW;
    attr.sample_period = 1;

    attr.watermark = true;
    attr.wakeup_watermark = perf_buffer_size / 4;

    memset(&oa_attr, 0, sizeof(oa_attr));
    oa_attr.size = sizeof(oa_attr);

    oa_attr.format = query->perf_oa_format;
    oa_attr.metrics_set = query->perf_oa_metrics_set;
    oa_attr.timer_exponent = period_exponent;

    attr.config = (uint64_t)&oa_attr;

    event_fd = perf_event_open(&attr,
			       -1, /* pid */
			       0, /* cpu */
			       -1, /* group fd */
			       PERF_FLAG_FD_CLOEXEC); /* flags */
    if (event_fd == -1) {
	asprintf(error, "Error opening i915_oa perf event: %m\n");
	return NULL;
    }

    /* NB: A read-write mapping ensures the kernel will stop writing data when
     * the buffer is full, and will report samples as lost. */
    mmap_base = mmap(NULL,
		     perf_buffer_size + page_size,
		     PROT_READ | PROT_WRITE, MAP_SHARED, event_fd, 0);
    if (mmap_base == MAP_FAILED) {
	asprintf(error, "Error mapping circular buffer, %m\n");
	close (event_fd);
	return NULL;
    }

    stream = xmalloc0(sizeof(*stream));
    stream->type = GPUTOP_STREAM_PERF;
    stream->ref_count = 1;
    stream->query = query;
    stream->fd = event_fd;
    stream->perf.buffer = mmap_base + page_size;
    stream->perf.buffer_size = perf_buffer_size;
    stream->perf.mmap_page = (void *)mmap_base;

    expected_max_samples =
	(stream->perf.buffer_size / MAX_CORE_PERF_OA_SAMPLE_SIZE) * 1.2;

    memset(&stream->perf.header_buf, 0, sizeof(stream->perf.header_buf));

    stream->overwrite = overwrite;
    if (overwrite) {
	stream->perf.header_buf.len = expected_max_samples;
	stream->perf.header_buf.offsets =
	    xmalloc(sizeof(uint32_t) * expected_max_samples);
    }

    stream->fd_poll.data = stream;
    uv_poll_init(gputop_ui_loop, &stream->fd_poll, stream->fd);
    uv_poll_start(&stream->fd_poll, UV_READABLE, ready_cb);

    return stream;
}
コード例 #15
0
ファイル: database.c プロジェクト: jens-na/abook-call
list_item
item_create()
{
	return xmalloc0(ITEM_SIZE);
}