• Domingo 15 de Diciembre de 2024, 11:49

Autor Tema:  Problema analisis de código.  (Leído 997 veces)

memmaker650

  • Nuevo Miembro
  • *
  • Mensajes: 18
  • Nacionalidad: es
    • Ver Perfil
Problema analisis de código.
« en: Lunes 20 de Julio de 2009, 19:51 »
0
Código: C++
  1. #ifndef WLPDSTM_TLS_H_
  2. #define WLPDSTM_TLS_H_
  3.  
  4. namespace wlpdstm {
  5.  
  6.     ///////////////////////
  7.     // invoke init start //
  8.     ///////////////////////
  9.  
  10.     template<typename T, bool INIT = true>
  11.     struct GlobalInitInvoker {
  12.         static void GlobalInit() {
  13.             T::GlobalInit();
  14.         }
  15.     };
  16.  
  17.     template<typename T>
  18.     struct GlobalInitInvoker<T, false> {
  19.         static void GlobalInit() {
  20.             // do nothing
  21.         }
  22.     };
  23.  
  24.     template<typename T, bool INIT = true>
  25.     struct ThreadInitInvoker {
  26.         static void ThreadInit(T *obj) {
  27.             obj->ThreadInit();
  28.         }
  29.     };
  30.  
  31.     template<typename T>
  32.     struct ThreadInitInvoker<T, false> {
  33.         static void ThreadInit(T *obj) {
  34.             // do nothing
  35.         }
  36.     };
  37. }
  38.     /////////////////////
  39.     // invoke init end //
  40.     /////////////////////
  41.  
  42. #ifdef USE_PTHREAD_TLS
  43.  
  44. #include <pthread.h>
  45.  
  46. namespace wlpdstm {
  47.     /**
  48.      * This is a TLS class that will put one instance of templated
  49.      * class into TLS storage and provide access to it. Assumption here
  50.      * is that the TLS class exposes default constructor. If this is
  51.      * not the case this class should be slightly changed.
  52.      *
  53.      */
  54.     template<class T, bool GLOBAL_INIT, bool THREAD_INIT>
  55.     class Tls {
  56.         public:
  57.             static void GlobalInit();
  58.             static void ThreadInit();
  59.             static T *Get();
  60.  
  61.         private:
  62.             static ::pthread_key_t tlsKey;
  63.             static ::pthread_key_t initKey;
  64.     };
  65. }
  66.  
  67. template<class T, bool GLOBAL_INIT, bool THREAD_INIT> ::pthread_key_t wlpdstm::Tls<T, GLOBAL_INIT, THREAD_INIT>::tlsKey;
  68. template<class T, bool GLOBAL_INIT, bool THREAD_INIT> ::pthread_key_t wlpdstm::Tls<T, GLOBAL_INIT, THREAD_INIT>::initKey;
  69.  
  70. template<class T, bool GLOBAL_INIT, bool THREAD_INIT>
  71. inline void wlpdstm::Tls<T, GLOBAL_INIT, THREAD_INIT>::GlobalInit() {
  72.     ::pthread_key_create(&tlsKey, NULL);
  73.     GlobalInitInvoker<T, GLOBAL_INIT>::GlobalInit();
  74.  
  75.     // not locally initialized
  76.     ::pthread_key_create(&initKey, NULL);
  77.     ::pthread_setspecific(initKey, (const void *)false);
  78. }
  79.  
  80. template<class T, bool GLOBAL_INIT, bool THREAD_INIT>
  81. inline void wlpdstm::Tls<T, GLOBAL_INIT, THREAD_INIT>::ThreadInit() {
  82.     bool initialized = (bool)::pthread_getspecific(initKey);
  83.  
  84.     if(!initialized) {
  85.         T *obj = new T();
  86.         ::pthread_setspecific(tlsKey, (const void *)obj);
  87.         ThreadInitInvoker<T, THREAD_INIT>::ThreadInit(obj);
  88.         ::pthread_setspecific(initKey, (const void *)true);
  89.     }
  90. }
  91.  
  92. template<class T, bool GLOBAL_INIT, bool THREAD_INIT>
  93. inline T *wlpdstm::Tls<T, GLOBAL_INIT, THREAD_INIT>::Get() {
  94.     return (T *)::pthread_getspecific(tlsKey);
  95. }
  96.  
  97. #else
  98.  
  99. namespace wlpdstm {
  100.     template<class T, bool GLOBAL_INIT, bool THREAD_INIT>
  101.     class Tls {
  102.         public:
  103.             static void GlobalInit() {
  104.                 GlobalInitInvoker<T, GLOBAL_INIT>::GlobalInit();
  105.             }
  106.  
  107.             static void ThreadInit() {
  108.                 if(!init) {
  109.                     val = new T();
  110.                     ThreadInitInvoker<T, THREAD_INIT>::ThreadInit(val);
  111.                     init = true;
  112.                 }
  113.             }
  114.  
  115.             static T *Get() {
  116.                 return val;
  117.             }
  118.  
  119.         private:
  120.             static __thread T *val;
  121.             static __thread bool init;
  122.     };
  123. }
  124.  
  125. template<class T, bool GLOBAL_INIT, bool THREAD_INIT> __thread T* wlpdstm::Tls<T, GLOBAL_INIT, THREAD_INIT>::val;
  126. template<class T, bool GLOBAL_INIT, bool THREAD_INIT> __thread bool wlpdstm::Tls<T, GLOBAL_INIT, THREAD_INIT>::init;
  127.  
  128. #endif
  129.  
  130. #endif // WLPDSTM_TLS_H_
  131.  

Buenas y gracias de antemano a todo aquel que se lea un poco este código que he puesto.
TEngo dudas sobre las definición de los tipos de datos, creo que no comprendo bien los define, template y los structs, porque me parece ver redundancias por todos lados.

DUDAS:
1ª Linea 24. No comprendo este template. No se supone que un template es para crear una estructura facilemnte repetible, tipo plantilla o algo así. No entiendo que hace un template justo antes de una definición de este 'struct'.

2ª Lineas 62 y 63. Definición de variables privadas dentro de  una clase. Que significa '::' delante de la definición de las variables.

3º  Líneas 67 y 68. No comprendo estos 2 templates.

4º Lineas 92 a 95. EL template con el 'inline' seguido. SE supone que un inline es una función de tamaño muy pequeño y que definimos de esta manera para mayor limpieza. Pero en este inline no encuentro el nombre de la función, para después invocarlo. Aparte no entiendo el comando después del inline, no veo declaración de variables.

5ªLinea 42 --> #ifdef USE_PTHREAD_TLS --> ESto es una instrucción para el pre-compilador. Se supone que si la variable USE_PTHREAD_TLS='1' se compila lo que esta a continuación y sino no. Lo que no entiendo es que en este fichero no se da valor a esa variable. Si estamos compilando y se supone que las variables no tienen valor, algunas sí, como sabe el compilador que tiene que compilar.

Gracias de antemano.
Soy un poco novato ocn esto de c++.

m0skit0

  • Miembro de PLATA
  • *****
  • Mensajes: 2337
  • Nacionalidad: ma
    • Ver Perfil
    • http://fr33kk0mpu73r.blogspot.com/
Re: Problema analisis de código.
« Respuesta #1 en: Jueves 23 de Julio de 2009, 12:42 »
0
Sólo te puedo resolver algunas de tus muchas dudas :)

Código: C++
  1. T *wlpdstm::Tls<T, GLOBAL_INIT, THREAD_INIT>::Get()
  2.  
Yo aquí veo una declaración de función perfectamente válida :P

Cita de: "memmaker650"
5ªLinea 42 --> #ifdef USE_PTHREAD_TLS --> ESto es una instrucción para el pre-compilador. Se supone que si la variable USE_PTHREAD_TLS='1' se compila lo que esta a continuación y sino no. Lo que no entiendo es que en este fichero no se da valor a esa variable. Si estamos compilando y se supone que las variables no tienen valor, algunas sí, como sabe el compilador que tiene que compilar.
No. Si está definida (es decir si hay un #define USE_PTHREAD_TLS) entonces se incluye ese cacho, si no no. No tiene nada que ver el valor asignado.

Las demás dudas creo que las puedes resolver mirando algún tutorial de C++.