mirror of
https://github.com/varun-r-mallya/sysprof.git
synced 2026-02-12 16:10:54 +00:00
capture: add frame type for defining and setting counters
We might want to add a CTRADD type later on, for relative values rather than absolute. But this should get us started. Simply define counters upfront, and then set them during the capture process. Obviously, we need to come up with a good way to visualize this information in the UI.
This commit is contained in:
@ -539,7 +539,7 @@ sp_capture_reader_read_sample (SpCaptureReader *self)
|
|||||||
|
|
||||||
sample = (SpCaptureSample *)(gpointer)&self->buf[self->pos];
|
sample = (SpCaptureSample *)(gpointer)&self->buf[self->pos];
|
||||||
|
|
||||||
if (self->endian != G_BYTE_ORDER)
|
if (G_UNLIKELY (self->endian != G_BYTE_ORDER))
|
||||||
{
|
{
|
||||||
guint i;
|
guint i;
|
||||||
|
|
||||||
@ -552,6 +552,105 @@ sp_capture_reader_read_sample (SpCaptureReader *self)
|
|||||||
return sample;
|
return sample;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const SpCaptureFrameCounterDefine *
|
||||||
|
sp_capture_reader_read_counter_define (SpCaptureReader *self)
|
||||||
|
{
|
||||||
|
SpCaptureFrameCounterDefine *def;
|
||||||
|
|
||||||
|
g_assert (self != NULL);
|
||||||
|
g_assert ((self->pos % SP_CAPTURE_ALIGN) == 0);
|
||||||
|
g_assert (self->pos <= self->bufsz);
|
||||||
|
|
||||||
|
if (!sp_capture_reader_ensure_space_for (self, sizeof *def))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
def = (SpCaptureFrameCounterDefine *)(gpointer)&self->buf[self->pos];
|
||||||
|
|
||||||
|
if (def->frame.type != SP_CAPTURE_FRAME_CTRDEF)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (def->frame.len < sizeof *def)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (G_UNLIKELY (self->endian != G_BYTE_ORDER))
|
||||||
|
def->n_counters = GUINT16_SWAP_LE_BE (def->n_counters);
|
||||||
|
|
||||||
|
if (def->frame.len < (sizeof *def + (sizeof (SpCaptureFrameCounterDefine) * def->n_counters)))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (!sp_capture_reader_ensure_space_for (self, def->frame.len))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
def = (SpCaptureFrameCounterDefine *)(gpointer)&self->buf[self->pos];
|
||||||
|
|
||||||
|
if (G_UNLIKELY (self->endian != G_BYTE_ORDER))
|
||||||
|
{
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
for (i = 0; i < def->n_counters; i++)
|
||||||
|
{
|
||||||
|
def->counters[i].id = GUINT32_SWAP_LE_BE (def->counters[i].id);
|
||||||
|
def->counters[i].value = GUINT64_SWAP_LE_BE (def->counters[i].value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self->pos += def->frame.len;
|
||||||
|
|
||||||
|
return def;
|
||||||
|
}
|
||||||
|
|
||||||
|
const SpCaptureFrameCounterSet *
|
||||||
|
sp_capture_reader_read_counter_set (SpCaptureReader *self)
|
||||||
|
{
|
||||||
|
SpCaptureFrameCounterSet *set;
|
||||||
|
|
||||||
|
g_assert (self != NULL);
|
||||||
|
g_assert ((self->pos % SP_CAPTURE_ALIGN) == 0);
|
||||||
|
g_assert (self->pos <= self->bufsz);
|
||||||
|
|
||||||
|
if (!sp_capture_reader_ensure_space_for (self, sizeof *set))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
set = (SpCaptureFrameCounterSet *)(gpointer)&self->buf[self->pos];
|
||||||
|
|
||||||
|
if (set->frame.type != SP_CAPTURE_FRAME_CTRSET)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (set->frame.len < sizeof *set)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (self->endian != G_BYTE_ORDER)
|
||||||
|
set->n_values = GUINT16_SWAP_LE_BE (set->n_values);
|
||||||
|
|
||||||
|
if (set->frame.len < (sizeof *set + (sizeof (SpCaptureCounterValues) * set->n_values)))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (!sp_capture_reader_ensure_space_for (self, set->frame.len))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
set = (SpCaptureFrameCounterSet *)(gpointer)&self->buf[self->pos];
|
||||||
|
|
||||||
|
if (G_UNLIKELY (self->endian != G_BYTE_ORDER))
|
||||||
|
{
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
for (i = 0; i < set->n_values; i++)
|
||||||
|
{
|
||||||
|
guint j;
|
||||||
|
|
||||||
|
for (j = 0; j < G_N_ELEMENTS (set->values[0].values); i++)
|
||||||
|
{
|
||||||
|
set->values[i].ids[j] = GUINT32_SWAP_LE_BE (set->values[i].ids[j]);
|
||||||
|
set->values[i].values[j] = GUINT64_SWAP_LE_BE (set->values[i].values[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self->pos += set->frame.len;
|
||||||
|
|
||||||
|
return set;
|
||||||
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
sp_capture_reader_reset (SpCaptureReader *self)
|
sp_capture_reader_reset (SpCaptureReader *self)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -43,6 +43,8 @@ const SpCaptureTimestamp *sp_capture_reader_read_timestamp (SpCaptureReader
|
|||||||
const SpCaptureProcess *sp_capture_reader_read_process (SpCaptureReader *self);
|
const SpCaptureProcess *sp_capture_reader_read_process (SpCaptureReader *self);
|
||||||
const SpCaptureSample *sp_capture_reader_read_sample (SpCaptureReader *self);
|
const SpCaptureSample *sp_capture_reader_read_sample (SpCaptureReader *self);
|
||||||
GHashTable *sp_capture_reader_read_jitmap (SpCaptureReader *self);
|
GHashTable *sp_capture_reader_read_jitmap (SpCaptureReader *self);
|
||||||
|
const SpCaptureFrameCounterDefine *sp_capture_reader_read_counter_define (SpCaptureReader *self);
|
||||||
|
const SpCaptureFrameCounterSet *sp_capture_reader_read_counter_set (SpCaptureReader *self);
|
||||||
gboolean sp_capture_reader_reset (SpCaptureReader *self);
|
gboolean sp_capture_reader_reset (SpCaptureReader *self);
|
||||||
gboolean sp_capture_reader_splice (SpCaptureReader *self,
|
gboolean sp_capture_reader_splice (SpCaptureReader *self,
|
||||||
SpCaptureWriter *dest,
|
SpCaptureWriter *dest,
|
||||||
|
|||||||
@ -54,6 +54,9 @@ typedef enum
|
|||||||
SP_CAPTURE_FRAME_FORK = 5,
|
SP_CAPTURE_FRAME_FORK = 5,
|
||||||
SP_CAPTURE_FRAME_EXIT = 6,
|
SP_CAPTURE_FRAME_EXIT = 6,
|
||||||
SP_CAPTURE_FRAME_JITMAP = 7,
|
SP_CAPTURE_FRAME_JITMAP = 7,
|
||||||
|
SP_CAPTURE_FRAME_CTRDEF = 8,
|
||||||
|
SP_CAPTURE_FRAME_CTRADD = 9,
|
||||||
|
SP_CAPTURE_FRAME_CTRSET = 10,
|
||||||
} SpCaptureFrameType;
|
} SpCaptureFrameType;
|
||||||
|
|
||||||
#pragma pack(push, 1)
|
#pragma pack(push, 1)
|
||||||
@ -126,6 +129,43 @@ typedef struct
|
|||||||
SpCaptureFrame frame;
|
SpCaptureFrame frame;
|
||||||
} SpCaptureTimestamp;
|
} SpCaptureTimestamp;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
gchar category[32];
|
||||||
|
gchar name[32];
|
||||||
|
gchar description[52];
|
||||||
|
guint32 id : 24;
|
||||||
|
guint8 type;
|
||||||
|
gint64 value;
|
||||||
|
} SpCaptureCounter;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
SpCaptureFrame frame;
|
||||||
|
guint16 n_counters;
|
||||||
|
guint64 padding : 48;
|
||||||
|
SpCaptureCounter counters[0];
|
||||||
|
} SpCaptureFrameCounterDefine;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* 96 bytes might seem a bit odd, but the counter frame header is 32
|
||||||
|
* bytes. So this makes a nice 2-cacheline aligned size which is
|
||||||
|
* useful when the number of counters is rather small.
|
||||||
|
*/
|
||||||
|
guint32 ids[8];
|
||||||
|
gint64 values[8];
|
||||||
|
} SpCaptureCounterValues;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
SpCaptureFrame frame;
|
||||||
|
guint16 n_values;
|
||||||
|
guint64 padding : 48;
|
||||||
|
SpCaptureCounterValues values[0];
|
||||||
|
} SpCaptureFrameCounterSet;
|
||||||
|
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
G_STATIC_ASSERT (sizeof (SpCaptureFileHeader) == 256);
|
G_STATIC_ASSERT (sizeof (SpCaptureFileHeader) == 256);
|
||||||
@ -137,6 +177,10 @@ G_STATIC_ASSERT (sizeof (SpCaptureSample) == 32);
|
|||||||
G_STATIC_ASSERT (sizeof (SpCaptureFork) == 28);
|
G_STATIC_ASSERT (sizeof (SpCaptureFork) == 28);
|
||||||
G_STATIC_ASSERT (sizeof (SpCaptureExit) == 24);
|
G_STATIC_ASSERT (sizeof (SpCaptureExit) == 24);
|
||||||
G_STATIC_ASSERT (sizeof (SpCaptureTimestamp) == 24);
|
G_STATIC_ASSERT (sizeof (SpCaptureTimestamp) == 24);
|
||||||
|
G_STATIC_ASSERT (sizeof (SpCaptureCounter) == 128);
|
||||||
|
G_STATIC_ASSERT (sizeof (SpCaptureCounterValues) == 96);
|
||||||
|
G_STATIC_ASSERT (sizeof (SpCaptureFrameCounterDefine) == 32);
|
||||||
|
G_STATIC_ASSERT (sizeof (SpCaptureFrameCounterSet) == 32);
|
||||||
|
|
||||||
static inline gint
|
static inline gint
|
||||||
sp_capture_address_compare (SpCaptureAddress a,
|
sp_capture_address_compare (SpCaptureAddress a,
|
||||||
|
|||||||
@ -176,6 +176,10 @@ static inline gboolean
|
|||||||
sp_capture_writer_ensure_space_for (SpCaptureWriter *self,
|
sp_capture_writer_ensure_space_for (SpCaptureWriter *self,
|
||||||
gsize len)
|
gsize len)
|
||||||
{
|
{
|
||||||
|
/* Check for max frame size */
|
||||||
|
if (len > G_MAXUSHORT)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
if ((self->len - self->pos) < len)
|
if ((self->len - self->pos) < len)
|
||||||
{
|
{
|
||||||
if (!sp_capture_writer_flush_data (self))
|
if (!sp_capture_writer_flush_data (self))
|
||||||
@ -952,3 +956,124 @@ sp_capture_writer_stat (SpCaptureWriter *self,
|
|||||||
|
|
||||||
*stat = self->stat;
|
*stat = self->stat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
sp_capture_writer_define_counters (SpCaptureWriter *self,
|
||||||
|
gint64 time,
|
||||||
|
gint cpu,
|
||||||
|
GPid pid,
|
||||||
|
const SpCaptureCounter *counters,
|
||||||
|
guint n_counters)
|
||||||
|
{
|
||||||
|
SpCaptureFrameCounterDefine *def;
|
||||||
|
gsize len;
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
g_assert (self != NULL);
|
||||||
|
g_assert (counters != NULL);
|
||||||
|
g_assert ((self->pos % SP_CAPTURE_ALIGN) == 0);
|
||||||
|
|
||||||
|
if (n_counters == 0)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
len = sizeof *def + (sizeof *counters * n_counters);
|
||||||
|
|
||||||
|
sp_capture_writer_realign (&len);
|
||||||
|
|
||||||
|
if (!sp_capture_writer_ensure_space_for (self, len))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
g_assert ((self->pos % SP_CAPTURE_ALIGN) == 0);
|
||||||
|
|
||||||
|
def = (SpCaptureFrameCounterDefine *)&self->buf[self->pos];
|
||||||
|
def->frame.len = len;
|
||||||
|
def->frame.cpu = cpu;
|
||||||
|
def->frame.pid = pid;
|
||||||
|
def->frame.time = time;
|
||||||
|
def->frame.type = SP_CAPTURE_FRAME_CTRDEF;
|
||||||
|
def->frame.padding = 0;
|
||||||
|
def->padding = 0;
|
||||||
|
def->n_counters = n_counters;
|
||||||
|
|
||||||
|
for (i = 0; i < n_counters; i++)
|
||||||
|
def->counters[i] = counters[i];
|
||||||
|
|
||||||
|
self->pos += def->frame.len;
|
||||||
|
|
||||||
|
g_assert ((self->pos % SP_CAPTURE_ALIGN) == 0);
|
||||||
|
|
||||||
|
self->stat.frame_count[SP_CAPTURE_FRAME_CTRDEF]++;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
sp_capture_writer_set_counters (SpCaptureWriter *self,
|
||||||
|
gint64 time,
|
||||||
|
gint cpu,
|
||||||
|
GPid pid,
|
||||||
|
const guint *counters_ids,
|
||||||
|
const gint64 *values,
|
||||||
|
guint n_counters)
|
||||||
|
{
|
||||||
|
SpCaptureFrameCounterSet *set;
|
||||||
|
gsize len;
|
||||||
|
guint n_groups;
|
||||||
|
guint group;
|
||||||
|
guint field;
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
g_assert (self != NULL);
|
||||||
|
g_assert (counters_ids != NULL);
|
||||||
|
g_assert (values != NULL || !n_counters);
|
||||||
|
g_assert ((self->pos % SP_CAPTURE_ALIGN) == 0);
|
||||||
|
|
||||||
|
if (n_counters == 0)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
/* Determine how many value groups we need */
|
||||||
|
n_groups = n_counters / G_N_ELEMENTS (set->values[0].values);
|
||||||
|
if ((n_groups * G_N_ELEMENTS (set->values[0].values)) != n_counters)
|
||||||
|
n_groups++;
|
||||||
|
|
||||||
|
len = sizeof *set + (n_groups * sizeof (SpCaptureCounterValues));
|
||||||
|
|
||||||
|
sp_capture_writer_realign (&len);
|
||||||
|
|
||||||
|
if (!sp_capture_writer_ensure_space_for (self, len))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
g_assert ((self->pos % SP_CAPTURE_ALIGN) == 0);
|
||||||
|
|
||||||
|
set = (SpCaptureFrameCounterSet *)&self->buf[self->pos];
|
||||||
|
set->frame.len = len;
|
||||||
|
set->frame.cpu = cpu;
|
||||||
|
set->frame.pid = pid;
|
||||||
|
set->frame.time = time;
|
||||||
|
set->frame.type = SP_CAPTURE_FRAME_CTRSET;
|
||||||
|
set->frame.padding = 0;
|
||||||
|
set->padding = 0;
|
||||||
|
set->n_values = n_groups;
|
||||||
|
|
||||||
|
for (i = 0, group = 0, field = 0; i < n_counters; i++)
|
||||||
|
{
|
||||||
|
set->values[group].ids[field] = counters_ids[i];
|
||||||
|
set->values[group].values[field] = values[i];
|
||||||
|
|
||||||
|
field++;
|
||||||
|
|
||||||
|
if (field == G_N_ELEMENTS (set->values[0].values))
|
||||||
|
{
|
||||||
|
field = 0;
|
||||||
|
group++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self->pos += set->frame.len;
|
||||||
|
|
||||||
|
g_assert ((self->pos % SP_CAPTURE_ALIGN) == 0);
|
||||||
|
|
||||||
|
self->stat.frame_count[SP_CAPTURE_FRAME_CTRSET]++;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|||||||
@ -81,6 +81,19 @@ gboolean sp_capture_writer_add_timestamp (SpCaptureWriter *
|
|||||||
gint64 time,
|
gint64 time,
|
||||||
gint cpu,
|
gint cpu,
|
||||||
GPid pid);
|
GPid pid);
|
||||||
|
gboolean sp_capture_writer_define_counters (SpCaptureWriter *self,
|
||||||
|
gint64 time,
|
||||||
|
gint cpu,
|
||||||
|
GPid pid,
|
||||||
|
const SpCaptureCounter *counters,
|
||||||
|
guint n_counters);
|
||||||
|
gboolean sp_capture_writer_set_counters (SpCaptureWriter *self,
|
||||||
|
gint64 time,
|
||||||
|
gint cpu,
|
||||||
|
GPid pid,
|
||||||
|
const guint *counters_ids,
|
||||||
|
const gint64 *values,
|
||||||
|
guint n_counters);
|
||||||
gboolean sp_capture_writer_flush (SpCaptureWriter *self);
|
gboolean sp_capture_writer_flush (SpCaptureWriter *self);
|
||||||
gboolean sp_capture_writer_save_as (SpCaptureWriter *self,
|
gboolean sp_capture_writer_save_as (SpCaptureWriter *self,
|
||||||
const gchar *filename,
|
const gchar *filename,
|
||||||
|
|||||||
@ -183,6 +183,89 @@ test_reader_basic (void)
|
|||||||
g_assert_cmpint (ex->child_pid, ==, i);
|
g_assert_cmpint (ex->child_pid, ==, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
SpCaptureCounter counters[10];
|
||||||
|
|
||||||
|
t = SP_CAPTURE_CURRENT_TIME;
|
||||||
|
|
||||||
|
for (i = 0; i < G_N_ELEMENTS (counters); i++)
|
||||||
|
{
|
||||||
|
g_snprintf (counters[i].category, sizeof counters[i].category, "cat%d", i);
|
||||||
|
g_snprintf (counters[i].name, sizeof counters[i].name, "name%d", i);
|
||||||
|
g_snprintf (counters[i].description, sizeof counters[i].description, "desc%d", i);
|
||||||
|
counters[i].id = i + 1;
|
||||||
|
counters[i].type = 0;
|
||||||
|
counters[i].value = i * G_GINT64_CONSTANT (100000000000);
|
||||||
|
}
|
||||||
|
|
||||||
|
r = sp_capture_writer_define_counters (writer, t, -1, -1, counters, G_N_ELEMENTS (counters));
|
||||||
|
g_assert_cmpint (r, ==, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
sp_capture_writer_flush (writer);
|
||||||
|
|
||||||
|
{
|
||||||
|
const SpCaptureFrameCounterDefine *def;
|
||||||
|
|
||||||
|
def = sp_capture_reader_read_counter_define (reader);
|
||||||
|
g_assert (def != NULL);
|
||||||
|
g_assert_cmpint (def->n_counters, ==, 10);
|
||||||
|
|
||||||
|
for (i = 0; i < def->n_counters; i++)
|
||||||
|
{
|
||||||
|
g_autofree gchar *cat = g_strdup_printf ("cat%d", i);
|
||||||
|
g_autofree gchar *name = g_strdup_printf ("name%d", i);
|
||||||
|
g_autofree gchar *desc = g_strdup_printf ("desc%d", i);
|
||||||
|
|
||||||
|
g_assert_cmpstr (def->counters[i].category, ==, cat);
|
||||||
|
g_assert_cmpstr (def->counters[i].name, ==, name);
|
||||||
|
g_assert_cmpstr (def->counters[i].description, ==, desc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < 1000; i++)
|
||||||
|
{
|
||||||
|
gint ids[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
|
||||||
|
gint64 values[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
|
||||||
|
|
||||||
|
r = sp_capture_writer_set_counters (writer, t, -1, -1, ids, values, G_N_ELEMENTS (values));
|
||||||
|
g_assert_cmpint (r, ==, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
sp_capture_writer_flush (writer);
|
||||||
|
|
||||||
|
for (i = 0; i < 1000; i++)
|
||||||
|
{
|
||||||
|
const SpCaptureFrameCounterSet *set;
|
||||||
|
|
||||||
|
set = sp_capture_reader_read_counter_set (reader);
|
||||||
|
g_assert (set != NULL);
|
||||||
|
|
||||||
|
/* 8 per chunk */
|
||||||
|
g_assert_cmpint (set->n_values, ==, 2);
|
||||||
|
|
||||||
|
g_assert_cmpint (1, ==, set->values[0].ids[0]);
|
||||||
|
g_assert_cmpint (2, ==, set->values[0].ids[1]);
|
||||||
|
g_assert_cmpint (3, ==, set->values[0].ids[2]);
|
||||||
|
g_assert_cmpint (4, ==, set->values[0].ids[3]);
|
||||||
|
g_assert_cmpint (5, ==, set->values[0].ids[4]);
|
||||||
|
g_assert_cmpint (6, ==, set->values[0].ids[5]);
|
||||||
|
g_assert_cmpint (7, ==, set->values[0].ids[6]);
|
||||||
|
g_assert_cmpint (8, ==, set->values[0].ids[7]);
|
||||||
|
g_assert_cmpint (9, ==, set->values[1].ids[0]);
|
||||||
|
g_assert_cmpint (10, ==, set->values[1].ids[1]);
|
||||||
|
g_assert_cmpint (1, ==, set->values[0].values[0]);
|
||||||
|
g_assert_cmpint (2, ==, set->values[0].values[1]);
|
||||||
|
g_assert_cmpint (3, ==, set->values[0].values[2]);
|
||||||
|
g_assert_cmpint (4, ==, set->values[0].values[3]);
|
||||||
|
g_assert_cmpint (5, ==, set->values[0].values[4]);
|
||||||
|
g_assert_cmpint (6, ==, set->values[0].values[5]);
|
||||||
|
g_assert_cmpint (7, ==, set->values[0].values[6]);
|
||||||
|
g_assert_cmpint (8, ==, set->values[0].values[7]);
|
||||||
|
g_assert_cmpint (9, ==, set->values[1].values[0]);
|
||||||
|
g_assert_cmpint (10, ==, set->values[1].values[1]);
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < 1000; i++)
|
for (i = 0; i < 1000; i++)
|
||||||
{
|
{
|
||||||
SpCaptureAddress addr;
|
SpCaptureAddress addr;
|
||||||
|
|||||||
Reference in New Issue
Block a user