--- a/include/my_sys.h	2012-04-25 11:06:00.000000000 +0800
+++ b/include/my_sys.h	2012-04-28 13:07:47.000000000 +0800
@@ -149,6 +149,19 @@
 #define GETDATE_GMT		8
 #define GETDATE_FIXEDLENGTH	16
 
+/* Thread Memory Usage By P.Linux */
+#if defined(__APPLE__)
+#define _msize(p)      malloc_size(p)
+#elif defined(__sun)
+#define _msize(p)      (*((size_t*)(p)-1))
+#elif !defined(_WIN32)
+#define _msize(p)      malloc_usable_size(p)
+#endif
+
+typedef void (*MALLOC_SIZE_CB) (long long size); 
+extern void set_malloc_size_cb(MALLOC_SIZE_CB func);
+/* End */
+
 	/* defines when allocating data */
 extern void *my_malloc(size_t Size,myf MyFlags);
 extern void *my_multi_malloc(myf MyFlags, ...);
--- a/mysys/my_malloc.c	2012-04-25 11:06:00.000000000 +0800
+++ b/mysys/my_malloc.c	2012-04-28 16:47:32.000000000 +0800
@@ -17,6 +17,22 @@
 #include "mysys_err.h"
 #include <m_string.h>
 
+/* Thread Memory Usage By P.Linux */
+MALLOC_SIZE_CB malloc_size_cb_func= NULL;
+
+void static_upd_malloc_size(long long size)
+{
+  if (malloc_size_cb_func)
+    malloc_size_cb_func(size);
+}
+
+void set_malloc_size_cb(MALLOC_SIZE_CB func)
+{
+  malloc_size_cb_func= func;
+}
+/* End */
+
+
 /**
   Allocate a sized block of memory.
 
@@ -36,8 +52,14 @@
     size=1;
 
   point= malloc(size);
+  /* Thread Memory Usage By P.Linux */
+  static_upd_malloc_size(0 + _msize(point)); 
+  /* End */
   DBUG_EXECUTE_IF("simulate_out_of_memory",
                   {
+                    /* Thread Memory Usage By P.Linux */
+                    static_upd_malloc_size(0 - _msize(point)); 
+                    /* End */
                     free(point);
                     point= NULL;
                   });
@@ -95,9 +117,15 @@
   else
   {
     memcpy(point,oldpoint,size);
+    /* Thread Memory Usage By P.Linux */
+    static_upd_malloc_size(_msize(point) - _msize(oldpoint));
+    /* End */
     free(oldpoint);
   }
 #else
+  /* Thread Memory Usage By P.Linux */
+  size_t old_size= _msize(oldpoint);
+  /* End */
   if ((point= realloc(oldpoint, size)) == NULL)
   {
     if (my_flags & MY_FREE_ON_ERROR)
@@ -108,6 +136,12 @@
     if (my_flags & (MY_FAE+MY_WME))
       my_error(EE_OUTOFMEMORY, MYF(ME_BELL+ME_WAITTANG), size);
   }
+  /* Thread Memory Usage By P.Linux */
+  else
+  {
+    static_upd_malloc_size(_msize(point) - old_size);
+  }
+  /* End */
 #endif
   DBUG_PRINT("exit",("ptr: %p", point));
   DBUG_RETURN(point);
@@ -125,6 +159,9 @@
 {
   DBUG_ENTER("my_free");
   DBUG_PRINT("my",("ptr: %p", ptr));
+  /* Thread Memory Usage By P.Linux */
+  static_upd_malloc_size(0 - _msize(ptr)); 
+  /* End */
   free(ptr);
   DBUG_VOID_RETURN;
 }
--- a/sql/sql_class.h	2012-04-25 11:06:00.000000000 +0800
+++ b/sql/sql_class.h	2012-04-28 14:39:47.000000000 +0800
@@ -3082,6 +3082,11 @@
   bool wakeup_ready;
   mysql_mutex_t LOCK_wakeup_ready;
   mysql_cond_t COND_wakeup_ready;
+
+public:
+  /* Thread Mem Usage By P.Linux */
+  long long malloc_size;
+  /* End*/
 };
 
 /* Returns string as 'IP' for the client-side of the connection represented by
--- a/sql/sql_class.cc	2012-04-25 11:06:00.000000000 +0800
+++ b/sql/sql_class.cc	2012-04-28 13:18:52.000000000 +0800
@@ -960,6 +960,10 @@
   m_binlog_invoker= FALSE;
   memset(&invoker_user, 0, sizeof(invoker_user));
   memset(&invoker_host, 0, sizeof(invoker_host));
+
+  /* Thread Memory Usage By P.Linux */
+  malloc_size= 0;
+  /* End */
 }
 
 
--- a/sql/sql_show.cc	2012-04-25 11:06:00.000000000 +0800
+++ b/sql/sql_show.cc	2012-04-28 14:42:20.000000000 +0800
@@ -2057,6 +2057,13 @@
       table->field[11]->store((ulonglong) tmp->warning_info->current_row_for_warning());
       mysql_mutex_unlock(&tmp->LOCK_thd_data);
 
+      /* Thread Memory Usage By P.Linux */
+      if (tmp->malloc_size>= 0) 
+      {
+        table->field[12]->store((longlong) (tmp->malloc_size + sizeof(THD)), TRUE);
+        table->field[12]->set_notnull();
+      }
+      /* End */
       if (schema_table_store_record(thd, table))
       {
         mysql_mutex_unlock(&LOCK_thread_count);
@@ -7767,6 +7774,7 @@
    SKIP_OPEN_TABLE},
   {"CHARACTER_SET_NAME", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, 0,
    SKIP_OPEN_TABLE},
+  {"MEM_USAGE", 7, MYSQL_TYPE_LONG, 0, 0, "Mem_Usage", SKIP_OPEN_TABLE},
   {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
 };
 
@@ -8176,6 +8184,7 @@
    MY_I_S_UNSIGNED, "Rows_examined", SKIP_OPEN_TABLE},
   {"ROWS_READ", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
    MY_I_S_UNSIGNED, "Rows_read", SKIP_OPEN_TABLE},
+  {"MEM_USAGE", 7, MYSQL_TYPE_LONG, 0, 0, "Mem_Usage", SKIP_OPEN_TABLE},
   {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
 };
 
--- a/sql/mysqld.cc	2012-04-25 11:06:00.000000000 +0800
+++ b/sql/mysqld.cc	2012-04-28 13:07:47.000000000 +0800
@@ -4289,6 +4289,18 @@
 }
 #endif//DBUG_OFF
 
+
+/* Thread Mem Usage By P.Linux */
+extern "C"
+void my_malloc_size_cb_func(long long size)
+{
+  THD *thd= current_thd;
+  if (thd)
+    thd->malloc_size+= size;
+}
+/* End */
+
+
 #ifdef __WIN__
 int win_main(int argc, char **argv)
 #else
@@ -4323,6 +4335,10 @@
   remaining_argc= argc;
   remaining_argv= argv;
 
+  /* Thread Memory Usage By P.Linux */
+  set_malloc_size_cb(my_malloc_size_cb_func);
+  /* End */
+
   /* Must be initialized early for comparison of options name */
   system_charset_info= &my_charset_utf8_general_ci;
 
