/* Locally-cached context pointer -- see _stp_runtime_entryfn_get_context()
* and _stp_runtime_entryfn_put_context(). */
-static __thread struct context *contexts;
+static __thread struct context *tls_context;
static int _stp_runtime_contexts_init(void)
{
/* If this thread has already gotten a context structure,
* return the data index from it. */
- if (contexts != NULL)
- return contexts->data_index;
+ if (tls_context != NULL)
+ return tls_context->data_index;
/* This shouldn't happen. */
/* FIXME: assert? */
struct context *c;
int i, index, rc, data_index;
- /* If 'contexts' (which is thread-local storage) is already set
+ /* If 'tls_context' (which is thread-local storage) is already set
* for this thread, we are re-entrant, so just quit. */
- if (contexts != NULL)
+ if (tls_context != NULL)
return NULL;
data_index = _stp_context_index();
if (pthread_mutex_trylock(&c->lock) == 0) {
/* We found a free context structure. Now that it is
* locked, set the TLS pointer and return the context. */
- contexts = c;
- return contexts;
+ tls_context = c;
+ return tls_context;
}
}
c = stp_session_context(data_index);
rc = pthread_mutex_lock(&c->lock);
if (rc == 0) {
- contexts = c;
- return contexts;
+ tls_context = c;
+ return tls_context;
}
return NULL;
}
-static void _stp_runtime_entryfn_put_context(void)
+static void _stp_runtime_entryfn_put_context(struct context *c)
{
- if (contexts) {
- struct context *c = contexts;
- contexts = NULL;
+ if (c && c == tls_context) {
+ tls_context = NULL;
pthread_mutex_unlock(&c->lock);
}
+ // else, warn about bad state?
return;
}
* here. This function is called after
* _stp_runtime_entryfn_get_context() and has no corresponding
* "put" function. */
- return contexts;
+ return tls_context;
}
static void _stp_runtime_context_wait(void)
type, data, len);
// This thread should already have a context structure.
- if (contexts == NULL)
+ struct context* c = _stp_runtime_get_context();
+ if (c == NULL)
return EINVAL;
// Currently, we're only handling 'STP_SYSTEM' control
return 0;
memcpy(buffer, data, len);
- size_t offset = buffer - contexts->transport_data.log_buf;
+ size_t offset = buffer - c->transport_data.log_buf;
__stp_dyninst_transport_queue_add(STP_DYN_SYSTEM,
- contexts->data_index, offset, len);
+ c->data_index, offset, len);
return len;
}
_stp_dyninst_transport_write_oob_data(char *buffer, size_t bytes)
{
// This thread should already have a context structure.
- if (contexts == NULL)
+ struct context* c = _stp_runtime_get_context();
+ if (c == NULL)
return EINVAL;
- size_t offset = buffer - contexts->transport_data.log_buf;
+ size_t offset = buffer - c->transport_data.log_buf;
__stp_dyninst_transport_queue_add(STP_DYN_OOB_DATA,
- contexts->data_index, offset, bytes);
+ c->data_index, offset, bytes);
return 0;
}
static int _stp_dyninst_transport_write(void)
{
// This thread should already have a context structure.
- if (contexts == NULL)
+ struct context* c = _stp_runtime_get_context();
+ if (c == NULL)
return 0;
- struct _stp_transport_context_data *data = &contexts->transport_data;
+ struct _stp_transport_context_data *data = &c->transport_data;
size_t bytes = data->write_bytes;
if (bytes == 0)
data->write_offset = _STP_D_T_PRINT_ADD(data->write_offset, bytes);
__stp_dyninst_transport_queue_add(STP_DYN_NORMAL_DATA,
- contexts->data_index,
+ c->data_index,
saved_write_offset, bytes);
return 0;
}
static char *_stp_dyninst_transport_log_buffer(void)
{
// This thread should already have a context structure.
- if (contexts == NULL)
+ struct context* c = _stp_runtime_get_context();
+ if (c == NULL)
return NULL;
// Note that the context structure is locked, so only one
// probe at a time can be operating on it.
- struct _stp_transport_context_data *data = &contexts->transport_data;
+ struct _stp_transport_context_data *data = &c->transport_data;
// If there isn't an available log buffer, wait.
if (_stp_dyninst_transport_log_buffer_full(data)) {
void *ret;
// This thread should already have a context structure.
- if (contexts == NULL) {
- _stp_transport_debug("NULL contexts!\n");
+ struct context* c = _stp_runtime_get_context();
+ if (c == NULL) {
+ _stp_transport_debug("NULL context!\n");
return NULL;
}
- struct _stp_transport_context_data *data = &contexts->transport_data;
+ struct _stp_transport_context_data *data = &c->transport_data;
size_t space_before, space_after, read_offset;
recheck:
static void _stp_dyninst_transport_unreserve_bytes(int numbytes)
{
// This thread should already have a context structure.
- if (contexts == NULL)
+ struct context* c = _stp_runtime_get_context();
+ if (c == NULL)
return;
- struct _stp_transport_context_data *data = &contexts->transport_data;
+ struct _stp_transport_context_data *data = &c->transport_data;
if (unlikely(numbytes <= 0 || numbytes > data->write_bytes))
return;
return contexts[smp_processor_id()];
}
-static inline void _stp_runtime_entryfn_put_context(void)
+static inline void _stp_runtime_entryfn_put_context(struct context *c __attribute__((unused)))
{
/* Do nothing. */
return;
static void _stp_runtime_contexts_free(void);
static int _stp_runtime_get_data_index(void);
static struct context *_stp_runtime_entryfn_get_context(void);
-static void _stp_runtime_entryfn_put_context(void);
+static void _stp_runtime_entryfn_put_context(struct context *);
static struct context *_stp_runtime_get_context(void);
#if defined(__KERNEL__)
// and there's *nothing* for the probe to do. (even alibi is in shm)
// So failure skips this whole block through the end of the epilogue.
s.op->newline() << "if (likely(session_state())) {";
- s.op->newline(1) << "int _stp_saved_errno = errno;";
+ s.op->indent(1);
}
s.op->newline() << "#ifdef STP_ALIBI";
s.op->newline() << "atomic_inc(probe_alibi(" << probe << "->index));";
s.op->newline() << "#else";
+ if (s.runtime_usermode_p())
+ s.op->newline() << "int _stp_saved_errno = errno;";
+
s.op->newline() << "struct context* __restrict__ c = NULL;";
s.op->newline() << "#if !INTERRUPTIBLE";
s.op->newline() << "unsigned long flags;";
// buffers are stored there).
if (!s.runtime_usermode_p())
{
- s.op->newline() << "_stp_runtime_entryfn_put_context();";
+ s.op->newline() << "_stp_runtime_entryfn_put_context(c);";
}
if (! s.suppress_handler_errors) // PR 13306
{
s.op->newline() << "local_irq_restore (flags);";
s.op->newline() << "#endif";
- s.op->newline() << "#endif // STP_ALIBI";
-
if (s.runtime_usermode_p())
{
- s.op->newline() << "if (c) _stp_runtime_entryfn_put_context();";
+ s.op->newline() << "_stp_runtime_entryfn_put_context(c);";
s.op->newline() << "errno = _stp_saved_errno;";
- s.op->newline(-1) << "}";
}
+
+ s.op->newline() << "#endif // STP_ALIBI";
+
+ if (s.runtime_usermode_p())
+ s.op->newline(-1) << "}";
}
// In dyninst mode, now we're done with the contexts, transport, everything!
if (session->runtime_usermode_p())
{
- o->newline() << "_stp_runtime_entryfn_put_context();";
+ o->newline() << "_stp_runtime_entryfn_put_context(c);";
o->newline() << "_stp_dyninst_transport_shutdown();";
o->newline() << "_stp_runtime_contexts_free();";
}