opal/threads: manually invoke thread-specific key destructors on the main thread.
there is no such thing as pthread_join(main_thread), so key destructors are never invoked on the main thread, which causes valgrind report some memory leaks. Manually store and then invoke the key destructors and make valgrind happy. Signed-off-by: Gilles Gouaillardet <gilles@rist.or.jp>
Этот коммит содержится в:
родитель
6ef281e163
Коммит
b3a2bdda7b
@ -13,7 +13,7 @@
|
|||||||
* Copyright (c) 2010-2015 Los Alamos National Security, LLC.
|
* Copyright (c) 2010-2015 Los Alamos National Security, LLC.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
* Copyright (c) 2013-2015 Intel, Inc. All rights reserved
|
* Copyright (c) 2013-2015 Intel, Inc. All rights reserved
|
||||||
* Copyright (c) 2016 Research Organization for Information Science
|
* Copyright (c) 2016-2017 Research Organization for Information Science
|
||||||
* and Technology (RIST). All rights reserved.
|
* and Technology (RIST). All rights reserved.
|
||||||
* $COPYRIGHT$
|
* $COPYRIGHT$
|
||||||
*
|
*
|
||||||
@ -55,6 +55,7 @@
|
|||||||
|
|
||||||
#include "opal/runtime/opal_cr.h"
|
#include "opal/runtime/opal_cr.h"
|
||||||
#include "opal/mca/crs/base/base.h"
|
#include "opal/mca/crs/base/base.h"
|
||||||
|
#include "opal/threads/tsd.h"
|
||||||
|
|
||||||
extern int opal_initialized;
|
extern int opal_initialized;
|
||||||
extern int opal_util_initialized;
|
extern int opal_util_initialized;
|
||||||
@ -160,6 +161,9 @@ opal_finalize(void)
|
|||||||
/* close the sec framework */
|
/* close the sec framework */
|
||||||
(void) mca_base_framework_close(&opal_sec_base_framework);
|
(void) mca_base_framework_close(&opal_sec_base_framework);
|
||||||
|
|
||||||
|
/* cleanup the main thread specific stuff */
|
||||||
|
opal_tsd_keys_destruct();
|
||||||
|
|
||||||
/* finalize util code */
|
/* finalize util code */
|
||||||
opal_finalize_util();
|
opal_finalize_util();
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
* Copyright (c) 2010-2015 Los Alamos National Security, LLC.
|
* Copyright (c) 2010-2015 Los Alamos National Security, LLC.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
* Copyright (c) 2013-2016 Intel, Inc. All rights reserved
|
* Copyright (c) 2013-2016 Intel, Inc. All rights reserved
|
||||||
* Copyright (c) 2015-2016 Research Organization for Information Science
|
* Copyright (c) 2015-2017 Research Organization for Information Science
|
||||||
* and Technology (RIST). All rights reserved.
|
* and Technology (RIST). All rights reserved.
|
||||||
* $COPYRIGHT$
|
* $COPYRIGHT$
|
||||||
*
|
*
|
||||||
@ -344,6 +344,8 @@ opal_init_util(int* pargc, char*** pargv)
|
|||||||
return OPAL_SUCCESS;
|
return OPAL_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
opal_thread_set_main();
|
||||||
|
|
||||||
opal_init_called = true;
|
opal_init_called = true;
|
||||||
|
|
||||||
/* set the nodename right away so anyone who needs it has it. Note
|
/* set the nodename right away so anyone who needs it has it. Note
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
* Copyright (c) 2004-2005 The Regents of the University of California.
|
* Copyright (c) 2004-2005 The Regents of the University of California.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
* Copyright (c) 2010 Cisco Systems, Inc. All rights reserved.
|
* Copyright (c) 2010 Cisco Systems, Inc. All rights reserved.
|
||||||
* Copyright (c) 2015 Research Organization for Information Science
|
* Copyright (c) 2015-2017 Research Organization for Information Science
|
||||||
* and Technology (RIST). All rights reserved.
|
* and Technology (RIST). All rights reserved.
|
||||||
* $COPYRIGHT$
|
* $COPYRIGHT$
|
||||||
*
|
*
|
||||||
@ -22,12 +22,23 @@
|
|||||||
#include "opal_config.h"
|
#include "opal_config.h"
|
||||||
|
|
||||||
#include "opal/threads/threads.h"
|
#include "opal/threads/threads.h"
|
||||||
|
#include "opal/threads/tsd.h"
|
||||||
#include "opal/constants.h"
|
#include "opal/constants.h"
|
||||||
|
|
||||||
bool opal_debug_threads = false;
|
bool opal_debug_threads = false;
|
||||||
|
|
||||||
static void opal_thread_construct(opal_thread_t *t);
|
static void opal_thread_construct(opal_thread_t *t);
|
||||||
|
|
||||||
|
static pthread_t opal_main_thread;
|
||||||
|
|
||||||
|
struct opal_tsd_key_value {
|
||||||
|
opal_tsd_key_t key;
|
||||||
|
opal_tsd_destructor_t destructor;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct opal_tsd_key_value *opal_tsd_key_values = NULL;
|
||||||
|
static int opal_tsd_key_values_count = 0;
|
||||||
|
|
||||||
OBJ_CLASS_INSTANCE(opal_thread_t,
|
OBJ_CLASS_INSTANCE(opal_thread_t,
|
||||||
opal_object_t,
|
opal_object_t,
|
||||||
opal_thread_construct, NULL);
|
opal_thread_construct, NULL);
|
||||||
@ -83,3 +94,39 @@ void opal_thread_kill(opal_thread_t *t, int sig)
|
|||||||
{
|
{
|
||||||
pthread_kill(t->t_handle, sig);
|
pthread_kill(t->t_handle, sig);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int opal_tsd_key_create(opal_tsd_key_t *key,
|
||||||
|
opal_tsd_destructor_t destructor)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
rc = pthread_key_create(key, destructor);
|
||||||
|
if ((0 == rc) && (pthread_self() == opal_main_thread)) {
|
||||||
|
opal_tsd_key_values = (struct opal_tsd_key_value *)realloc(opal_tsd_key_values, (opal_tsd_key_values_count+1) * sizeof(struct opal_tsd_key_value));
|
||||||
|
opal_tsd_key_values[opal_tsd_key_values_count].key = *key;
|
||||||
|
opal_tsd_key_values[opal_tsd_key_values_count].destructor = destructor;
|
||||||
|
opal_tsd_key_values_count ++;
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
int opal_tsd_keys_destruct()
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
void * ptr;
|
||||||
|
for (i=0; i<opal_tsd_key_values_count; i++) {
|
||||||
|
if(OPAL_SUCCESS == opal_tsd_getspecific(opal_tsd_key_values[i].key, &ptr)) {
|
||||||
|
if (NULL != opal_tsd_key_values[i].destructor) {
|
||||||
|
opal_tsd_key_values[i].destructor(ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (0 < opal_tsd_key_values_count) {
|
||||||
|
free(opal_tsd_key_values);
|
||||||
|
opal_tsd_key_values_count = 0;
|
||||||
|
}
|
||||||
|
return OPAL_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void opal_thread_set_main() {
|
||||||
|
opal_main_thread = pthread_self();
|
||||||
|
}
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
* Copyright (c) 2010 Cisco Systems, Inc. All rights reserved.
|
* Copyright (c) 2010 Cisco Systems, Inc. All rights reserved.
|
||||||
* Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved.
|
||||||
* Copyright (c) 2015 Research Organization for Information Science
|
* Copyright (c) 2015-2017 Research Organization for Information Science
|
||||||
* and Technology (RIST). All rights reserved.
|
* and Technology (RIST). All rights reserved.
|
||||||
* $COPYRIGHT$
|
* $COPYRIGHT$
|
||||||
*
|
*
|
||||||
@ -120,6 +120,7 @@ OPAL_DECLSPEC int opal_thread_join(opal_thread_t *, void **thread_return);
|
|||||||
OPAL_DECLSPEC bool opal_thread_self_compare(opal_thread_t*);
|
OPAL_DECLSPEC bool opal_thread_self_compare(opal_thread_t*);
|
||||||
OPAL_DECLSPEC opal_thread_t *opal_thread_get_self(void);
|
OPAL_DECLSPEC opal_thread_t *opal_thread_get_self(void);
|
||||||
OPAL_DECLSPEC void opal_thread_kill(opal_thread_t *, int sig);
|
OPAL_DECLSPEC void opal_thread_kill(opal_thread_t *, int sig);
|
||||||
|
OPAL_DECLSPEC void opal_thread_set_main(void);
|
||||||
|
|
||||||
END_C_DECLS
|
END_C_DECLS
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* Copyright (c) 2007-2013 Los Alamos National Security, LLC. All rights
|
* Copyright (c) 2007-2013 Los Alamos National Security, LLC. All rights
|
||||||
* reserved.
|
* reserved.
|
||||||
* Copyright (c) 2008 Cisco Systems, Inc. All rights reserved.
|
* Copyright (c) 2008 Cisco Systems, Inc. All rights reserved.
|
||||||
* Copyright (c) 2015 Research Organization for Information Science
|
* Copyright (c) 2015-2017 Research Organization for Information Science
|
||||||
* and Technology (RIST). All rights reserved.
|
* and Technology (RIST). All rights reserved.
|
||||||
* $COPYRIGHT$
|
* $COPYRIGHT$
|
||||||
*
|
*
|
||||||
@ -45,36 +45,6 @@ typedef void (*opal_tsd_destructor_t)(void *value);
|
|||||||
typedef void* opal_tsd_key_t;
|
typedef void* opal_tsd_key_t;
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create thread-specific data key
|
|
||||||
*
|
|
||||||
* Create a thread-specific data key visible to all threads in the
|
|
||||||
* current process. The returned key is valid in all threads,
|
|
||||||
* although the values bound to the key by opal_tsd_setspecific() are
|
|
||||||
* allocated on a per-thread basis and persist for the life of the
|
|
||||||
* calling thread.
|
|
||||||
*
|
|
||||||
* Upon key creation, the value NULL is associated with the new key in
|
|
||||||
* all active threads. When a new thread is created, the value NULL
|
|
||||||
* is associated with all defined keys in the new thread.
|
|
||||||
*
|
|
||||||
* The destructor parameter may be NULL. At thread exit, if
|
|
||||||
* destructor is non-NULL AND the thread has a non-NULL value
|
|
||||||
* associated with the key, the function is called with the current
|
|
||||||
* value as its argument.
|
|
||||||
*
|
|
||||||
* @param key[out] The key for accessing thread-specific data
|
|
||||||
* @param destructor[in] Cleanup function to call when a thread exits
|
|
||||||
*
|
|
||||||
* @retval OPAL_SUCCESS Success
|
|
||||||
* @retval EAGAIN The system lacked the necessary resource to
|
|
||||||
* create another thread specific data key
|
|
||||||
* @retval ENOMEM Insufficient memory exists to create the key
|
|
||||||
*/
|
|
||||||
OPAL_DECLSPEC int opal_tsd_key_create(opal_tsd_key_t *key,
|
|
||||||
opal_tsd_destructor_t destructor);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete a thread-specific data key
|
* Delete a thread-specific data key
|
||||||
*
|
*
|
||||||
@ -138,13 +108,6 @@ OPAL_DECLSPEC int opal_tsd_getspecific(opal_tsd_key_t key, void **valuep);
|
|||||||
|
|
||||||
typedef pthread_key_t opal_tsd_key_t;
|
typedef pthread_key_t opal_tsd_key_t;
|
||||||
|
|
||||||
static inline int
|
|
||||||
opal_tsd_key_create(opal_tsd_key_t *key,
|
|
||||||
opal_tsd_destructor_t destructor)
|
|
||||||
{
|
|
||||||
return pthread_key_create(key, destructor);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
opal_tsd_key_delete(opal_tsd_key_t key)
|
opal_tsd_key_delete(opal_tsd_key_t key)
|
||||||
{
|
{
|
||||||
@ -166,6 +129,50 @@ opal_tsd_getspecific(opal_tsd_key_t key, void **valuep)
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create thread-specific data key
|
||||||
|
*
|
||||||
|
* Create a thread-specific data key visible to all threads in the
|
||||||
|
* current process. The returned key is valid in all threads,
|
||||||
|
* although the values bound to the key by opal_tsd_setspecific() are
|
||||||
|
* allocated on a per-thread basis and persist for the life of the
|
||||||
|
* calling thread.
|
||||||
|
*
|
||||||
|
* Upon key creation, the value NULL is associated with the new key in
|
||||||
|
* all active threads. When a new thread is created, the value NULL
|
||||||
|
* is associated with all defined keys in the new thread.
|
||||||
|
*
|
||||||
|
* The destructor parameter may be NULL. At thread exit, if
|
||||||
|
* destructor is non-NULL AND the thread has a non-NULL value
|
||||||
|
* associated with the key, the function is called with the current
|
||||||
|
* value as its argument.
|
||||||
|
*
|
||||||
|
* @param key[out] The key for accessing thread-specific data
|
||||||
|
* @param destructor[in] Cleanup function to call when a thread exits
|
||||||
|
*
|
||||||
|
* @retval OPAL_SUCCESS Success
|
||||||
|
* @retval EAGAIN The system lacked the necessary resource to
|
||||||
|
* create another thread specific data key
|
||||||
|
* @retval ENOMEM Insufficient memory exists to create the key
|
||||||
|
*/
|
||||||
|
OPAL_DECLSPEC int opal_tsd_key_create(opal_tsd_key_t *key,
|
||||||
|
opal_tsd_destructor_t destructor);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destruct all thread-specific data keys
|
||||||
|
*
|
||||||
|
* Destruct all thread-specific data keys and invoke the destructor
|
||||||
|
*
|
||||||
|
* This should only be invoked in the main thread.
|
||||||
|
* This is made necessary since destructors are not invoked on the
|
||||||
|
* keys of the main thread, since there is no such thing as
|
||||||
|
* pthread_join(main_thread)
|
||||||
|
*
|
||||||
|
* @retval OPAL_SUCCESS Success
|
||||||
|
*/
|
||||||
|
OPAL_DECLSPEC int opal_tsd_keys_destruct(void);
|
||||||
|
|
||||||
END_C_DECLS
|
END_C_DECLS
|
||||||
|
|
||||||
#endif /* OPAL_MTHREADS_TSD_H */
|
#endif /* OPAL_MTHREADS_TSD_H */
|
||||||
|
Загрузка…
Ссылка в новой задаче
Block a user