Re: [PATCH 0/1] trace2: fix tracing when NO_PTHREADS is defined
- From
Jeff King <peff@peff.net>
- Date
- May 23, 2019, 05:51 UTC
- Message-ID
- <20190523055108.GA20871@sigill.intra.peff.net>
- In-Reply-To
- <97796007-db6e-f2ea-91ae-3113b74e4ae9@jeffhostetler.com>
On Wed, May 22, 2019 at 09:23:39AM -0400, Jeff Hostetler wrote:
Show 9 quoted lines
> I was wondering about that too as the proper long term solution. > We would need (as the discussion suggests [1]) to properly > respect/represent the pthread_key_t argument. > > For now, I've guarded my usage of pthread_getspecific() in the trace2 > (similar to what index-pack does), so its not urgent that we update it. > And I'd rather we take this simple trace2 fix now and not try to combine > it with fixes for the pthread macros. Especially now as we're in the RC > cycle for 2.22.
Yeah, I think that makes sense.
> I'll make a note to revisit the pthread code after 2.22.
For fun, here's a constant-time zero-allocation implementation that I came up with. It passes t0211 with NO_PTHREADS, but I didn't test it beyond that.
diff --git a/thread-utils.h b/thread-utils.h index 4961487ed9..f466215742 100644 --- a/thread-utils.h +++ b/thread-utils.h @@ -18,7 +18,7 @@ #define pthread_t int #define pthread_mutex_t int #define pthread_cond_t int -#define pthread_key_t int +#define pthread_key_t git_pthread_key_t #define pthread_mutex_init(mutex, attr) dummy_pthread_init(mutex) #define pthread_mutex_lock(mutex) @@ -31,16 +31,49 @@ #define pthread_cond_broadcast(cond) #define pthread_cond_destroy(cond) -#define pthread_key_create(key, attr) dummy_pthread_init(key) -#define pthread_key_delete(key) +#define pthread_key_create(key, destroy) git_pthread_key_create(key, destroy) +#define pthread_key_delete(key) git_pthread_key_delete(key) #define pthread_create(thread, attr, fn, data) \ dummy_pthread_create(thread, attr, fn, data) #define pthread_join(thread, retval) \ dummy_pthread_join(thread, retval) -#define pthread_setspecific(key, data) -#define pthread_getspecific(key) NULL +#define pthread_setspecific(key, data) git_pthread_setspecific(key, data) +#define pthread_getspecific(key) git_pthread_getspecific(key) + +typedef struct { + void *data; + /* extra indirection because setspecific is passed key by value */ + void **vdata; +} git_pthread_key_t; + +static inline int git_pthread_key_create(git_pthread_key_t *key, + void (*destroy)(void *)) +{ + key->data = NULL; + key->vdata = &key->data; + /* We don't use this; alternatively we could all via atexit(). */ + if (destroy) + BUG("NO_PTHREADS does not support pthread key destructors"); + return 0; +} + +static inline int git_pthread_key_delete(git_pthread_key_t key) +{ + /* noop */ + return 0; +} + +static inline void git_pthread_setspecific(git_pthread_key_t key, void *data) +{ + *(key.vdata) = data; +} + +static inline void *git_pthread_getspecific(git_pthread_key_t key) +{ + return key.data; +} int dummy_pthread_create(pthread_t *pthread, const void *attr, void *(*fn)(void *), void *data);