From 6fda93be42ace9eeab0e82ceebb6798961c9105c Mon Sep 17 00:00:00 2001
From: marha <marha@users.sourceforge.net>
Date: Tue, 23 Nov 2010 21:46:41 +0000
Subject: Added missing files from mesalib 7.9

---
 mesalib/src/mapi/mapi/entry.c            |  65 +++++
 mesalib/src/mapi/mapi/entry.h            |  49 ++++
 mesalib/src/mapi/mapi/entry_x86-64_tls.h |  97 ++++++++
 mesalib/src/mapi/mapi/entry_x86_tls.h    | 120 +++++++++
 mesalib/src/mapi/mapi/entry_x86_tsd.h    |  89 +++++++
 mesalib/src/mapi/mapi/mapi.c             | 191 +++++++++++++++
 mesalib/src/mapi/mapi/mapi.h             |  66 +++++
 mesalib/src/mapi/mapi/mapi_abi.py        | 402 +++++++++++++++++++++++++++++++
 mesalib/src/mapi/mapi/mapi_tmp.h         | 211 ++++++++++++++++
 mesalib/src/mapi/mapi/sources.mak        |  19 ++
 mesalib/src/mapi/mapi/stub.c             | 180 ++++++++++++++
 mesalib/src/mapi/mapi/stub.h             |  52 ++++
 mesalib/src/mapi/mapi/table.c            |  56 +++++
 mesalib/src/mapi/mapi/table.h            |  76 ++++++
 mesalib/src/mapi/mapi/u_compiler.h       |  48 ++++
 mesalib/src/mapi/mapi/u_current.c        | 277 +++++++++++++++++++++
 mesalib/src/mapi/mapi/u_current.h        | 102 ++++++++
 mesalib/src/mapi/mapi/u_execmem.c        | 145 +++++++++++
 mesalib/src/mapi/mapi/u_execmem.h        |   7 +
 mesalib/src/mapi/mapi/u_macros.h         |  12 +
 mesalib/src/mapi/mapi/u_thread.c         | 254 +++++++++++++++++++
 mesalib/src/mapi/mapi/u_thread.h         | 201 ++++++++++++++++
 22 files changed, 2719 insertions(+)
 create mode 100644 mesalib/src/mapi/mapi/entry.c
 create mode 100644 mesalib/src/mapi/mapi/entry.h
 create mode 100644 mesalib/src/mapi/mapi/entry_x86-64_tls.h
 create mode 100644 mesalib/src/mapi/mapi/entry_x86_tls.h
 create mode 100644 mesalib/src/mapi/mapi/entry_x86_tsd.h
 create mode 100644 mesalib/src/mapi/mapi/mapi.c
 create mode 100644 mesalib/src/mapi/mapi/mapi.h
 create mode 100644 mesalib/src/mapi/mapi/mapi_abi.py
 create mode 100644 mesalib/src/mapi/mapi/mapi_tmp.h
 create mode 100644 mesalib/src/mapi/mapi/sources.mak
 create mode 100644 mesalib/src/mapi/mapi/stub.c
 create mode 100644 mesalib/src/mapi/mapi/stub.h
 create mode 100644 mesalib/src/mapi/mapi/table.c
 create mode 100644 mesalib/src/mapi/mapi/table.h
 create mode 100644 mesalib/src/mapi/mapi/u_compiler.h
 create mode 100644 mesalib/src/mapi/mapi/u_current.c
 create mode 100644 mesalib/src/mapi/mapi/u_current.h
 create mode 100644 mesalib/src/mapi/mapi/u_execmem.c
 create mode 100644 mesalib/src/mapi/mapi/u_execmem.h
 create mode 100644 mesalib/src/mapi/mapi/u_macros.h
 create mode 100644 mesalib/src/mapi/mapi/u_thread.c
 create mode 100644 mesalib/src/mapi/mapi/u_thread.h

(limited to 'mesalib/src')

diff --git a/mesalib/src/mapi/mapi/entry.c b/mesalib/src/mapi/mapi/entry.c
new file mode 100644
index 000000000..fdf2a89c5
--- /dev/null
+++ b/mesalib/src/mapi/mapi/entry.c
@@ -0,0 +1,65 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.9
+ *
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Chia-I Wu <olv@lunarg.com>
+ */
+
+#include "entry.h"
+
+#if defined(USE_X86_ASM) && defined(__GNUC__)
+#   ifdef GLX_USE_TLS
+#      include "entry_x86_tls.h"
+#   else                 
+#      include "entry_x86_tsd.h"
+#   endif
+#elif defined(USE_X86_64_ASM) && defined(__GNUC__) && defined(GLX_USE_TLS)
+#   include "entry_x86-64_tls.h"
+#else
+
+#include <stdlib.h>
+#include "u_current.h"
+#include "table.h"
+
+/* C version of the public entries */
+#define MAPI_TMP_PUBLIC_ENTRIES
+#include "mapi_tmp.h"
+
+void
+entry_patch_public(void)
+{
+}
+
+mapi_func
+entry_generate(int slot)
+{
+   return NULL;
+}
+
+void
+entry_patch(mapi_func entry, int slot)
+{
+}
+
+#endif /* asm */
diff --git a/mesalib/src/mapi/mapi/entry.h b/mesalib/src/mapi/mapi/entry.h
new file mode 100644
index 000000000..48ed3f9ec
--- /dev/null
+++ b/mesalib/src/mapi/mapi/entry.h
@@ -0,0 +1,49 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.9
+ *
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Chia-I Wu <olv@lunarg.com>
+ */
+
+#ifndef _ENTRY_H_
+#define _ENTRY_H_
+
+#include "u_compiler.h"
+#include "stub.h"
+
+/* declare public entries */
+#define MAPI_TMP_DEFINES
+#define MAPI_TMP_PUBLIC_DECLARES
+#include "mapi_tmp.h"
+
+void
+entry_patch_public(void);
+
+mapi_func
+entry_generate(int slot);
+
+void
+entry_patch(mapi_func entry, int slot);
+
+#endif /* _ENTRY_H_ */
diff --git a/mesalib/src/mapi/mapi/entry_x86-64_tls.h b/mesalib/src/mapi/mapi/entry_x86-64_tls.h
new file mode 100644
index 000000000..2fbe73b5b
--- /dev/null
+++ b/mesalib/src/mapi/mapi/entry_x86-64_tls.h
@@ -0,0 +1,97 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.9
+ *
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Chia-I Wu <olv@lunarg.com>
+ */
+
+#include <string.h>
+#include "u_execmem.h"
+#include "u_macros.h"
+
+__asm__(".text");
+
+__asm__("x86_64_current_tls:\n\t"
+	"movq u_current_table_tls@GOTTPOFF(%rip), %rax\n\t"
+	"ret");
+
+#define STUB_ASM_ENTRY(func)                             \
+   ".globl " func "\n"                                   \
+   ".type " func ", @function\n"                         \
+   ".balign 32\n"                                        \
+   func ":"
+
+#define STUB_ASM_CODE(slot)                              \
+   "movq u_current_table_tls@GOTTPOFF(%rip), %rax\n\t"   \
+   "movq %fs:(%rax), %r11\n\t"                           \
+   "jmp *(8 * " slot ")(%r11)"
+
+#define MAPI_TMP_STUB_ASM_GCC
+#include "mapi_tmp.h"
+
+extern unsigned long
+x86_64_current_tls();
+
+void
+entry_patch_public(void)
+{
+}
+
+void
+entry_patch(mapi_func entry, int slot)
+{
+   char *code = (char *) entry;
+   *((unsigned int *) (code + 12)) = slot * sizeof(mapi_func);
+}
+
+mapi_func
+entry_generate(int slot)
+{
+   const char code_templ[16] = {
+      /* movq %fs:0, %r11 */
+      0x64, 0x4c, 0x8b, 0x1c, 0x25, 0x00, 0x00, 0x00, 0x00,
+      /* jmp *0x1234(%r11) */
+      0x41, 0xff, 0xa3, 0x34, 0x12, 0x00, 0x00,
+   };
+   unsigned long addr;
+   void *code;
+   mapi_func entry;
+
+   addr = x86_64_current_tls();
+   if ((addr >> 32) != 0xffffffff)
+      return NULL;
+   addr &= 0xffffffff;
+
+   code = u_execmem_alloc(sizeof(code_templ));
+   if (!code)
+      return NULL;
+
+   memcpy(code, code_templ, sizeof(code_templ));
+
+   *((unsigned int *) (code + 5)) = addr;
+   entry = (mapi_func) code;
+   entry_patch(entry, slot);
+
+   return entry;
+}
diff --git a/mesalib/src/mapi/mapi/entry_x86_tls.h b/mesalib/src/mapi/mapi/entry_x86_tls.h
new file mode 100644
index 000000000..d4f7d98cf
--- /dev/null
+++ b/mesalib/src/mapi/mapi/entry_x86_tls.h
@@ -0,0 +1,120 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.9
+ *
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Chia-I Wu <olv@lunarg.com>
+ */
+
+#include <string.h>
+#include "u_execmem.h"
+#include "u_macros.h"
+
+__asm__(".text");
+
+__asm__("x86_current_tls:\n\t"
+	"call 1f\n"
+        "1:\n\t"
+        "popl %eax\n\t"
+	"addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %eax\n\t"
+	"movl u_current_table_tls@GOTNTPOFF(%eax), %eax\n\t"
+	"ret");
+
+#ifndef GLX_X86_READONLY_TEXT
+__asm__(".section wtext, \"awx\", @progbits\n"
+        ".balign 16\n"
+        "x86_entry_start:");
+#endif /* GLX_X86_READONLY_TEXT */
+
+#define STUB_ASM_ENTRY(func)     \
+   ".globl " func "\n"           \
+   ".type " func ", @function\n" \
+   ".balign 16\n"                \
+   func ":"
+
+#define STUB_ASM_CODE(slot)      \
+   "call x86_current_tls\n\t"    \
+   "movl %gs:(%eax), %eax\n\t"   \
+   "jmp *(4 * " slot ")(%eax)"
+
+#define MAPI_TMP_STUB_ASM_GCC
+#include "mapi_tmp.h"
+
+#ifndef GLX_X86_READONLY_TEXT
+__asm__(".balign 16\n"
+        "x86_entry_end:");
+__asm__(".text");
+#endif /* GLX_X86_READONLY_TEXT */
+
+extern unsigned long
+x86_current_tls();
+
+void
+entry_patch_public(void)
+{
+#ifndef GLX_X86_READONLY_TEXT
+   extern char x86_entry_start[];
+   extern char x86_entry_end[];
+   char patch[8] = {
+      0x65, 0xa1, 0x00, 0x00, 0x00, 0x00, /* movl %gs:0x0, %eax */
+      0x90, 0x90                          /* nop's */
+   };
+   char *entry;
+
+   *((unsigned long *) (patch + 2)) = x86_current_tls();
+
+   for (entry = x86_entry_start; entry < x86_entry_end; entry += 16)
+      memcpy(entry, patch, sizeof(patch));
+#endif
+}
+
+void
+entry_patch(mapi_func entry, int slot)
+{
+   char *code = (char *) entry;
+   *((unsigned long *) (code + 8)) = slot * sizeof(mapi_func);
+}
+
+mapi_func
+entry_generate(int slot)
+{
+   const char code_templ[16] = {
+      0x65, 0xa1, 0x00, 0x00, 0x00, 0x00, /* movl %gs:0x0, %eax */
+      0xff, 0xa0, 0x34, 0x12, 0x00, 0x00, /* jmp *0x1234(%eax) */
+      0x90, 0x90, 0x90, 0x90              /* nop's */
+   };
+   void *code;
+   mapi_func entry;
+
+   code = u_execmem_alloc(sizeof(code_templ));
+   if (!code)
+      return NULL;
+
+   memcpy(code, code_templ, sizeof(code_templ));
+
+   *((unsigned long *) (code + 2)) = x86_current_tls();
+   entry = (mapi_func) code;
+   entry_patch(entry, slot);
+
+   return entry;
+}
diff --git a/mesalib/src/mapi/mapi/entry_x86_tsd.h b/mesalib/src/mapi/mapi/entry_x86_tsd.h
new file mode 100644
index 000000000..f37c7473a
--- /dev/null
+++ b/mesalib/src/mapi/mapi/entry_x86_tsd.h
@@ -0,0 +1,89 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.9
+ *
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Chia-I Wu <olv@lunarg.com>
+ */
+
+#include <string.h>
+#include "u_execmem.h"
+#include "u_macros.h"
+
+#define X86_ENTRY_SIZE 32
+
+__asm__(".text");
+
+#define STUB_ASM_ENTRY(func)        \
+   ".globl " func "\n"              \
+   ".type " func ", @function\n"    \
+   ".balign 32\n"                   \
+   func ":"
+
+#define STUB_ASM_CODE(slot)         \
+   "movl u_current_table, %eax\n\t" \
+   "testl %eax, %eax\n\t"           \
+   "je 1f\n\t"                      \
+   "jmp *(4 * " slot ")(%eax)\n"    \
+   "1:\n\t"                         \
+   "call u_current_get_internal\n\t"\
+   "jmp *(4 * " slot ")(%eax)"
+
+#define MAPI_TMP_STUB_ASM_GCC
+#include "mapi_tmp.h"
+
+__asm__(".balign 32\n"
+        "x86_entry_end:");
+
+void
+entry_patch_public(void)
+{
+}
+
+void
+entry_patch(mapi_func entry, int slot)
+{
+   char *code = (char *) entry;
+
+   *((unsigned long *) (code + 11)) = slot * sizeof(mapi_func);
+   *((unsigned long *) (code + 22)) = slot * sizeof(mapi_func);
+}
+
+mapi_func
+entry_generate(int slot)
+{
+   extern const char x86_entry_end[];
+   const char *code_templ = x86_entry_end - X86_ENTRY_SIZE;
+   void *code;
+   mapi_func entry;
+
+   code = u_execmem_alloc(X86_ENTRY_SIZE);
+   if (!code)
+      return NULL;
+
+   memcpy(code, code_templ, X86_ENTRY_SIZE);
+   entry = (mapi_func) code;
+   entry_patch(entry, slot);
+
+   return entry;
+}
diff --git a/mesalib/src/mapi/mapi/mapi.c b/mesalib/src/mapi/mapi/mapi.c
new file mode 100644
index 000000000..2f1c3fff6
--- /dev/null
+++ b/mesalib/src/mapi/mapi/mapi.c
@@ -0,0 +1,191 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.9
+ *
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Chia-I Wu <olv@lunarg.com>
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "u_current.h"
+#include "u_thread.h"
+#include "mapi.h"
+#include "stub.h"
+#include "table.h"
+
+/* dynamic stubs will run out before this array */
+#define MAPI_MAX_STUBS (sizeof(struct mapi_table) / sizeof(mapi_func))
+static const struct mapi_stub *mapi_stub_map[MAPI_MAX_STUBS];
+static int mapi_num_stubs;
+
+static const struct mapi_stub *
+get_stub(const char *name, const struct mapi_stub *alias)
+{
+   const struct mapi_stub *stub;
+
+   stub = stub_find_public(name);
+   if (!stub) {
+      struct mapi_stub *dyn = stub_find_dynamic(name, 1);
+      if (dyn) {
+         stub_fix_dynamic(dyn, alias);
+         stub = dyn;
+      }
+   }
+
+   return stub;
+}
+
+/**
+ * Initialize mapi.  spec consists of NULL-separated strings.  The first string
+ * denotes the version.  It is followed by variable numbers of entries.  Each
+ * entry can have multiple names.  An empty name terminates an entry.  An empty
+ * entry terminates the spec.  A spec of two entries, Foo and Bar, is as
+ * follows
+ *
+ *   "1\0"
+ *   "Foo\0"
+ *   "FooEXT\0"
+ *   "\0"
+ *   "Bar\0"
+ *   "\0"
+ */
+void
+mapi_init(const char *spec)
+{
+   u_mutex_declare_static(mutex);
+   const char *p;
+   int ver, count;
+
+   u_mutex_lock(mutex);
+
+   /* already initialized */
+   if (mapi_num_stubs) {
+      u_mutex_unlock(mutex);
+      return;
+   }
+
+   count = 0;
+   p = spec;
+
+   /* parse version string */
+   ver = atoi(p);
+   if (ver != 1) {
+      u_mutex_unlock(mutex);
+      return;
+   }
+   p += strlen(p) + 1;
+
+   while (*p) {
+      const struct mapi_stub *stub;
+
+      stub = get_stub(p, NULL);
+      /* out of dynamic entries */
+      if (!stub)
+         break;
+      p += strlen(p) + 1;
+
+      while (*p) {
+         get_stub(p, stub);
+         p += strlen(p) + 1;
+      }
+
+      mapi_stub_map[count++] = stub;
+      p++;
+   }
+
+   mapi_num_stubs = count;
+
+   u_mutex_unlock(mutex);
+}
+
+/**
+ * Return the address of an entry.  Optionally generate the entry if it does
+ * not exist.
+ */
+mapi_proc
+mapi_get_proc_address(const char *name)
+{
+   const struct mapi_stub *stub;
+
+   stub = stub_find_public(name);
+   if (!stub)
+      stub = stub_find_dynamic(name, 0);
+
+   return (stub) ? (mapi_proc) stub->addr : NULL;
+}
+
+/**
+ * Create a dispatch table.
+ */
+struct mapi_table *
+mapi_table_create(void)
+{
+   const struct mapi_table *noop = table_get_noop();
+   struct mapi_table *tbl;
+
+   tbl = malloc(sizeof(*tbl));
+   if (tbl)
+      memcpy(tbl, noop, sizeof(*tbl));
+
+   return tbl;
+}
+
+/**
+ * Destroy a dispatch table.
+ */
+void
+mapi_table_destroy(struct mapi_table *tbl)
+{
+   free(tbl);
+}
+
+/**
+ * Fill a dispatch table.  The order of the procs is determined when mapi_init
+ * is called.
+ */
+void
+mapi_table_fill(struct mapi_table *tbl, const mapi_proc *procs)
+{
+   const struct mapi_table *noop = table_get_noop();
+   int i;
+
+   for (i = 0; i < mapi_num_stubs; i++) {
+      const struct mapi_stub *stub = mapi_stub_map[i];
+      mapi_func func = (mapi_func) procs[i];
+
+      if (!func)
+         func = table_get_func(noop, stub);
+      table_set_func(tbl, stub, func);
+   }
+}
+
+/**
+ * Make a dispatch table current.
+ */
+void
+mapi_table_make_current(const struct mapi_table *tbl)
+{
+   u_current_set(tbl);
+}
diff --git a/mesalib/src/mapi/mapi/mapi.h b/mesalib/src/mapi/mapi/mapi.h
new file mode 100644
index 000000000..c7e43e22e
--- /dev/null
+++ b/mesalib/src/mapi/mapi/mapi.h
@@ -0,0 +1,66 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.9
+ *
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Chia-I Wu <olv@lunarg.com>
+ */
+
+#ifndef _MAPI_H_
+#define _MAPI_H_
+
+#include "u_compiler.h"
+
+#ifdef _WIN32
+#ifdef MAPI_DLL_EXPORTS
+#define MAPI_EXPORT __declspec(dllexport)
+#else
+#define MAPI_EXPORT __declspec(dllimport)
+#endif
+#else /* _WIN32 */
+#define MAPI_EXPORT PUBLIC
+#endif
+
+typedef void (*mapi_proc)(void);
+
+struct mapi_table;
+
+MAPI_EXPORT void
+mapi_init(const char *spec);
+
+MAPI_EXPORT mapi_proc
+mapi_get_proc_address(const char *name);
+
+MAPI_EXPORT struct mapi_table *
+mapi_table_create(void);
+
+MAPI_EXPORT void
+mapi_table_destroy(struct mapi_table *tbl);
+
+MAPI_EXPORT void
+mapi_table_fill(struct mapi_table *tbl, const mapi_proc *procs);
+
+MAPI_EXPORT void
+mapi_table_make_current(const struct mapi_table *tbl);
+
+#endif /* _MAPI_H_ */
diff --git a/mesalib/src/mapi/mapi/mapi_abi.py b/mesalib/src/mapi/mapi/mapi_abi.py
new file mode 100644
index 000000000..440eb4bb9
--- /dev/null
+++ b/mesalib/src/mapi/mapi/mapi_abi.py
@@ -0,0 +1,402 @@
+#!/usr/bin/env python
+
+# Mesa 3-D graphics library
+# Version:  7.9
+#
+# Copyright (C) 2010 LunarG Inc.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+#
+# Authors:
+#    Chia-I Wu <olv@lunarg.com>
+
+import sys
+import re
+from optparse import OptionParser
+
+# number of dynamic entries
+ABI_NUM_DYNAMIC_ENTRIES = 256
+
+class ABIEntry(object):
+    """Represent an ABI entry."""
+
+    _match_c_param = re.compile(
+            '^(?P<type>[\w\s*]+?)(?P<name>\w+)(\[(?P<array>\d+)\])?$')
+
+    def __init__(self, cols, attrs):
+        self._parse(cols)
+
+        self.slot = attrs['slot']
+        self.hidden = attrs['hidden']
+        self.alias = attrs['alias']
+
+    def c_prototype(self):
+        return '%s %s(%s)' % (self.c_return(), self.name, self.c_params())
+
+    def c_return(self):
+        ret = self.ret
+        if not ret:
+            ret = 'void'
+
+        return ret
+
+    def c_params(self):
+        """Return the parameter list used in the entry prototype."""
+        c_params = []
+        for t, n, a in self.params:
+            sep = '' if t.endswith('*') else ' '
+            arr = '[%d]' % a if a else ''
+            c_params.append(t + sep + n + arr)
+        if not c_params:
+            c_params.append('void')
+
+        return ", ".join(c_params)
+
+    def c_args(self):
+        """Return the argument list used in the entry invocation."""
+        c_args = []
+        for t, n, a in self.params:
+            c_args.append(n)
+
+        return ", ".join(c_args)
+
+    def _parse(self, cols):
+        ret = cols.pop(0)
+        if ret == 'void':
+            ret = None
+
+        name = cols.pop(0)
+
+        params = []
+        if not cols:
+            raise Exception(cols)
+        elif len(cols) == 1 and cols[0] == 'void':
+            pass
+        else:
+            for val in cols:
+                params.append(self._parse_param(val))
+
+        self.ret = ret
+        self.name = name
+        self.params = params
+
+    def _parse_param(self, c_param):
+        m = self._match_c_param.match(c_param)
+        if not m:
+            raise Exception('unrecognized param ' + c_param)
+
+        c_type = m.group('type').strip()
+        c_name = m.group('name')
+        c_array = m.group('array')
+        c_array = int(c_array) if c_array else 0
+
+        return (c_type, c_name, c_array)
+
+    def __str__(self):
+        return self.c_prototype()
+
+    def __cmp__(self, other):
+        # compare slot, alias, and then name
+        res = cmp(self.slot, other.slot)
+        if not res:
+            if not self.alias:
+                res = -1
+            elif not other.alias:
+                res = 1
+
+            if not res:
+                res = cmp(self.name, other.name)
+
+        return res
+
+def abi_parse_line(line):
+    cols = [col.strip() for col in line.split(',')]
+
+    attrs = {
+            'slot': -1,
+            'hidden': False,
+            'alias': None,
+    }
+
+    # extract attributes from the first column
+    vals = cols[0].split(':')
+    while len(vals) > 1:
+        val = vals.pop(0)
+        if val.startswith('slot='):
+            attrs['slot'] = int(val[5:])
+        elif val == 'hidden':
+            attrs['hidden'] = True
+        elif val.startswith('alias='):
+            attrs['alias'] = val[6:]
+        elif not val:
+            pass
+        else:
+            raise Exception('unknown attribute %s' % val)
+    cols[0] = vals[0]
+
+    return (attrs, cols)
+
+def abi_parse(filename):
+    """Parse a CSV file for ABI entries."""
+    fp = open(filename) if filename != '-' else sys.stdin
+    lines = [line.strip() for line in fp.readlines()
+            if not line.startswith('#') and line.strip()]
+
+    entry_dict = {}
+    next_slot = 0
+    for line in lines:
+        attrs, cols = abi_parse_line(line)
+
+        # post-process attributes
+        if attrs['alias']:
+            try:
+                ent = entry_dict[attrs['alias']]
+                slot = ent.slot
+            except KeyError:
+                raise Exception('failed to alias %s' % attrs['alias'])
+        else:
+            slot = next_slot
+            next_slot += 1
+
+        if attrs['slot'] < 0:
+            attrs['slot'] = slot
+        elif attrs['slot'] != slot:
+            raise Exception('invalid slot in %s' % (line))
+
+        ent = ABIEntry(cols, attrs)
+        if entry_dict.has_key(ent.name):
+            raise Exception('%s is duplicated' % (ent.name))
+        entry_dict[ent.name] = ent
+
+    entries = entry_dict.values()
+    entries.sort()
+
+    # sanity check
+    i = 0
+    for slot in xrange(next_slot):
+        if entries[i].slot != slot:
+            raise Exception('entries are not ordered by slots')
+        if entries[i].alias:
+            raise Exception('first entry of slot %d aliases %s'
+                    % (slot, entries[i].alias))
+        while i < len(entries) and entries[i].slot == slot:
+            i += 1
+    if i < len(entries):
+        raise Exception('there are %d invalid entries' % (len(entries) - 1))
+
+    return entries
+
+def abi_dynamics():
+    """Return the dynamic entries."""
+    entries = []
+    for i in xrange(ABI_NUM_DYNAMIC_ENTRIES):
+        cols = ['void', 'dynamic%d' % (i), 'void']
+        attrs = { 'slot': -1, 'hidden': False, 'alias': None }
+        entries.append(ABIEntry(cols, attrs))
+    return entries
+
+class ABIPrinter(object):
+    """ABIEntry Printer"""
+
+    def __init__(self, entries, options):
+        self.entries = entries
+        self.options = options
+        self._undefs = []
+
+    def _add_undefs(self, undefs):
+        self._undefs.extend(undefs)
+
+    def output_header(self):
+        print '/* This file is automatically generated.  Do not modify. */'
+        print
+
+    def output_footer(self):
+        print '/* clean up */'
+        for m in self._undefs:
+            print '#undef %s' % (m)
+
+    def output_entry(self, ent):
+        if ent.slot < 0:
+            out_ent = 'MAPI_DYNAMIC_ENTRY(%s, %s, (%s))' % \
+                    (ent.c_return(), ent.name, ent.c_params())
+            out_code = ''
+        else:
+            if ent.alias:
+                macro_ent = 'MAPI_ALIAS_ENTRY'
+                macro_code = 'MAPI_ALIAS_CODE'
+            else:
+                macro_ent = 'MAPI_ABI_ENTRY'
+                macro_code = 'MAPI_ABI_CODE'
+
+            if ent.ret:
+                macro_code += '_RETURN'
+            if ent.hidden:
+                macro_ent += '_HIDDEN'
+                macro_code += '_HIDDEN'
+
+            if ent.alias:
+                out_ent = '%s(%s, %s, %s, (%s))' % (macro_ent,
+                        ent.alias, ent.c_return(), ent.name, ent.c_params())
+                out_code = '%s(%s, %s, %s, (%s))' % (macro_code,
+                        ent.alias, ent.c_return(), ent.name, ent.c_args())
+            else:
+                out_ent = '%s(%s, %s, (%s))' % (macro_ent,
+                        ent.c_return(), ent.name, ent.c_params())
+                out_code = '%s(%s, %s, (%s))' % (macro_code,
+                        ent.c_return(), ent.name, ent.c_args())
+
+        print out_ent
+        if out_code:
+            print '   ' + out_code
+
+    def output_entries(self, pool_offsets):
+        defs = [
+                # normal entries
+                ('MAPI_ABI_ENTRY', '(ret, name, params)', ''),
+                ('MAPI_ABI_CODE', '(ret, name, args)', ''),
+                ('MAPI_ABI_CODE_RETURN', '', 'MAPI_ABI_CODE'),
+                # alias entries
+                ('MAPI_ALIAS_ENTRY', '(alias, ret, name, params)', ''),
+                ('MAPI_ALIAS_CODE', '(alias, ret, name, args)', ''),
+                ('MAPI_ALIAS_CODE_RETURN', '', 'MAPI_ALIAS_CODE'),
+                # hidden normal entries
+                ('MAPI_ABI_ENTRY_HIDDEN', '', 'MAPI_ABI_ENTRY'),
+                ('MAPI_ABI_CODE_HIDDEN', '', 'MAPI_ABI_CODE'),
+                ('MAPI_ABI_CODE_RETURN_HIDDEN', '', 'MAPI_ABI_CODE_RETURN'),
+                # hidden alias entries
+                ('MAPI_ALIAS_ENTRY_HIDDEN', '', 'MAPI_ALIAS_ENTRY'),
+                ('MAPI_ALIAS_CODE_HIDDEN', '', 'MAPI_ALIAS_CODE'),
+                ('MAPI_ALIAS_CODE_RETURN_HIDDEN', '', 'MAPI_ALIAS_CODE_RETURN'),
+                # dynamic entries
+                ('MAPI_DYNAMIC_ENTRY', '(ret, name, params)', ''),
+        ]
+        undefs = [d[0] for d in defs]
+
+        print '#if defined(MAPI_ABI_ENTRY) || defined(MAPI_ABI_ENTRY_HIDDEN)'
+        print
+        for d in defs:
+            print '#ifndef %s' % (d[0])
+            if d[2]:
+                print '#define %s%s %s' % d
+            else:
+                print '#define %s%s' % d[:2]
+
+            print '#endif'
+        print
+
+        print '/* see MAPI_TMP_TABLE */'
+        for ent in self.entries:
+            print '#define MAPI_SLOT_%s %d' % (ent.name, ent.slot)
+        print
+        print '/* see MAPI_TMP_PUBLIC_STUBS */'
+        for ent in self.entries:
+            print '#define MAPI_POOL_%s %d' % (ent.name, pool_offsets[ent])
+        print
+
+        # define macros that generate code
+        for ent in self.entries:
+            self.output_entry(ent)
+        print
+        dynamics = abi_dynamics()
+        for ent in dynamics:
+            self.output_entry(ent)
+        print
+
+        for ent in self.entries:
+            print '#undef MAPI_SLOT_%s' % (ent.name)
+        for ent in self.entries:
+            print '#undef MAPI_POOL_%s' % (ent.name)
+        print
+        print '#endif /* defined(MAPI_ABI_ENTRY) || defined(MAPI_ABI_ENTRY_HIDDEN) */'
+        print
+
+        self._add_undefs(undefs)
+
+    def _get_string_pool(self):
+        """Get the string pool."""
+        pool = []
+        offsets = {}
+
+        count = 0
+        for ent in self.entries:
+            offsets[ent] = count
+            pool.append(ent.name + '\\0')
+            count += len(ent.name) + 1
+
+        return (pool, offsets)
+
+    def output_sorted_indices(self):
+        entry_index_pairs = []
+        for i in xrange(len(self.entries)):
+            entry_index_pairs.append((self.entries[i], i))
+        entry_index_pairs.sort(lambda x, y: cmp(x[0].name, y[0].name))
+
+        print '/* see MAPI_TMP_PUBLIC_STUBS */'
+        print '#ifdef MAPI_ABI_SORTED_INDICES'
+        print
+        print 'static const int MAPI_ABI_SORTED_INDICES[] = {'
+        for ent, idx in entry_index_pairs:
+            print '   %d, /* %s */' % (idx, ent.name)
+        print '   -1'
+        print '};'
+        print
+        print '#endif /* MAPI_ABI_SORTED_INDICES */'
+        print
+
+        self._add_undefs(['MAPI_ABI_SORTED_INDICES'])
+
+    def output_defines(self):
+        print '/* ABI defines */'
+        print '#ifdef MAPI_ABI_DEFINES'
+        print '#include "%s"' % (self.options.include)
+        print '#endif /* MAPI_ABI_DEFINES */'
+        print
+
+        self._add_undefs(['MAPI_ABI_DEFINES'])
+
+    def output(self):
+        pool, pool_offsets = self._get_string_pool()
+
+        self.output_header()
+        self.output_defines()
+        self.output_entries(pool_offsets)
+        self.output_sorted_indices()
+        self.output_footer()
+
+def parse_args():
+    parser = OptionParser(usage='usage: %prog [options] <filename>')
+    parser.add_option('-i', '--include', dest='include',
+            help='include the header for API defines')
+
+    options, args = parser.parse_args()
+    if not args or not options.include:
+        parser.print_help()
+        sys.exit(1)
+
+    return (args[0], options)
+
+def main():
+    filename, options = parse_args()
+
+    entries = abi_parse(filename)
+    printer = ABIPrinter(entries, options)
+    printer.output()
+
+if __name__ == '__main__':
+    main()
diff --git a/mesalib/src/mapi/mapi/mapi_tmp.h b/mesalib/src/mapi/mapi/mapi_tmp.h
new file mode 100644
index 000000000..79beca47d
--- /dev/null
+++ b/mesalib/src/mapi/mapi/mapi_tmp.h
@@ -0,0 +1,211 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.9
+ *
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Chia-I Wu <olv@lunarg.com>
+ */
+
+#include "u_macros.h"
+
+#ifndef MAPI_ABI_HEADER
+#error "MAPI_ABI_HEADER must be defined"
+#endif
+
+
+/**
+ * Get API defines.
+ */
+#ifdef MAPI_TMP_DEFINES
+#   define MAPI_ABI_DEFINES
+#   include MAPI_ABI_HEADER
+
+#ifndef MAPI_ABI_PREFIX
+#error "MAPI_ABI_PREFIX must be defined"
+#endif
+#ifndef MAPI_ABI_PUBLIC
+#error "MAPI_ABI_PUBLIC must be defined"
+#endif
+#ifndef MAPI_ABI_ATTR
+#error "MAPI_ABI_ATTR must be defined"
+#endif
+
+#undef MAPI_TMP_DEFINES
+#endif /* MAPI_TMP_DEFINES */
+
+
+/**
+ * Generate fields of struct mapi_table.
+ */
+#ifdef MAPI_TMP_TABLE
+#   define MAPI_ABI_ENTRY(ret, name, params)                   \
+      ret (MAPI_ABI_ATTR *name) params;
+#   define MAPI_DYNAMIC_ENTRY(ret, name, params)               \
+      ret (MAPI_ABI_ATTR *name) params;
+#   include MAPI_ABI_HEADER
+#undef MAPI_TMP_TABLE
+#endif /* MAPI_TMP_TABLE */
+
+
+/**
+ * Declare public entries.
+ */
+#ifdef MAPI_TMP_PUBLIC_DECLARES
+#   define MAPI_ABI_ENTRY(ret, name, params)                   \
+      MAPI_ABI_PUBLIC ret MAPI_ABI_ATTR U_CONCAT(MAPI_ABI_PREFIX, name) params;
+#   define MAPI_ALIAS_ENTRY(alias, ret, name, params)          \
+      MAPI_ABI_ENTRY(ret, name, params);
+#   define MAPI_ABI_ENTRY_HIDDEN(ret, name, params)            \
+      HIDDEN ret MAPI_ABI_ATTR U_CONCAT(MAPI_ABI_PREFIX, name) params;
+#   define MAPI_ALIAS_ENTRY_HIDDEN(alias, ret, name, params)   \
+      MAPI_ABI_ENTRY_HIDDEN(ret, name, params)
+#   include MAPI_ABI_HEADER
+#undef MAPI_TMP_PUBLIC_DECLARES
+#endif /* MAPI_TMP_PUBLIC_DECLARES */
+
+
+/**
+ * Generate string pool and public stubs.
+ */
+#ifdef MAPI_TMP_PUBLIC_STUBS
+/* define the string pool */
+static const char public_string_pool[] =
+#   define MAPI_ABI_ENTRY(ret, name, params)                   \
+      U_STRINGIFY(name) "\0"
+#   define MAPI_ALIAS_ENTRY(alias, ret, name, params)          \
+      MAPI_ABI_ENTRY(ret, name, params)
+#   include MAPI_ABI_HEADER
+   ;
+/* define public_sorted_indices */
+#   define MAPI_ABI_SORTED_INDICES public_sorted_indices
+#   include MAPI_ABI_HEADER
+
+/* define public_stubs */
+static const struct mapi_stub public_stubs[] = {
+#   define MAPI_ABI_ENTRY(ret, name, params)                   \
+      { (mapi_func) U_CONCAT(MAPI_ABI_PREFIX, name),           \
+         MAPI_SLOT_ ## name, (void *) MAPI_POOL_ ## name },
+#   define MAPI_ALIAS_ENTRY(alias, ret, name, params)          \
+      MAPI_ABI_ENTRY(ret, name, params)
+#   include MAPI_ABI_HEADER
+   { NULL, -1, (void *) -1 }
+};
+
+#undef MAPI_TMP_PUBLIC_STUBS
+#endif /* MAPI_TMP_PUBLIC_STUBS */
+
+
+/**
+ * Generate public entries.
+ */
+#ifdef MAPI_TMP_PUBLIC_ENTRIES
+#   define MAPI_ABI_ENTRY(ret, name, params)                   \
+      ret MAPI_ABI_ATTR U_CONCAT(MAPI_ABI_PREFIX, name) params
+#   define MAPI_ABI_CODE(ret, name, args)                      \
+      {                                                        \
+         const struct mapi_table *tbl = u_current_get();       \
+         tbl->name args;                                       \
+      }
+#   define MAPI_ABI_CODE_RETURN(ret, name, args)               \
+      {                                                        \
+         const struct mapi_table *tbl = u_current_get();       \
+         return tbl->name args;                                \
+      }
+#   define MAPI_ALIAS_ENTRY(alias, ret, name, params)          \
+      MAPI_ABI_ENTRY(ret, name, params)
+#   define MAPI_ALIAS_CODE(alias, ret, name, args)             \
+      MAPI_ABI_CODE(ret, alias, args)
+#   define MAPI_ALIAS_CODE_RETURN(alias, ret, name, args)      \
+      MAPI_ABI_CODE_RETURN(ret, alias, args)
+#   include MAPI_ABI_HEADER
+#undef MAPI_TMP_PUBLIC_ENTRIES
+#endif /* MAPI_TMP_PUBLIC_ENTRIES */
+
+
+/**
+ * Generate noop entries.
+ */
+#ifdef MAPI_TMP_NOOP_ARRAY
+#ifdef DEBUG
+#   define MAPI_ABI_ENTRY(ret, name, params)                         \
+      static ret MAPI_ABI_ATTR U_CONCAT(noop_, name) params
+#   define MAPI_ABI_CODE(ret, name, args)                            \
+      {                                                              \
+         noop_warn(U_CONCAT_STR(MAPI_ABI_PREFIX, name));             \
+      }
+#   define MAPI_ABI_CODE_RETURN(ret, name, args)                     \
+      {                                                              \
+         noop_warn(U_CONCAT_STR(MAPI_ABI_PREFIX, name));             \
+         return (ret) 0;                                             \
+      }
+#   include MAPI_ABI_HEADER
+
+/* define the noop function array that may be casted to mapi_table */
+const mapi_func table_noop_array[] = {
+#   define MAPI_ABI_ENTRY(ret, name, params)                   \
+      (mapi_func) U_CONCAT(noop_, name),
+#   define MAPI_DYNAMIC_ENTRY(ret, name, params)               \
+      (mapi_func) noop_generic,
+#   include MAPI_ABI_HEADER
+      (mapi_func) noop_generic
+};
+
+#else /* DEBUG */
+
+const mapi_func table_noop_array[] = {
+#   define MAPI_ABI_ENTRY(ret, name, params)                   \
+      (mapi_func) noop_generic,
+#   define MAPI_DYNAMIC_ENTRY(ret, name, params)               \
+      (mapi_func) noop_generic,
+#   include MAPI_ABI_HEADER
+      (mapi_func) noop_generic
+};
+
+#endif /* DEBUG */
+#undef MAPI_TMP_NOOP_ARRAY
+#endif /* MAPI_TMP_NOOP_ARRAY */
+
+
+#ifdef MAPI_TMP_STUB_ASM_GCC
+#   define STUB_ASM_ALIAS(func, to)    \
+      ".globl " func "\n"              \
+      ".set " func ", " to
+#   define STUB_ASM_HIDE(func)         \
+      ".hidden " func
+
+#   define MAPI_ABI_ENTRY(ret, name, params)                         \
+      __asm__(STUB_ASM_ENTRY(U_CONCAT_STR(MAPI_ABI_PREFIX, name)));
+#   define MAPI_ABI_CODE(ret, name, args)                            \
+      __asm__(STUB_ASM_CODE(U_STRINGIFY(MAPI_SLOT_ ## name)));
+#   define MAPI_ALIAS_ENTRY(alias, ret, name, params)                \
+      __asm__(STUB_ASM_ALIAS(U_CONCAT_STR(MAPI_ABI_PREFIX, name),    \
+            U_CONCAT_STR(MAPI_ABI_PREFIX, alias)));
+#   define MAPI_ABI_ENTRY_HIDDEN(ret, name, params)                  \
+      __asm__(STUB_ASM_HIDE(U_CONCAT_STR(MAPI_ABI_PREFIX, name)));   \
+      MAPI_ABI_ENTRY(ret, name, params);
+#   define MAPI_ALIAS_ENTRY_HIDDEN(alias, ret, name, params)         \
+      __asm__(STUB_ASM_HIDE(U_CONCAT_STR(MAPI_ABI_PREFIX, name)));   \
+      MAPI_ALIAS_ENTRY(alias, ret, name, params);
+#   include MAPI_ABI_HEADER
+#undef MAPI_TMP_STUB_ASM_GCC
+#endif /* MAPI_TMP_STUB_ASM_GCC */
diff --git a/mesalib/src/mapi/mapi/sources.mak b/mesalib/src/mapi/mapi/sources.mak
new file mode 100644
index 000000000..5f327f3df
--- /dev/null
+++ b/mesalib/src/mapi/mapi/sources.mak
@@ -0,0 +1,19 @@
+# src/mapi/mapi/sources.mak
+#
+# When MAPI_GLAPI_CURRENT is defined, MAPI_GLAPI_SOURCES can be built without
+# MAPI_SOURCES and it is used by glapi.
+#
+# Otherwise, MAPI_ABI_HEADER must be defined.  It should expand to the header
+# generated by mapi_abi.py.
+
+MAPI_GLAPI_SOURCES = \
+	u_current.c \
+	u_execmem.c \
+	u_thread.c
+
+MAPI_SOURCES = \
+	entry.c \
+	mapi.c \
+	stub.c \
+	table.c \
+	$(MAPI_GLAPI_SOURCES)
diff --git a/mesalib/src/mapi/mapi/stub.c b/mesalib/src/mapi/mapi/stub.c
new file mode 100644
index 000000000..8ceaec313
--- /dev/null
+++ b/mesalib/src/mapi/mapi/stub.c
@@ -0,0 +1,180 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.9
+ *
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Chia-I Wu <olv@lunarg.com>
+ */
+
+#include <stdlib.h>
+#include <stddef.h> /* for offsetof */
+#include <string.h>
+#include <assert.h>
+
+#include "u_current.h"
+#include "u_thread.h"
+#include "entry.h"
+#include "stub.h"
+#include "table.h"
+
+#define MAPI_TABLE_FIRST_DYNAMIC \
+   (offsetof(struct mapi_table, dynamic0) / sizeof(mapi_func))
+#define MAPI_TABLE_NUM_DYNAMIC \
+   ((offsetof(struct mapi_table, last) - \
+     offsetof(struct mapi_table, dynamic0)) / sizeof(mapi_func))
+#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))
+
+/*
+ * This will define public_string_pool, public_sorted_indices, and
+ * public_stubs.
+ */
+#define MAPI_TMP_PUBLIC_STUBS
+#include "mapi_tmp.h"
+
+static struct mapi_stub dynamic_stubs[MAPI_TABLE_NUM_DYNAMIC];
+static int num_dynamic_stubs;
+static int next_dynamic_slot = MAPI_TABLE_FIRST_DYNAMIC;
+
+void
+stub_init_once(void)
+{
+#ifdef PTHREADS
+   static pthread_once_t once = PTHREAD_ONCE_INIT;
+   pthread_once(&once, entry_patch_public);
+#else
+   static int first = 1;
+   if (first) {
+      first = 0;
+      entry_patch_public();
+   }
+#endif
+}
+
+static int
+stub_compare(const void *key, const void *elem)
+{
+   const char *name = (const char *) key;
+   const int *index = (const int *) elem;
+   const struct mapi_stub *stub;
+   const char *stub_name;
+
+   stub = &public_stubs[*index];
+   stub_name = &public_string_pool[(unsigned long) stub->name];
+
+   return strcmp(name, stub_name);
+}
+
+/**
+ * Return the public stub with the given name.
+ */
+const struct mapi_stub *
+stub_find_public(const char *name)
+{
+   const int *index;
+
+   index = (const int *) bsearch(name, public_sorted_indices,
+         ARRAY_SIZE(public_sorted_indices) - 1,
+         sizeof(public_sorted_indices[0]), stub_compare);
+
+   return (index) ? &public_stubs[*index] : NULL;
+}
+
+/**
+ * Add a dynamic stub.
+ */
+static struct mapi_stub *
+stub_add_dynamic(const char *name)
+{
+   struct mapi_stub *stub;
+   int idx;
+
+   idx = num_dynamic_stubs;
+   if (idx >= MAPI_TABLE_NUM_DYNAMIC)
+      return NULL;
+
+   stub = &dynamic_stubs[idx];
+
+   /* dispatch to mapi_table->last, which is always no-op */
+   stub->addr =
+      entry_generate(MAPI_TABLE_FIRST_DYNAMIC + MAPI_TABLE_NUM_DYNAMIC);
+   if (!stub->addr)
+      return NULL;
+
+   stub->name = (const void *) name;
+   /* to be fixed later */
+   stub->slot = -1;
+
+   num_dynamic_stubs = idx + 1;
+
+   return stub;
+}
+
+/**
+ * Return the dynamic stub with the given name.  If no such stub exists and
+ * generate is true, a new stub is generated.
+ */
+struct mapi_stub *
+stub_find_dynamic(const char *name, int generate)
+{
+   u_mutex_declare_static(dynamic_mutex);
+   struct mapi_stub *stub = NULL;
+   int count, i;
+   
+   u_mutex_lock(dynamic_mutex);
+
+   if (generate)
+      assert(!stub_find_public(name));
+
+   count = num_dynamic_stubs;
+   for (i = 0; i < count; i++) {
+      if (strcmp(name, (const char *) dynamic_stubs[i].name) == 0) {
+         stub = &dynamic_stubs[i];
+         break;
+      }
+   }
+
+   /* generate a dynamic stub */
+   if (generate && !stub)
+         stub = stub_add_dynamic(name);
+
+   u_mutex_unlock(dynamic_mutex);
+
+   return stub;
+}
+
+void
+stub_fix_dynamic(struct mapi_stub *stub, const struct mapi_stub *alias)
+{
+   int slot;
+
+   if (stub->slot >= 0)
+      return;
+
+   if (alias)
+      slot = alias->slot;
+   else
+      slot = next_dynamic_slot++;
+
+   entry_patch(stub->addr, slot);
+   stub->slot = slot;
+}
diff --git a/mesalib/src/mapi/mapi/stub.h b/mesalib/src/mapi/mapi/stub.h
new file mode 100644
index 000000000..c7e194cf4
--- /dev/null
+++ b/mesalib/src/mapi/mapi/stub.h
@@ -0,0 +1,52 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.9
+ *
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Chia-I Wu <olv@lunarg.com>
+ */
+
+#ifndef _STUB_H_
+#define _STUB_H_
+
+typedef void (*mapi_func)(void);
+
+struct mapi_stub {
+   mapi_func addr;
+   int slot;
+   const void *name;
+};
+
+void
+stub_init_once(void);
+
+const struct mapi_stub *
+stub_find_public(const char *name);
+
+struct mapi_stub *
+stub_find_dynamic(const char *name, int generate);
+
+void
+stub_fix_dynamic(struct mapi_stub *stub, const struct mapi_stub *alias);
+
+#endif /* _STUB_H_ */
diff --git a/mesalib/src/mapi/mapi/table.c b/mesalib/src/mapi/mapi/table.c
new file mode 100644
index 000000000..8f4f700b9
--- /dev/null
+++ b/mesalib/src/mapi/mapi/table.c
@@ -0,0 +1,56 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.9
+ *
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Chia-I Wu <olv@lunarg.com>
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "stub.h"
+#include "table.h"
+
+static void
+noop_warn(const char *name)
+{
+   static int debug = -1;
+   
+   if (debug < 0)
+      debug = (getenv("MESA_DEBUG") || getenv("LIBGL_DEBUG"));
+
+   if (debug)
+      fprintf(stderr, "%s is no-op", name);
+}
+
+static int
+noop_generic(void)
+{
+   noop_warn("function");
+   return 0;
+}
+
+/* define noop_array */
+#define MAPI_TMP_NOOP_ARRAY
+#include "mapi_tmp.h"
diff --git a/mesalib/src/mapi/mapi/table.h b/mesalib/src/mapi/mapi/table.h
new file mode 100644
index 000000000..48c99018a
--- /dev/null
+++ b/mesalib/src/mapi/mapi/table.h
@@ -0,0 +1,76 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.9
+ *
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Chia-I Wu <olv@lunarg.com>
+ */
+
+#ifndef _TABLE_H_
+#define _TABLE_H_
+
+#include "u_compiler.h"
+#include "stub.h"
+
+#define MAPI_TMP_DEFINES
+#include "mapi_tmp.h"
+
+struct mapi_table {
+#define MAPI_TMP_TABLE
+#include "mapi_tmp.h"
+   mapi_func last;
+};
+
+extern const mapi_func table_noop_array[];
+
+/**
+ * Get the no-op dispatch table.
+ */
+static INLINE const struct mapi_table *
+table_get_noop(void)
+{
+   return (const struct mapi_table *) table_noop_array;
+}
+
+/**
+ * Update the dispatch table to dispatch a stub to the given function.
+ */
+static INLINE void
+table_set_func(struct mapi_table *tbl,
+               const struct mapi_stub *stub, mapi_func func)
+{
+   mapi_func *funcs = (mapi_func *) tbl;
+   funcs[stub->slot] = func;
+}
+
+/**
+ * Return the dispatched function of a stub.
+ */
+static INLINE mapi_func
+table_get_func(const struct mapi_table *tbl, const struct mapi_stub *stub)
+{
+   const mapi_func *funcs = (const mapi_func *) tbl;
+   return funcs[stub->slot];
+}
+
+#endif /* _TABLE_H_ */
diff --git a/mesalib/src/mapi/mapi/u_compiler.h b/mesalib/src/mapi/mapi/u_compiler.h
new file mode 100644
index 000000000..f1752d16f
--- /dev/null
+++ b/mesalib/src/mapi/mapi/u_compiler.h
@@ -0,0 +1,48 @@
+#ifndef _U_COMPILER_H_
+#define _U_COMPILER_H_
+
+/* Function inlining */
+#ifndef INLINE
+#  ifdef __cplusplus
+#    define INLINE inline
+#  elif defined(__GNUC__)
+#    define INLINE __inline__
+#  elif defined(_MSC_VER)
+#    define INLINE __inline
+#  elif defined(__ICL)
+#    define INLINE __inline
+#  elif defined(__INTEL_COMPILER)
+#    define INLINE inline
+#  elif defined(__WATCOMC__) && (__WATCOMC__ >= 1100)
+#    define INLINE __inline
+#  elif defined(__SUNPRO_C) && defined(__C99FEATURES__)
+#    define INLINE inline
+#  elif (__STDC_VERSION__ >= 199901L) /* C99 */
+#    define INLINE inline
+#  else
+#    define INLINE
+#  endif
+#endif
+
+/* Function visibility */
+#ifndef PUBLIC
+#  if defined(__GNUC__) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590))
+#    define PUBLIC __attribute__((visibility("default")))
+#  elif defined(_MSC_VER)
+#    define PUBLIC __declspec(dllexport)
+#  else
+#    define PUBLIC
+#  endif
+#endif
+
+#ifndef likely
+#  if defined(__GNUC__)
+#    define likely(x)   __builtin_expect(!!(x), 1)
+#    define unlikely(x) __builtin_expect(!!(x), 0)
+#  else
+#    define likely(x)   (x)
+#    define unlikely(x) (x)
+#  endif
+#endif
+
+#endif /* _U_COMPILER_H_ */
diff --git a/mesalib/src/mapi/mapi/u_current.c b/mesalib/src/mapi/mapi/u_current.c
new file mode 100644
index 000000000..ed9ccfe22
--- /dev/null
+++ b/mesalib/src/mapi/mapi/u_current.c
@@ -0,0 +1,277 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.1
+ *
+ * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+/*
+ * This file manages the OpenGL API dispatch layer.
+ * The dispatch table (struct _glapi_table) is basically just a list
+ * of function pointers.
+ * There are functions to set/get the current dispatch table for the
+ * current thread and to manage registration/dispatch of dynamically
+ * added extension functions.
+ *
+ * It's intended that this file and the other glapi*.[ch] files are
+ * flexible enough to be reused in several places:  XFree86, DRI-
+ * based libGL.so, and perhaps the SGI SI.
+ *
+ * NOTE: There are no dependencies on Mesa in this code.
+ *
+ * Versions (API changes):
+ *   2000/02/23  - original version for Mesa 3.3 and XFree86 4.0
+ *   2001/01/16  - added dispatch override feature for Mesa 3.5
+ *   2002/06/28  - added _glapi_set_warning_func(), Mesa 4.1.
+ *   2002/10/01  - _glapi_get_proc_address() will now generate new entrypoints
+ *                 itself (using offset ~0).  _glapi_add_entrypoint() can be
+ *                 called afterward and it'll fill in the correct dispatch
+ *                 offset.  This allows DRI libGL to avoid probing for DRI
+ *                 drivers!  No changes to the public glapi interface.
+ */
+
+#include "u_current.h"
+#include "u_thread.h"
+
+#ifndef MAPI_GLAPI_CURRENT
+
+#include "table.h"
+#include "stub.h"
+
+#else
+
+extern void init_glapi_relocs_once(void);
+extern void (*__glapi_noop_table[])(void);
+
+#define table_noop_array __glapi_noop_table
+#define stub_init_once() init_glapi_relocs_once()
+
+#endif
+
+/**
+ * \name Current dispatch and current context control variables
+ *
+ * Depending on whether or not multithreading is support, and the type of
+ * support available, several variables are used to store the current context
+ * pointer and the current dispatch table pointer.  In the non-threaded case,
+ * the variables \c _glapi_Dispatch and \c _glapi_Context are used for this
+ * purpose.
+ *
+ * In the "normal" threaded case, the variables \c _glapi_Dispatch and
+ * \c _glapi_Context will be \c NULL if an application is detected as being
+ * multithreaded.  Single-threaded applications will use \c _glapi_Dispatch
+ * and \c _glapi_Context just like the case without any threading support.
+ * When \c _glapi_Dispatch and \c _glapi_Context are \c NULL, the thread state
+ * data \c _gl_DispatchTSD and \c ContextTSD are used.  Drivers and the
+ * static dispatch functions access these variables via \c _glapi_get_dispatch
+ * and \c _glapi_get_context.
+ *
+ * There is a race condition in setting \c _glapi_Dispatch to \c NULL.  It is
+ * possible for the original thread to be setting it at the same instant a new
+ * thread, perhaps running on a different processor, is clearing it.  Because
+ * of that, \c ThreadSafe, which can only ever be changed to \c GL_TRUE, is
+ * used to determine whether or not the application is multithreaded.
+ * 
+ * In the TLS case, the variables \c _glapi_Dispatch and \c _glapi_Context are
+ * hardcoded to \c NULL.  Instead the TLS variables \c _glapi_tls_Dispatch and
+ * \c _glapi_tls_Context are used.  Having \c _glapi_Dispatch and
+ * \c _glapi_Context be hardcoded to \c NULL maintains binary compatability
+ * between TLS enabled loaders and non-TLS DRI drivers.
+ */
+/*@{*/
+#if defined(GLX_USE_TLS)
+
+__thread struct mapi_table *u_current_table_tls
+    __attribute__((tls_model("initial-exec")))
+    = (struct mapi_table *) table_noop_array;
+
+__thread void *u_current_user_tls
+    __attribute__((tls_model("initial-exec")));
+
+const struct mapi_table *u_current_table;
+const void *u_current_user;
+
+#else
+
+struct mapi_table *u_current_table =
+   (struct mapi_table *) table_noop_array;
+void *u_current_user;
+
+#ifdef THREADS
+struct u_tsd u_current_table_tsd;
+static struct u_tsd u_current_user_tsd;
+static int ThreadSafe;
+#endif /* THREADS */
+
+#endif /* defined(GLX_USE_TLS) */
+/*@}*/
+
+
+void
+u_current_destroy(void)
+{
+#if defined(THREADS) && defined(WIN32_THREADS)
+   u_tsd_destroy(&u_current_table_tsd);
+   u_tsd_destroy(&u_current_user_tsd);
+#endif
+}
+
+
+#if defined(THREADS) && !defined(GLX_USE_TLS)
+
+static void
+u_current_init_tsd(void)
+{
+   u_tsd_init(&u_current_table_tsd);
+   u_tsd_init(&u_current_user_tsd);
+}
+
+/**
+ * Mutex for multithread check.
+ */
+#ifdef WIN32_THREADS
+/* _glthread_DECLARE_STATIC_MUTEX is broken on windows.  There will be race! */
+#define CHECK_MULTITHREAD_LOCK()
+#define CHECK_MULTITHREAD_UNLOCK()
+#else
+u_mutex_declare_static(ThreadCheckMutex);
+#define CHECK_MULTITHREAD_LOCK() u_mutex_lock(ThreadCheckMutex)
+#define CHECK_MULTITHREAD_UNLOCK() u_mutex_unlock(ThreadCheckMutex)
+#endif
+
+/**
+ * We should call this periodically from a function such as glXMakeCurrent
+ * in order to test if multiple threads are being used.
+ */
+void
+u_current_init(void)
+{
+   static unsigned long knownID;
+   static int firstCall = 1;
+
+   if (ThreadSafe)
+      return;
+
+   CHECK_MULTITHREAD_LOCK();
+   if (firstCall) {
+      u_current_init_tsd();
+
+      knownID = u_thread_self();
+      firstCall = 0;
+   }
+   else if (knownID != u_thread_self()) {
+      ThreadSafe = 1;
+      u_current_set_internal(NULL);
+      u_current_set_user_internal(NULL);
+   }
+   CHECK_MULTITHREAD_UNLOCK();
+}
+
+#else
+
+void
+u_current_init(void)
+{
+}
+
+#endif
+
+
+
+/**
+ * Set the current context pointer for this thread.
+ * The context pointer is an opaque type which should be cast to
+ * void from the real context pointer type.
+ */
+void
+u_current_set_user_internal(void *ptr)
+{
+   u_current_init();
+
+#if defined(GLX_USE_TLS)
+   u_current_user_tls = ptr;
+#elif defined(THREADS)
+   u_tsd_set(&u_current_user_tsd, ptr);
+   u_current_user = (ThreadSafe) ? NULL : ptr;
+#else
+   u_current_user = ptr;
+#endif
+}
+
+/**
+ * Get the current context pointer for this thread.
+ * The context pointer is an opaque type which should be cast from
+ * void to the real context pointer type.
+ */
+void *
+u_current_get_user_internal(void)
+{
+#if defined(GLX_USE_TLS)
+   return u_current_user_tls;
+#elif defined(THREADS)
+   return (ThreadSafe)
+      ? u_tsd_get(&u_current_user_tsd)
+      : u_current_user;
+#else
+   return u_current_user;
+#endif
+}
+
+/**
+ * Set the global or per-thread dispatch table pointer.
+ * If the dispatch parameter is NULL we'll plug in the no-op dispatch
+ * table (__glapi_noop_table).
+ */
+void
+u_current_set_internal(struct mapi_table *tbl)
+{
+   u_current_init();
+
+   stub_init_once();
+
+   if (!tbl)
+      tbl = (struct mapi_table *) table_noop_array;
+
+#if defined(GLX_USE_TLS)
+   u_current_table_tls = tbl;
+#elif defined(THREADS)
+   u_tsd_set(&u_current_table_tsd, (void *) tbl);
+   u_current_table = (ThreadSafe) ? NULL : tbl;
+#else
+   u_current_table = tbl;
+#endif
+}
+
+/**
+ * Return pointer to current dispatch table for calling thread.
+ */
+struct mapi_table *
+u_current_get_internal(void)
+{
+#if defined(GLX_USE_TLS)
+   return u_current_table_tls;
+#elif defined(THREADS)
+   return (struct mapi_table *) ((ThreadSafe) ?
+         u_tsd_get(&u_current_table_tsd) : (void *) u_current_table);
+#else
+   return u_current_table;
+#endif
+}
diff --git a/mesalib/src/mapi/mapi/u_current.h b/mesalib/src/mapi/mapi/u_current.h
new file mode 100644
index 000000000..62e54c6c9
--- /dev/null
+++ b/mesalib/src/mapi/mapi/u_current.h
@@ -0,0 +1,102 @@
+#ifndef _U_CURRENT_H_
+#define _U_CURRENT_H_
+
+#ifdef MAPI_GLAPI_CURRENT
+
+#include "glapi/glapi.h"
+
+/* ugly renames to match glapi.h */
+#define mapi_table _glapi_table
+
+#define u_current_table_tls _glapi_tls_Dispatch
+#define u_current_user_tls _glapi_tls_Context
+#define u_current_table _glapi_Dispatch
+#define u_current_user _glapi_Context
+
+#define u_current_destroy _glapi_destroy_multithread
+#define u_current_init _glapi_check_multithread
+#define u_current_set_internal _glapi_set_dispatch
+#define u_current_get_internal _glapi_get_dispatch
+#define u_current_set_user_internal _glapi_set_context
+#define u_current_get_user_internal _glapi_get_context
+
+#define u_current_table_tsd _gl_DispatchTSD
+
+#else /* MAPI_GLAPI_CURRENT */
+
+#include "u_compiler.h"
+
+struct mapi_table;
+
+#ifdef GLX_USE_TLS
+
+extern __thread struct mapi_table *u_current_table_tls
+    __attribute__((tls_model("initial-exec")));
+
+extern __thread void *u_current_user_tls
+    __attribute__((tls_model("initial-exec")));
+
+extern const struct mapi_table *u_current_table;
+extern const void *u_current_user;
+
+#else /* GLX_USE_TLS */
+
+extern struct mapi_table *u_current_table;
+extern void *u_current_user;
+
+#endif /* GLX_USE_TLS */
+
+void
+u_current_init(void);
+
+void
+u_current_destroy(void);
+
+void
+u_current_set_internal(struct mapi_table *tbl);
+
+struct mapi_table *
+u_current_get_internal(void);
+
+void
+u_current_set_user_internal(void *ptr);
+
+void *
+u_current_get_user_internal(void);
+
+static INLINE void
+u_current_set(const struct mapi_table *tbl)
+{
+   u_current_set_internal((struct mapi_table *) tbl);
+}
+
+static INLINE const struct mapi_table *
+u_current_get(void)
+{
+#ifdef GLX_USE_TLS
+   return (const struct mapi_table *) u_current_table_tls;
+#else
+   return (likely(u_current_table) ?
+         (const struct mapi_table *) u_current_table : u_current_get_internal());
+#endif
+}
+
+static INLINE void
+u_current_set_user(void *ptr)
+{
+   u_current_set_internal(ptr);
+}
+
+static INLINE void *
+u_current_get_user(void)
+{
+#ifdef GLX_USE_TLS
+   return u_current_user_tls;
+#else
+   return likely(u_current_user) ? u_current_user : u_current_get_user_internal();
+#endif
+}
+
+#endif /* MAPI_GLAPI_CURRENT */
+
+#endif /* _U_CURRENT_H_ */
diff --git a/mesalib/src/mapi/mapi/u_execmem.c b/mesalib/src/mapi/mapi/u_execmem.c
new file mode 100644
index 000000000..e5072e06e
--- /dev/null
+++ b/mesalib/src/mapi/mapi/u_execmem.c
@@ -0,0 +1,145 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  6.5
+ *
+ * Copyright (C) 1999-2005  Brian Paul   All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+/**
+ * \file glapi_execmem.c
+ *
+ * Function for allocating executable memory for dispatch stubs.
+ *
+ * Copied from main/execmem.c and simplified for dispatch stubs.
+ */
+
+
+#include "u_compiler.h"
+#include "u_thread.h"
+#include "u_execmem.h"
+
+
+#define EXEC_MAP_SIZE (4*1024)
+
+u_mutex_declare_static(exec_mutex);
+
+static unsigned int head = 0;
+
+static unsigned char *exec_mem = (unsigned char *)0;
+
+
+#if defined(__linux__) || defined(__OpenBSD__) || defined(_NetBSD__) || defined(__sun)
+
+#include <unistd.h>
+#include <sys/mman.h>
+
+#ifdef MESA_SELINUX
+#include <selinux/selinux.h>
+#endif
+
+
+#ifndef MAP_ANONYMOUS
+#define MAP_ANONYMOUS MAP_ANON
+#endif
+
+
+/*
+ * Dispatch stubs are of fixed size and never freed. Thus, we do not need to
+ * overlay a heap, we just mmap a page and manage through an index.
+ */
+
+static int
+init_map(void)
+{
+#ifdef MESA_SELINUX
+   if (is_selinux_enabled()) {
+      if (!security_get_boolean_active("allow_execmem") ||
+	  !security_get_boolean_pending("allow_execmem"))
+         return 0;
+   }
+#endif
+
+   if (!exec_mem)
+      exec_mem = mmap(NULL, EXEC_MAP_SIZE, PROT_EXEC | PROT_READ | PROT_WRITE,
+		      MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+
+   return (exec_mem != MAP_FAILED);
+}
+
+
+#elif defined(_WIN32)
+
+#include <windows.h>
+
+
+/*
+ * Avoid Data Execution Prevention.
+ */
+
+static int
+init_map(void)
+{
+   exec_mem = VirtualAlloc(NULL, EXEC_MAP_SIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
+
+   return (exec_mem != NULL);
+}
+
+
+#else
+
+#include <stdlib.h>
+
+static int
+init_map(void)
+{
+   exec_mem = malloc(EXEC_MAP_SIZE);
+
+   return (exec_mem != NULL);
+}
+
+
+#endif
+
+void *
+u_execmem_alloc(unsigned int size)
+{
+   void *addr = NULL;
+
+   u_mutex_lock(exec_mutex);
+
+   if (!init_map())
+      goto bail;
+
+   /* free space check, assumes no integer overflow */
+   if (head + size > EXEC_MAP_SIZE)
+      goto bail;
+
+   /* allocation, assumes proper addr and size alignement */
+   addr = exec_mem + head;
+   head += size;
+
+bail:
+   u_mutex_unlock(exec_mutex);
+
+   return addr;
+}
+
+
diff --git a/mesalib/src/mapi/mapi/u_execmem.h b/mesalib/src/mapi/mapi/u_execmem.h
new file mode 100644
index 000000000..13fff8df2
--- /dev/null
+++ b/mesalib/src/mapi/mapi/u_execmem.h
@@ -0,0 +1,7 @@
+#ifndef _U_EXECMEM_H_
+#define _U_EXECMEM_H_
+
+void *
+u_execmem_alloc(unsigned int size);
+
+#endif /* _U_EXECMEM_H_ */
diff --git a/mesalib/src/mapi/mapi/u_macros.h b/mesalib/src/mapi/mapi/u_macros.h
new file mode 100644
index 000000000..72345b5f1
--- /dev/null
+++ b/mesalib/src/mapi/mapi/u_macros.h
@@ -0,0 +1,12 @@
+#ifndef _U_MACROS_
+#define _U_MACROS_
+
+#define _U_STRINGIFY(x) #x
+#define _U_CONCAT(x, y) x ## y
+#define _U_CONCAT_STR(x, y) #x#y
+
+#define U_STRINGIFY(x) _U_STRINGIFY(x)
+#define U_CONCAT(x, y) _U_CONCAT(x, y)
+#define U_CONCAT_STR(x, y) _U_CONCAT_STR(x, y)
+
+#endif /* _U_MACROS_ */
diff --git a/mesalib/src/mapi/mapi/u_thread.c b/mesalib/src/mapi/mapi/u_thread.c
new file mode 100644
index 000000000..e0fa64ae0
--- /dev/null
+++ b/mesalib/src/mapi/mapi/u_thread.c
@@ -0,0 +1,254 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  6.5.1
+ *
+ * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "u_compiler.h"
+#include "u_thread.h"
+
+
+/*
+ * This file should still compile even when THREADS is not defined.
+ * This is to make things easier to deal with on the makefile scene..
+ */
+#ifdef THREADS
+#include <errno.h>
+
+/*
+ * Error messages
+ */
+#define INIT_TSD_ERROR "_glthread_: failed to allocate key for thread specific data"
+#define GET_TSD_ERROR "_glthread_: failed to get thread specific data"
+#define SET_TSD_ERROR "_glthread_: thread failed to set thread specific data"
+
+
+/*
+ * Magic number to determine if a TSD object has been initialized.
+ * Kind of a hack but there doesn't appear to be a better cross-platform
+ * solution.
+ */
+#define INIT_MAGIC 0xff8adc98
+
+
+
+/*
+ * POSIX Threads -- The best way to go if your platform supports them.
+ *                  Solaris >= 2.5 have POSIX threads, IRIX >= 6.4 reportedly
+ *                  has them, and many of the free Unixes now have them.
+ *                  Be sure to use appropriate -mt or -D_REENTRANT type
+ *                  compile flags when building.
+ */
+#ifdef PTHREADS
+
+unsigned long
+u_thread_self(void)
+{
+   return (unsigned long) pthread_self();
+}
+
+
+void
+u_tsd_init(struct u_tsd *tsd)
+{
+   if (pthread_key_create(&tsd->key, NULL/*free*/) != 0) {
+      perror(INIT_TSD_ERROR);
+      exit(-1);
+   }
+   tsd->initMagic = INIT_MAGIC;
+}
+
+
+void *
+u_tsd_get(struct u_tsd *tsd)
+{
+   if (tsd->initMagic != (int) INIT_MAGIC) {
+      u_tsd_init(tsd);
+   }
+   return pthread_getspecific(tsd->key);
+}
+
+
+void
+u_tsd_set(struct u_tsd *tsd, void *ptr)
+{
+   if (tsd->initMagic != (int) INIT_MAGIC) {
+      u_tsd_init(tsd);
+   }
+   if (pthread_setspecific(tsd->key, ptr) != 0) {
+      perror(SET_TSD_ERROR);
+      exit(-1);
+   }
+}
+
+#endif /* PTHREADS */
+
+
+
+/*
+ * Win32 Threads.  The only available option for Windows 95/NT.
+ * Be sure that you compile using the Multithreaded runtime, otherwise
+ * bad things will happen.
+ */
+#ifdef WIN32_THREADS
+
+static void InsteadOf_exit(int nCode)
+{
+   DWORD dwErr = GetLastError();
+}
+
+unsigned long
+u_thread_self(void)
+{
+   return GetCurrentThreadId();
+}
+
+
+void
+u_tsd_init(struct u_tsd *tsd)
+{
+   tsd->key = TlsAlloc();
+   if (tsd->key == TLS_OUT_OF_INDEXES) {
+      perror(INIT_TSD_ERROR);
+      InsteadOf_exit(-1);
+   }
+   tsd->initMagic = INIT_MAGIC;
+}
+
+
+void
+u_tsd_destroy(struct u_tsd *tsd)
+{
+   if (tsd->initMagic != INIT_MAGIC) {
+      return;
+   }
+   TlsFree(tsd->key);
+   tsd->initMagic = 0x0;
+}
+
+
+void *
+u_tsd_get(struct u_tsd *tsd)
+{
+   if (tsd->initMagic != INIT_MAGIC) {
+      u_tsd_init(tsd);
+   }
+   return TlsGetValue(tsd->key);
+}
+
+
+void
+u_tsd_set(struct u_tsd *tsd, void *ptr)
+{
+   /* the following code assumes that the struct u_tsd has been initialized
+      to zero at creation */
+   if (tsd->initMagic != INIT_MAGIC) {
+      u_tsd_init(tsd);
+   }
+   if (TlsSetValue(tsd->key, ptr) == 0) {
+      perror(SET_TSD_ERROR);
+      InsteadOf_exit(-1);
+   }
+}
+
+#endif /* WIN32_THREADS */
+
+/*
+ * BeOS threads
+ */
+#ifdef BEOS_THREADS
+
+unsigned long
+u_thread_self(void)
+{
+   return (unsigned long) find_thread(NULL);
+}
+
+void
+u_tsd_init(struct u_tsd *tsd)
+{
+   tsd->key = tls_allocate();
+   tsd->initMagic = INIT_MAGIC;
+}
+
+void *
+u_tsd_get(struct u_tsd *tsd)
+{
+   if (tsd->initMagic != (int) INIT_MAGIC) {
+      u_tsd_init(tsd);
+   }
+   return tls_get(tsd->key);
+}
+
+void
+u_tsd_set(struct u_tsd *tsd, void *ptr)
+{
+   if (tsd->initMagic != (int) INIT_MAGIC) {
+      u_tsd_init(tsd);
+   }
+   tls_set(tsd->key, ptr);
+}
+
+#endif /* BEOS_THREADS */
+
+
+
+#else  /* THREADS */
+
+
+/*
+ * no-op functions
+ */
+
+unsigned long
+_glthread_GetID(void)
+{
+   return 0;
+}
+
+
+void
+u_tsd_init(struct u_tsd *tsd)
+{
+   (void) tsd;
+}
+
+
+void *
+u_tsd_get(struct u_tsd *tsd)
+{
+   (void) tsd;
+   return NULL;
+}
+
+
+void
+u_tsd_set(struct u_tsd *tsd, void *ptr)
+{
+   (void) tsd;
+   (void) ptr;
+}
+
+
+#endif /* THREADS */
diff --git a/mesalib/src/mapi/mapi/u_thread.h b/mesalib/src/mapi/mapi/u_thread.h
new file mode 100644
index 000000000..b4487a340
--- /dev/null
+++ b/mesalib/src/mapi/mapi/u_thread.h
@@ -0,0 +1,201 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  6.5.2
+ *
+ * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+/*
+ * Thread support for gl dispatch.
+ *
+ * Initial version by John Stone (j.stone@acm.org) (johns@cs.umr.edu)
+ *                and Christoph Poliwoda (poliwoda@volumegraphics.com)
+ * Revised by Keith Whitwell
+ * Adapted for new gl dispatcher by Brian Paul
+ * Modified for use in mapi by Chia-I Wu
+ */
+
+/*
+ * If this file is accidentally included by a non-threaded build,
+ * it should not cause the build to fail, or otherwise cause problems.
+ * In general, it should only be included when needed however.
+ */
+
+#ifndef _U_THREAD_H_
+#define _U_THREAD_H_
+
+#include "u_compiler.h"
+
+#if defined(PTHREADS) || defined(WIN32_THREADS) || defined(BEOS_THREADS)
+#ifndef THREADS
+#define THREADS
+#endif
+#endif
+
+/*
+ * POSIX threads. This should be your choice in the Unix world
+ * whenever possible.  When building with POSIX threads, be sure
+ * to enable any compiler flags which will cause the MT-safe
+ * libc (if one exists) to be used when linking, as well as any
+ * header macros for MT-safe errno, etc.  For Solaris, this is the -mt
+ * compiler flag.  On Solaris with gcc, use -D_REENTRANT to enable
+ * proper compiling for MT-safe libc etc.
+ */
+#if defined(PTHREADS)
+#include <pthread.h> /* POSIX threads headers */
+
+struct u_tsd {
+   pthread_key_t key;
+   int initMagic;
+};
+
+typedef pthread_mutex_t u_mutex;
+
+#define u_mutex_declare_static(name) \
+   static u_mutex name = PTHREAD_MUTEX_INITIALIZER
+
+#define u_mutex_init(name)    pthread_mutex_init(&(name), NULL)
+#define u_mutex_destroy(name) pthread_mutex_destroy(&(name))
+#define u_mutex_lock(name)    (void) pthread_mutex_lock(&(name))
+#define u_mutex_unlock(name)  (void) pthread_mutex_unlock(&(name))
+
+#endif /* PTHREADS */
+
+
+/*
+ * Windows threads. Should work with Windows NT and 95.
+ * IMPORTANT: Link with multithreaded runtime library when THREADS are
+ * used!
+ */
+#ifdef WIN32_THREADS
+#include <windows.h>
+
+struct u_tsd {
+   DWORD key;
+   int   initMagic;
+};
+
+typedef CRITICAL_SECTION u_mutex;
+
+/* http://locklessinc.com/articles/pthreads_on_windows/ */
+#define u_mutex_declare_static(name) \
+   /* static */ u_mutex name = {(void*)-1, -1, 0, 0, 0, 0}
+
+#define u_mutex_init(name)    InitializeCriticalSection(&name)
+#define u_mutex_destroy(name) DeleteCriticalSection(&name)
+#define u_mutex_lock(name)    EnterCriticalSection(&name)
+#define u_mutex_unlock(name)  LeaveCriticalSection(&name)
+
+#endif /* WIN32_THREADS */
+
+
+/*
+ * BeOS threads. R5.x required.
+ */
+#ifdef BEOS_THREADS
+
+/* Problem with OS.h and this file on haiku */
+#ifndef __HAIKU__
+#include <kernel/OS.h>
+#endif
+
+#include <support/TLS.h>
+
+/* The only two typedefs required here
+ * this is cause of the OS.h problem
+ */
+#ifdef __HAIKU__
+typedef int32 thread_id;
+typedef int32 sem_id;
+#endif
+
+struct u_tsd {
+   int32        key;
+   int          initMagic;
+};
+
+/* Use Benaphore, aka speeder semaphore */
+typedef struct {
+    int32   lock;
+    sem_id  sem;
+} benaphore;
+typedef benaphore u_mutex;
+
+#define u_mutex_declare_static(name) \
+   static u_mutex name = { 0, 0 }
+
+#define u_mutex_init(name) \
+   name.sem = create_sem(0, #name"_benaphore"), \
+   name.lock = 0
+
+#define u_mutex_destroy(name) \
+   delete_sem(name.sem), \
+   name.lock = 0
+
+#define u_mutex_lock(name) \
+   if (name.sem == 0) \
+      u_mutex_init(name); \
+   if (atomic_add(&(name.lock), 1) >= 1) \
+      acquire_sem(name.sem)
+
+#define u_mutex_unlock(name) \
+   if (atomic_add(&(name.lock), -1) > 1) \
+      release_sem(name.sem)
+
+#endif /* BEOS_THREADS */
+
+
+/*
+ * THREADS not defined
+ */
+#ifndef THREADS
+
+struct u_tsd {
+   int initMagic; 
+};
+
+typedef unsigned u_mutex;
+
+#define u_mutex_declare_static(name)   static u_mutex name = 0
+#define u_mutex_init(name)             (void) name
+#define u_mutex_destroy(name)          (void) name
+#define u_mutex_lock(name)             (void) name
+#define u_mutex_unlock(name)           (void) name
+
+#endif /* THREADS */
+
+
+unsigned long
+u_thread_self(void);
+
+void
+u_tsd_init(struct u_tsd *tsd);
+
+void
+u_tsd_destroy(struct u_tsd *tsd); /* WIN32 only */
+
+void *
+u_tsd_get(struct u_tsd *tsd);
+
+void
+u_tsd_set(struct u_tsd *tsd, void *ptr);
+
+#endif /* _U_THREAD_H_ */
-- 
cgit v1.2.3