about summary refs log tree commit diff
path: root/REORG.TODO/nptl_db/td_ta_tsd_iter.c
diff options
context:
space:
mode:
Diffstat (limited to 'REORG.TODO/nptl_db/td_ta_tsd_iter.c')
-rw-r--r--REORG.TODO/nptl_db/td_ta_tsd_iter.c81
1 files changed, 81 insertions, 0 deletions
diff --git a/REORG.TODO/nptl_db/td_ta_tsd_iter.c b/REORG.TODO/nptl_db/td_ta_tsd_iter.c
new file mode 100644
index 0000000000..33fd53d6c1
--- /dev/null
+++ b/REORG.TODO/nptl_db/td_ta_tsd_iter.c
@@ -0,0 +1,81 @@
+/* Iterate over a process's thread-specific data.
+   Copyright (C) 1999-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <stdint.h>
+#include "thread_dbP.h"
+#include <alloca.h>
+
+td_err_e
+td_ta_tsd_iter (const td_thragent_t *ta_arg, td_key_iter_f *callback,
+		void *cbdata_p)
+{
+  td_thragent_t *const ta = (td_thragent_t *) ta_arg;
+  td_err_e err;
+  void *keys;
+  size_t keys_nb, keys_elemsize;
+  psaddr_t addr;
+  uint32_t idx;
+
+  LOG ("td_ta_tsd_iter");
+
+  /* Test whether the TA parameter is ok.  */
+  if (! ta_ok (ta))
+    return TD_BADTA;
+
+  /* This makes sure we have the size information on hand.  */
+  addr = 0;
+  err = _td_locate_field (ta,
+			  ta->ta_var___pthread_keys, SYM_DESC___pthread_keys,
+			  (psaddr_t) 0 + 1, &addr);
+  if (err != TD_OK)
+    return err;
+
+  /* Now copy in the entire array of key descriptors.  */
+  keys_elemsize = (addr - (psaddr_t) 0) / 8;
+  keys_nb = keys_elemsize * DB_DESC_NELEM (ta->ta_var___pthread_keys);
+  keys = __alloca (keys_nb);
+  err = DB_GET_SYMBOL (addr, ta, __pthread_keys);
+  if (err != TD_OK)
+    return err;
+  if (ps_pdread (ta->ph, addr, keys, keys_nb) != PS_OK)
+    return TD_ERR;
+
+  /* Now get all descriptors, one after the other.  */
+  for (idx = 0; idx < DB_DESC_NELEM (ta->ta_var___pthread_keys); ++idx)
+    {
+      psaddr_t seq, destr;
+      err = DB_GET_FIELD_LOCAL (seq, ta, keys, pthread_key_struct, seq, 0);
+      if (err != TD_OK)
+	return err;
+      if (((uintptr_t) seq) & 1)
+	{
+	  err = DB_GET_FIELD_LOCAL (destr, ta, keys, pthread_key_struct,
+				    destr, 0);
+	  if (err != TD_OK)
+	    return err;
+	  /* Return with an error if the callback returns a nonzero value.  */
+	  if (callback ((thread_key_t) idx, destr, cbdata_p) != 0)
+	    return TD_DBERR;
+	}
+      /* Advance to the next element in the copied array.  */
+      keys += keys_elemsize;
+    }
+
+  return TD_OK;
+}