*
* Copyright 2010 Novell, Inc (http://www.novell.com)
* Copyright 2011 Xamarin Inc (http://www.xamarin.com)
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
*/
#include <config.h>
#include <mono/utils/atomic.h>
#include <mono/utils/mono-membar.h>
#include <mono/utils/mono-counters.h>
-#include <mono/utils/mono-mutex.h>
+#include <mono/utils/mono-os-mutex.h>
#include <mono/utils/mono-conc-hashtable.h>
#include <mono/utils/lock-free-queue.h>
#include <stdlib.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
+#ifdef HAVE_SCHED_GETAFFINITY
+#include <sched.h>
+#endif
#include <fcntl.h>
#include <errno.h>
#if defined(HOST_WIN32) || defined(DISABLE_SOCKETS)
#include <unistd.h>
#include <sys/syscall.h>
-#include "perf_event.h"
#ifdef ENABLE_PERF_EVENTS
+#include <linux/perf_event.h>
+
#define USE_PERF_EVENTS 1
static int read_perf_mmap (MonoProfiler* prof, int cpu);
* be done to the format.
*/
+// Pending data to be written to the log, for a single thread.
+// Threads periodically flush their own LogBuffers by calling safe_send
struct _LogBuffer {
+ // Next (older) LogBuffer in processing queue
LogBuffer *next;
+
uint64_t time_base;
uint64_t last_time;
uintptr_t ptr_base;
uintptr_t last_method;
uintptr_t obj_base;
uintptr_t thread_id;
- unsigned char* data_end;
- unsigned char* data;
int locked;
- int size;
int call_depth;
+
+ // Bytes allocated for this LogBuffer
+ int size;
+
+ // Start of currently unused space in buffer
+ unsigned char* cursor;
+
+ // Pointer to start-of-structure-plus-size (for convenience)
+ unsigned char* buf_end;
+
+ // Start of data in buffer. Contents follow "buffer format" described above.
unsigned char buf [1];
};
#define ENTER_LOG(lb,str) if ((lb)->locked) {ign_res (write(2, str, strlen(str))); ign_res (write(2, "\n", 1));return;} else {(lb)->locked++;}
#define EXIT_LOG(lb) (lb)->locked--;
+// Shared queue of sample snapshots taken at signal time.
+// The queue is written into by signal handlers for all threads;
+// the helper thread later unqueues and writes into its own LogBuffer.
typedef struct _StatBuffer StatBuffer;
struct _StatBuffer {
+ // Next (older) StatBuffer in processing queue
StatBuffer *next;
+
+ // Bytes allocated for this StatBuffer
uintptr_t size;
- uintptr_t *data_end;
- uintptr_t *data;
+
+ // Start of currently unused space in buffer
+ uintptr_t *cursor;
+
+ // Pointer to start-of-structure-plus-size (for convenience)
+ uintptr_t *buf_end;
+
+ // Start of data in buffer.
+ // Data consists of a series of sample packets consisting of:
+ // 1 ptrword: Metadata
+ // Low 8 bits: COUNT, the count of native stack frames in this sample (currently always 1)
+ // Next 8 bits: MBT_COUNT, the count of managed stacks in this sample
+ // Next 8 bits: TYPE. See "sampling sources" enum in proflog.h. Usually SAMPLE_CYCLES (1)
+ // 1 ptrword: Thread ID
+ // 1 ptrword: Timestamp
+ // COUNT ptrwords: Native stack frames
+ // Each word is an IP (first is IP where the signal did the interruption)
+ // MBT_COUNT * 4 ptrwords: Managed stack frames (AsyncFrameInfo, repacked)
+ // Word 1: MonoMethod ptr
+ // Word 2: MonoDomain ptr
+ // Word 3: Base address of method
+ // Word 4: Offset within method
uintptr_t buf [1];
};
pstrdup (const char *s)
{
int len = strlen (s) + 1;
- char *p = malloc (len);
+ char *p = (char *)malloc (len);
memcpy (p, s, len);
return p;
}
static StatBuffer*
create_stat_buffer (void)
{
- StatBuffer* buf = alloc_buffer (BUFFER_SIZE);
+ StatBuffer* buf = (StatBuffer *)alloc_buffer (BUFFER_SIZE);
buf->size = BUFFER_SIZE;
- buf->data_end = (uintptr_t*)((unsigned char*)buf + buf->size);
- buf->data = buf->buf;
+ buf->buf_end = (uintptr_t*)((unsigned char*)buf + buf->size);
+ buf->cursor = buf->buf;
return buf;
}
static LogBuffer*
create_buffer (void)
{
- LogBuffer* buf = alloc_buffer (BUFFER_SIZE);
+ LogBuffer* buf = (LogBuffer *)alloc_buffer (BUFFER_SIZE);
buf->size = BUFFER_SIZE;
buf->time_base = current_time ();
buf->last_time = buf->time_base;
- buf->data_end = (unsigned char*)buf + buf->size;
- buf->data = buf->buf;
+ buf->buf_end = (unsigned char*)buf + buf->size;
+ buf->cursor = buf->buf;
return buf;
}
static LogBuffer *
ensure_logbuf_inner (LogBuffer *old, int bytes)
{
- if (old && old->data + bytes + 100 < old->data_end)
+ if (old && old->cursor + bytes + 100 < old->buf_end)
return old;
- LogBuffer *new = create_buffer ();
- new->thread_id = thread_id ();
- new->next = old;
+ LogBuffer *new_ = (LogBuffer *)create_buffer ();
+ new_->thread_id = thread_id ();
+ new_->next = old;
if (old)
- new->call_depth = old->call_depth;
+ new_->call_depth = old->call_depth;
- return new;
+ return new_;
}
static LogBuffer*
ensure_logbuf (int bytes)
{
LogBuffer *old = TLS_GET (LogBuffer, tlsbuffer);
- LogBuffer *new = ensure_logbuf_inner (old, bytes);
+ LogBuffer *new_ = ensure_logbuf_inner (old, bytes);
- if (new == old)
+ if (new_ == old)
return old; // Still enough space.
- TLS_SET (tlsbuffer, new);
+ TLS_SET (tlsbuffer, new_);
init_thread ();
- return new;
+ return new_;
}
static void
emit_byte (LogBuffer *logbuffer, int value)
{
- logbuffer->data [0] = value;
- logbuffer->data++;
- assert (logbuffer->data <= logbuffer->data_end);
+ logbuffer->cursor [0] = value;
+ logbuffer->cursor++;
+ assert (logbuffer->cursor <= logbuffer->buf_end);
}
static void
emit_value (LogBuffer *logbuffer, int value)
{
- encode_uleb128 (value, logbuffer->data, &logbuffer->data);
- assert (logbuffer->data <= logbuffer->data_end);
+ encode_uleb128 (value, logbuffer->cursor, &logbuffer->cursor);
+ assert (logbuffer->cursor <= logbuffer->buf_end);
}
static void
// printf ("time went backwards\n");
//if (tdiff > 1000000)
// printf ("large time offset: %llu\n", tdiff);
- encode_uleb128 (tdiff, logbuffer->data, &logbuffer->data);
+ encode_uleb128 (tdiff, logbuffer->cursor, &logbuffer->cursor);
/*if (tdiff != decode_uleb128 (p, &p))
printf ("incorrect encoding: %llu\n", tdiff);*/
logbuffer->last_time = value;
- assert (logbuffer->data <= logbuffer->data_end);
+ assert (logbuffer->cursor <= logbuffer->buf_end);
}
static void
emit_svalue (LogBuffer *logbuffer, int64_t value)
{
- encode_sleb128 (value, logbuffer->data, &logbuffer->data);
- assert (logbuffer->data <= logbuffer->data_end);
+ encode_sleb128 (value, logbuffer->cursor, &logbuffer->cursor);
+ assert (logbuffer->cursor <= logbuffer->buf_end);
}
static void
emit_uvalue (LogBuffer *logbuffer, uint64_t value)
{
- encode_uleb128 (value, logbuffer->data, &logbuffer->data);
- assert (logbuffer->data <= logbuffer->data_end);
+ encode_uleb128 (value, logbuffer->cursor, &logbuffer->cursor);
+ assert (logbuffer->cursor <= logbuffer->buf_end);
}
static void
if (!logbuffer->ptr_base)
logbuffer->ptr_base = (uintptr_t)ptr;
emit_svalue (logbuffer, (intptr_t)ptr - logbuffer->ptr_base);
- assert (logbuffer->data <= logbuffer->data_end);
+ assert (logbuffer->cursor <= logbuffer->buf_end);
}
static void
logbuffer->method_base = (intptr_t)method;
logbuffer->last_method = (intptr_t)method;
}
- encode_sleb128 ((intptr_t)((char*)method - (char*)logbuffer->last_method), logbuffer->data, &logbuffer->data);
+ encode_sleb128 ((intptr_t)((char*)method - (char*)logbuffer->last_method), logbuffer->cursor, &logbuffer->cursor);
logbuffer->last_method = (intptr_t)method;
- assert (logbuffer->data <= logbuffer->data_end);
+ assert (logbuffer->cursor <= logbuffer->buf_end);
}
/*
*/
//g_assert (ji);
- MethodInfo *info = malloc (sizeof (MethodInfo));
+ MethodInfo *info = (MethodInfo *)malloc (sizeof (MethodInfo));
info->method = method;
info->ji = ji;
if (!logbuffer->obj_base)
logbuffer->obj_base = (uintptr_t)ptr >> 3;
emit_svalue (logbuffer, ((uintptr_t)ptr >> 3) - logbuffer->obj_base);
- assert (logbuffer->data <= logbuffer->data_end);
+ assert (logbuffer->cursor <= logbuffer->buf_end);
}
static void
static void
send_buffer (MonoProfiler *prof, GPtrArray *methods, LogBuffer *buffer)
{
- WriterQueueEntry *entry = calloc (1, sizeof (WriterQueueEntry));
+ WriterQueueEntry *entry = (WriterQueueEntry *)calloc (1, sizeof (WriterQueueEntry));
mono_lock_free_queue_node_init (&entry->node, FALSE);
entry->methods = methods;
entry->buffer = buffer;
if (buf->next)
dump_buffer (profiler, buf->next);
p = write_int32 (p, BUF_ID);
- p = write_int32 (p, buf->data - buf->buf);
+ p = write_int32 (p, buf->cursor - buf->buf);
p = write_int64 (p, buf->time_base);
p = write_int64 (p, buf->ptr_base);
p = write_int64 (p, buf->obj_base);
#if defined (HAVE_SYS_ZLIB)
if (profiler->gzfile) {
gzwrite (profiler->gzfile, hbuf, p - hbuf);
- gzwrite (profiler->gzfile, buf->buf, buf->data - buf->buf);
+ gzwrite (profiler->gzfile, buf->buf, buf->cursor - buf->buf);
} else {
#endif
fwrite (hbuf, p - hbuf, 1, profiler->file);
- fwrite (buf->buf, buf->data - buf->buf, 1, profiler->file);
+ fwrite (buf->buf, buf->cursor - buf->buf, 1, profiler->file);
fflush (profiler->file);
#if defined (HAVE_SYS_ZLIB)
}
static mono_bool
walk_stack (MonoMethod *method, int32_t native_offset, int32_t il_offset, mono_bool managed, void* data)
{
- FrameData *frame = data;
+ FrameData *frame = (FrameData *)data;
if (method && frame->count < num_frames) {
frame->il_offsets [frame->count] = il_offset;
frame->native_offsets [frame->count] = native_offset;
emit_value (logbuffer, 0); /* flags */
emit_value (logbuffer, data->count);
//if (*p != data.count) {
- // printf ("bad num frames enc at %d: %d -> %d\n", count, data.count, *p); printf ("frames end: %p->%p\n", p, logbuffer->data); exit(0);}
+ // printf ("bad num frames enc at %d: %d -> %d\n", count, data.count, *p); printf ("frames end: %p->%p\n", p, logbuffer->cursor); exit(0);}
while (data->count) {
emit_method_as_ptr (prof, logbuffer, data->methods [--data->count]);
}
char buf [1024];
char *p;
push_nesting (buf, klass);
- p = malloc (strlen (buf) + 1);
+ p = (char *)malloc (strlen (buf) + 1);
strcpy (p, buf);
return p;
}
emit_byte (logbuffer, TYPE_IMAGE);
emit_ptr (logbuffer, image);
emit_value (logbuffer, 0); /* flags */
- memcpy (logbuffer->data, name, nlen);
- logbuffer->data += nlen;
+ memcpy (logbuffer->cursor, name, nlen);
+ logbuffer->cursor += nlen;
//printf ("loaded image %p (%s)\n", image, name);
EXIT_LOG (logbuffer);
if (logbuffer->next)
emit_byte (logbuffer, TYPE_IMAGE);
emit_ptr (logbuffer, image);
emit_value (logbuffer, 0); /* flags */
- memcpy (logbuffer->data, name, nlen);
- logbuffer->data += nlen;
+ memcpy (logbuffer->cursor, name, nlen);
+ logbuffer->cursor += nlen;
EXIT_LOG (logbuffer);
if (logbuffer->next)
emit_byte (logbuffer, TYPE_ASSEMBLY);
emit_ptr (logbuffer, assembly);
emit_value (logbuffer, 0); /* flags */
- memcpy (logbuffer->data, name, nlen);
- logbuffer->data += nlen;
+ memcpy (logbuffer->cursor, name, nlen);
+ logbuffer->cursor += nlen;
EXIT_LOG (logbuffer);
mono_free (name);
emit_byte (logbuffer, TYPE_ASSEMBLY);
emit_ptr (logbuffer, assembly);
emit_value (logbuffer, 0); /* flags */
- memcpy (logbuffer->data, name, nlen);
- logbuffer->data += nlen;
+ memcpy (logbuffer->cursor, name, nlen);
+ logbuffer->cursor += nlen;
EXIT_LOG (logbuffer);
mono_free (name);
emit_ptr (logbuffer, klass);
emit_ptr (logbuffer, image);
emit_value (logbuffer, 0); /* flags */
- memcpy (logbuffer->data, name, nlen);
- logbuffer->data += nlen;
+ memcpy (logbuffer->cursor, name, nlen);
+ logbuffer->cursor += nlen;
//printf ("loaded class %p (%s)\n", klass, name);
if (runtime_inited)
mono_free (name);
emit_ptr (logbuffer, klass);
emit_ptr (logbuffer, image);
emit_value (logbuffer, 0); /* flags */
- memcpy (logbuffer->data, name, nlen);
- logbuffer->data += nlen;
+ memcpy (logbuffer->cursor, name, nlen);
+ logbuffer->cursor += nlen;
EXIT_LOG (logbuffer);
if (runtime_inited)
char *name;
LogBuffer *logbuffer;
if (type == MONO_PROFILER_CODE_BUFFER_SPECIFIC_TRAMPOLINE) {
- name = data;
+ name = (char *)data;
nlen = strlen (name) + 1;
} else {
name = NULL;
emit_ptr (logbuffer, buffer);
emit_value (logbuffer, size);
if (name) {
- memcpy (logbuffer->data, name, nlen);
- logbuffer->data += nlen;
+ memcpy (logbuffer->cursor, name, nlen);
+ logbuffer->cursor += nlen;
}
EXIT_LOG (logbuffer);
process_requests (prof);
emit_byte (logbuffer, TYPE_DOMAIN);
emit_ptr (logbuffer, (void*)(uintptr_t) mono_domain_get_id (domain));
emit_value (logbuffer, 0); /* flags */
- memcpy (logbuffer->data, name, nlen);
- logbuffer->data += nlen;
+ memcpy (logbuffer->cursor, name, nlen);
+ logbuffer->cursor += nlen;
EXIT_LOG (logbuffer);
if (logbuffer->next)
emit_byte (logbuffer, TYPE_THREAD);
emit_ptr (logbuffer, (void*)tid);
emit_value (logbuffer, 0); /* flags */
- memcpy (logbuffer->data, name, len);
- logbuffer->data += len;
+ memcpy (logbuffer->cursor, name, len);
+ logbuffer->cursor += len;
EXIT_LOG (logbuffer);
if (logbuffer->next)
static mono_bool
async_walk_stack (MonoMethod *method, MonoDomain *domain, void *base_address, int offset, void *data)
{
- AsyncFrameData *frame = data;
+ AsyncFrameData *frame = (AsyncFrameData *)data;
if (frame->count < num_frames) {
frame->data [frame->count].method = method;
frame->data [frame->count].domain = domain;
if (!sbuf)
return;
/* flush the buffer at 1 second intervals */
- if (sbuf->data > sbuf->buf && (elapsed - sbuf->buf [2]) > 100000) {
+ if (sbuf->cursor > sbuf->buf && (elapsed - sbuf->buf [2]) > 100000) {
timedout = 1;
}
/* overflow: 400 slots is a big enough number to reduce the chance of losing this event if many
* threads hit this same spot at the same time
*/
- if (timedout || (sbuf->data + 400 >= sbuf->data_end)) {
+ if (timedout || (sbuf->cursor + 400 >= sbuf->buf_end)) {
StatBuffer *oldsb, *foundsb;
sbuf = create_stat_buffer ();
do {
oldsb = profiler->stat_buffers;
sbuf->next = oldsb;
- foundsb = InterlockedCompareExchangePointer ((void * volatile*)&profiler->stat_buffers, sbuf, oldsb);
+ foundsb = (StatBuffer *)InterlockedCompareExchangePointer ((void * volatile*)&profiler->stat_buffers, sbuf, oldsb);
} while (foundsb != oldsb);
if (do_debug)
ign_res (write (2, "overflow\n", 9));
}
}
do {
- old_data = sbuf->data;
+ old_data = sbuf->cursor;
new_data = old_data + SAMPLE_EVENT_SIZE_IN_SLOTS (bt_data.count);
- data = InterlockedCompareExchangePointer ((void * volatile*)&sbuf->data, new_data, old_data);
+ if (new_data > sbuf->buf_end)
+ return; /* Not enough room in buf to hold this event-- lost event */
+ data = (uintptr_t *)InterlockedCompareExchangePointer ((void * volatile*)&sbuf->cursor, new_data, old_data);
} while (data != old_data);
- if (old_data >= sbuf->data_end)
- return; /* lost event */
+
old_data [0] = 1 | (sample_type << 16) | (bt_data.count << 8);
old_data [1] = thread_id ();
old_data [2] = elapsed;
size_code_pages *= 2;
if (size_code_pages == 0)
size_code_pages = 16;
- n = calloc (sizeof (uintptr_t) * size_code_pages, 1);
+ n = (uintptr_t *)calloc (sizeof (uintptr_t) * size_code_pages, 1);
for (i = 0; i < old_size; ++i) {
if (code_pages [i])
add_code_page (n, size_code_pages, code_pages [i]);
emit_svalue (logbuffer, load_addr);
emit_uvalue (logbuffer, offset);
emit_uvalue (logbuffer, size);
- memcpy (logbuffer->data, filename, len);
- logbuffer->data += len;
+ memcpy (logbuffer->cursor, filename, len);
+ logbuffer->cursor += len;
}
#endif
emit_byte (logbuffer, TYPE_SAMPLE | TYPE_SAMPLE_USYM);
emit_ptr (logbuffer, (void*)value);
emit_value (logbuffer, size);
- memcpy (logbuffer->data, name, len);
- logbuffer->data += len;
+ memcpy (logbuffer->cursor, name, len);
+ logbuffer->cursor += len;
}
/* ELF code crashes on some systems. */
g_ptr_array_set_size (prof->sorted_sample_events, 0);
- for (uintptr_t *sample = sbuf->buf; sample < sbuf->data;) {
+ for (uintptr_t *sample = sbuf->buf; sample < sbuf->cursor;) {
int count = sample [0] & 0xff;
int mbt_count = (sample [0] & 0xff00) >> 8;
- if (sample + SAMPLE_EVENT_SIZE_IN_SLOTS (mbt_count) > sbuf->data)
+ if (sample + SAMPLE_EVENT_SIZE_IN_SLOTS (mbt_count) > sbuf->cursor)
break;
g_ptr_array_add (prof->sorted_sample_events, sample);
g_ptr_array_sort (prof->sorted_sample_events, compare_sample_events);
for (guint sidx = 0; sidx < prof->sorted_sample_events->len; sidx++) {
- uintptr_t *sample = g_ptr_array_index (prof->sorted_sample_events, sidx);
+ uintptr_t *sample = (uintptr_t *)g_ptr_array_index (prof->sorted_sample_events, sidx);
int count = sample [0] & 0xff;
int mbt_count = (sample [0] & 0xff00) >> 8;
int type = sample [0] >> 16;
void *address = (void*)managed_sample_base [i * 4 + 2];
if (!method) {
- MonoJitInfo *ji = mono_jit_info_table_find (domain, address);
+ g_assert (domain);
+ MonoJitInfo *ji = mono_jit_info_table_find (domain, (char *)address);
if (ji)
managed_sample_base [i * 4 + 0] = (uintptr_t)mono_jit_info_get_method (ji);
static int
mono_cpu_count (void)
{
- int count = 0;
#ifdef PLATFORM_ANDROID
/* Android tries really hard to save power by powering off CPUs on SMP phones which
* means the normal way to query cpu count returns a wrong value with userspace API.
* Instead we use /sys entries to query the actual hardware CPU count.
*/
+ int count = 0;
char buffer[8] = {'\0'};
int present = open ("/sys/devices/system/cpu/present", O_RDONLY);
/* Format of the /sys entry is a cpulist of indexes which in the case
if (count > 0)
return count + 1;
#endif
+
+#if defined(HOST_ARM) || defined (HOST_ARM64)
+
+ /* ARM platforms tries really hard to save power by powering off CPUs on SMP phones which
+ * means the normal way to query cpu count returns a wrong value with userspace API. */
+
+#ifdef _SC_NPROCESSORS_CONF
+ {
+ int count = sysconf (_SC_NPROCESSORS_CONF);
+ if (count > 0)
+ return count;
+ }
+#endif
+
+#else
+
+#ifdef HAVE_SCHED_GETAFFINITY
+ {
+ cpu_set_t set;
+ if (sched_getaffinity (getpid (), sizeof (set), &set) == 0)
+ return CPU_COUNT (&set);
+ }
+#endif
#ifdef _SC_NPROCESSORS_ONLN
- count = sysconf (_SC_NPROCESSORS_ONLN);
- if (count > 0)
- return count;
+ {
+ int count = sysconf (_SC_NPROCESSORS_ONLN);
+ if (count > 0)
+ return count;
+ }
#endif
+
+#endif /* defined(HOST_ARM) || defined (HOST_ARM64) */
+
#ifdef USE_SYSCTL
{
+ int count;
int mib [2];
size_t len = sizeof (int);
mib [0] = CTL_HW;
if (!counters_initialized)
return;
- mono_mutex_lock (&counters_mutex);
+ mono_os_mutex_lock (&counters_mutex);
for (agent = counters; agent; agent = agent->next) {
if (agent->counter == counter) {
free (agent->value);
agent->value = NULL;
}
- mono_mutex_unlock (&counters_mutex);
+ mono_os_mutex_unlock (&counters_mutex);
return;
}
}
- agent = malloc (sizeof (MonoCounterAgent));
+ agent = (MonoCounterAgent *)malloc (sizeof (MonoCounterAgent));
agent->counter = counter;
agent->value = NULL;
agent->value_size = 0;
item->next = agent;
}
- mono_mutex_unlock (&counters_mutex);
+ mono_os_mutex_unlock (&counters_mutex);
}
static mono_bool
{
assert (!counters_initialized);
- mono_mutex_init (&counters_mutex);
+ mono_os_mutex_init (&counters_mutex);
counters_initialized = TRUE;
if (!counters_initialized)
return;
- mono_mutex_lock (&counters_mutex);
+ mono_os_mutex_lock (&counters_mutex);
for (agent = counters; agent; agent = agent->next) {
if (agent->emitted)
}
if (!len) {
- mono_mutex_unlock (&counters_mutex);
+ mono_os_mutex_unlock (&counters_mutex);
return;
}
safe_send (profiler, logbuffer);
- mono_mutex_unlock (&counters_mutex);
+ mono_os_mutex_unlock (&counters_mutex);
}
static void
buffer_size = 8;
buffer = calloc (1, buffer_size);
- mono_mutex_lock (&counters_mutex);
+ mono_os_mutex_lock (&counters_mutex);
size =
EVENT_SIZE /* event */ +
safe_send (profiler, logbuffer);
- mono_mutex_unlock (&counters_mutex);
+ mono_os_mutex_unlock (&counters_mutex);
}
typedef struct _PerfCounterAgent PerfCounterAgent;
if (!counters_initialized)
return;
- mono_mutex_lock (&counters_mutex);
+ mono_os_mutex_lock (&counters_mutex);
/* mark all perfcounters as deleted, foreach will unmark them as necessary */
for (pcagent = perfcounters; pcagent; pcagent = pcagent->next)
safe_send (profiler, logbuffer);
- mono_mutex_unlock (&counters_mutex);
+ mono_os_mutex_unlock (&counters_mutex);
}
static void
if (name == NULL || *name == '\0')
return g_strdup ("");
- if (!(ret = new_name = calloc (strlen (name) * 4 + 1, sizeof (char))))
+ if (!(ret = new_name = (char *)calloc (strlen (name) * 4 + 1, sizeof (char))))
return NULL;
do {
method_name = mono_method_get_name (method);
if (coverage_data->len != 0) {
- CoverageEntry *entry = coverage_data->pdata[0];
+ CoverageEntry *entry = (CoverageEntry *)coverage_data->pdata[0];
first_filename = entry->filename ? entry->filename : "";
} else
first_filename = "";
safe_send (prof, logbuffer);
for (i = 0; i < coverage_data->len; i++) {
- CoverageEntry *entry = coverage_data->pdata[i];
+ CoverageEntry *entry = (CoverageEntry *)coverage_data->pdata[i];
logbuffer = ensure_logbuf (
EVENT_SIZE /* event */ +
static void
get_coverage_for_image (MonoImage *image, int *number_of_methods, guint *fully_covered, int *partially_covered)
{
- MonoLockFreeQueue *image_methods = mono_conc_hashtable_lookup (image_to_methods, image);
+ MonoLockFreeQueue *image_methods = (MonoLockFreeQueue *)mono_conc_hashtable_lookup (image_to_methods, image);
*number_of_methods = mono_image_get_table_rows (image, MONO_TABLE_METHOD);
if (image_methods)
COVERAGE_DEBUG(fprintf (stderr, "Coverage: Started dump\n");)
method_id = 0;
- mono_mutex_lock (&coverage_mutex);
+ mono_os_mutex_lock (&coverage_mutex);
mono_conc_hashtable_foreach (coverage_assemblies, build_assembly_buffer, prof);
mono_conc_hashtable_foreach (coverage_classes, build_class_buffer, prof);
mono_conc_hashtable_foreach (coverage_methods, build_method_buffer, prof);
- mono_mutex_unlock (&coverage_mutex);
+ mono_os_mutex_unlock (&coverage_mutex);
COVERAGE_DEBUG(fprintf (stderr, "Coverage: Finished dump\n");)
}
if (mono_conc_hashtable_lookup (suppressed_assemblies, (gpointer) mono_image_get_name (image)))
return;
- mono_mutex_lock (&coverage_mutex);
+ mono_os_mutex_lock (&coverage_mutex);
mono_conc_hashtable_insert (entered_methods, method, method);
- mono_mutex_unlock (&coverage_mutex);
+ mono_os_mutex_unlock (&coverage_mutex);
}
static MonoLockFreeQueueNode *
create_method_node (MonoMethod *method)
{
- MethodNode *node = g_malloc (sizeof (MethodNode));
+ MethodNode *node = (MethodNode *)g_malloc (sizeof (MethodNode));
mono_lock_free_queue_node_init ((MonoLockFreeQueueNode *) node, FALSE);
node->method = method;
static gboolean
coverage_filter (MonoProfiler *prof, MonoMethod *method)
{
+ MonoError error;
MonoClass *klass;
MonoImage *image;
MonoAssembly *assembly;
has_positive = FALSE;
found = FALSE;
for (guint i = 0; i < prof->coverage_filters->len; ++i) {
- char *filter = g_ptr_array_index (prof->coverage_filters, i);
+ char *filter = (char *)g_ptr_array_index (prof->coverage_filters, i);
if (filter [0] == '+') {
filter = &filter [1];
if (has_positive && !found) {
COVERAGE_DEBUG(fprintf (stderr, " Positive match was not found\n");)
- mono_mutex_lock (&coverage_mutex);
+ mono_os_mutex_lock (&coverage_mutex);
mono_conc_hashtable_insert (filtered_classes, klass, klass);
- mono_mutex_unlock (&coverage_mutex);
+ mono_os_mutex_unlock (&coverage_mutex);
g_free (fqn);
g_free (classname);
for (guint i = 0; i < prof->coverage_filters->len; ++i) {
// FIXME: Is substring search sufficient?
- char *filter = g_ptr_array_index (prof->coverage_filters, i);
+ char *filter = (char *)g_ptr_array_index (prof->coverage_filters, i);
if (filter [0] == '+')
continue;
if (strstr (fqn, filter) != NULL) {
COVERAGE_DEBUG(fprintf (stderr, "matched\n");)
- mono_mutex_lock (&coverage_mutex);
+ mono_os_mutex_lock (&coverage_mutex);
mono_conc_hashtable_insert (filtered_classes, klass, klass);
- mono_mutex_unlock (&coverage_mutex);
+ mono_os_mutex_unlock (&coverage_mutex);
g_free (fqn);
g_free (classname);
}
COVERAGE_DEBUG(fprintf (stderr, " Handling coverage for %s\n", mono_method_get_name (method));)
- header = mono_method_get_header (method);
+ header = mono_method_get_header_checked (method, &error);
+ mono_error_cleanup (&error);
mono_method_header_get_code (header, &code_size, NULL);
assembly = mono_image_get_assembly (image);
- mono_mutex_lock (&coverage_mutex);
+ mono_os_mutex_lock (&coverage_mutex);
mono_conc_hashtable_insert (coverage_methods, method, method);
mono_conc_hashtable_insert (coverage_assemblies, assembly, assembly);
- mono_mutex_unlock (&coverage_mutex);
+ mono_os_mutex_unlock (&coverage_mutex);
- image_methods = mono_conc_hashtable_lookup (image_to_methods, image);
+ image_methods = (MonoLockFreeQueue *)mono_conc_hashtable_lookup (image_to_methods, image);
if (image_methods == NULL) {
- image_methods = g_malloc (sizeof (MonoLockFreeQueue));
+ image_methods = (MonoLockFreeQueue *)g_malloc (sizeof (MonoLockFreeQueue));
mono_lock_free_queue_init (image_methods);
- mono_mutex_lock (&coverage_mutex);
+ mono_os_mutex_lock (&coverage_mutex);
mono_conc_hashtable_insert (image_to_methods, image, image_methods);
- mono_mutex_unlock (&coverage_mutex);
+ mono_os_mutex_unlock (&coverage_mutex);
}
node = create_method_node (method);
mono_lock_free_queue_enqueue (image_methods, node);
- class_methods = mono_conc_hashtable_lookup (coverage_classes, klass);
+ class_methods = (MonoLockFreeQueue *)mono_conc_hashtable_lookup (coverage_classes, klass);
if (class_methods == NULL) {
- class_methods = g_malloc (sizeof (MonoLockFreeQueue));
+ class_methods = (MonoLockFreeQueue *)g_malloc (sizeof (MonoLockFreeQueue));
mono_lock_free_queue_init (class_methods);
- mono_mutex_lock (&coverage_mutex);
+ mono_os_mutex_lock (&coverage_mutex);
mono_conc_hashtable_insert (coverage_classes, klass, class_methods);
- mono_mutex_unlock (&coverage_mutex);
+ mono_os_mutex_unlock (&coverage_mutex);
}
node = create_method_node (method);
if (filesize > MAX_FILE_SIZE)
return NULL;
- buffer = g_malloc ((filesize + 1) * sizeof (char));
+ buffer = (char *)g_malloc ((filesize + 1) * sizeof (char));
while ((bytes_read = fread (buffer + offset, 1, LINE_BUFFER_SIZE, stream)) > 0)
offset += bytes_read;
COVERAGE_DEBUG(fprintf (stderr, "Coverage initialized\n");)
- mono_mutex_init (&coverage_mutex);
+ mono_os_mutex_init (&coverage_mutex);
coverage_methods = mono_conc_hashtable_new (NULL, NULL);
coverage_assemblies = mono_conc_hashtable_new (NULL, NULL);
coverage_classes = mono_conc_hashtable_new (NULL, NULL);
fclose (prof->file);
mono_conc_hashtable_destroy (prof->method_table);
- mono_mutex_destroy (&prof->method_table_mutex);
+ mono_os_mutex_destroy (&prof->method_table_mutex);
if (coverage_initialized) {
mono_conc_hashtable_destroy (coverage_methods);
mono_conc_hashtable_destroy (entered_methods);
mono_conc_hashtable_destroy (image_to_methods);
mono_conc_hashtable_destroy (suppressed_assemblies);
- mono_mutex_destroy (&coverage_mutex);
+ mono_os_mutex_destroy (&coverage_mutex);
}
free (prof);
1900 + ts->tm_year, 1 + ts->tm_mon, ts->tm_mday, ts->tm_hour, ts->tm_min, ts->tm_sec);
s_date = strlen (time_buf);
s_pid = strlen (pid_buf);
- d = res = malloc (strlen (filename) + s_date * count_dates + s_pid * count_pids);
+ d = res = (char *)malloc (strlen (filename) + s_date * count_dates + s_pid * count_pids);
for (p = filename; *p; p++) {
if (*p != '%') {
*d++ = *p;
static void*
helper_thread (void* arg)
{
- MonoProfiler* prof = arg;
+ MonoProfiler* prof = (MonoProfiler *)arg;
int command_socket;
int len;
char buf [64];
static void *
writer_thread (void *arg)
{
- MonoProfiler *prof = arg;
+ MonoProfiler *prof = (MonoProfiler *)arg;
mono_threads_attach_tools_thread ();
* methods have metadata emitted before they're referenced.
*/
for (guint i = 0; i < entry->methods->len; i++) {
- MethodInfo *info = g_ptr_array_index (entry->methods, i);
+ MethodInfo *info = (MethodInfo *)g_ptr_array_index (entry->methods, i);
if (mono_conc_hashtable_lookup (prof->method_table, info->method))
continue;
* method lists will just be empty for the rest of the
* app's lifetime.
*/
- mono_mutex_lock (&prof->method_table_mutex);
+ mono_os_mutex_lock (&prof->method_table_mutex);
mono_conc_hashtable_insert (prof->method_table, info->method, info->method);
- mono_mutex_unlock (&prof->method_table_mutex);
+ mono_os_mutex_unlock (&prof->method_table_mutex);
char *name = mono_method_full_name (info->method, 1);
int nlen = strlen (name) + 1;
emit_ptr (method_buffer, cstart);
emit_value (method_buffer, csize);
- memcpy (method_buffer->data, name, nlen);
- method_buffer->data += nlen;
+ memcpy (method_buffer->cursor, name, nlen);
+ method_buffer->cursor += nlen;
mono_free (name);
free (info);
MonoProfiler *prof;
char *nf;
int force_delete = 0;
- prof = calloc (1, sizeof (MonoProfiler));
+ prof = (MonoProfiler *)calloc (1, sizeof (MonoProfiler));
prof->command_port = command_port;
if (filename && *filename == '-') {
nf = new_filename (filename);
if (do_report) {
int s = strlen (nf) + 32;
- char *p = malloc (s);
+ char *p = (char *)malloc (s);
snprintf (p, s, "|mprof-report '--out=%s' -", nf);
free (nf);
nf = p;
#endif
mono_lock_free_queue_init (&prof->writer_queue);
- mono_mutex_init (&prof->method_table_mutex);
+ mono_os_mutex_init (&prof->method_table_mutex);
prof->method_table = mono_conc_hashtable_new (NULL, NULL);
if (do_coverage)
} else {
l = end - opt;
}
- val = malloc (l + 1);
+ val = (char *)malloc (l + 1);
memcpy (val, opt, l);
val [l] = 0;
*rval = val;
mono_profiler_install_statistical (mono_sample_hit);
}
- mono_profiler_set_events (events);
+ mono_profiler_set_events ((MonoProfileFlags)events);
TLS_INIT (tlsbuffer);
TLS_INIT (tlsmethodlist);