glapi: Move to src/mapi/.
[mesa.git] / src / mapi / glapi / glapi_execmem.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 6.5
4 *
5 * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25
26 /**
27 * \file glapi_execmem.c
28 *
29 * Function for allocating executable memory for dispatch stubs.
30 *
31 * Copied from main/execmem.c and simplified for dispatch stubs.
32 */
33
34
35 #ifdef HAVE_DIX_CONFIG_H
36 #include <dix-config.h>
37 #include "glapi/mesa.h"
38 #else
39 #include "main/compiler.h"
40 #endif
41
42 #include "glapi/glthread.h"
43 #include "glapi/glapi_priv.h"
44
45
46 #if defined(__linux__) || defined(__OpenBSD__) || defined(_NetBSD__) || defined(__sun)
47
48 #include <unistd.h>
49 #include <sys/mman.h>
50
51 #ifdef MESA_SELINUX
52 #include <selinux/selinux.h>
53 #endif
54
55
56 #ifndef MAP_ANONYMOUS
57 #define MAP_ANONYMOUS MAP_ANON
58 #endif
59
60
61 #define EXEC_MAP_SIZE (4*1024)
62
63 _glthread_DECLARE_STATIC_MUTEX(exec_mutex);
64
65 static unsigned int head = 0;
66
67 static unsigned char *exec_mem = NULL;
68
69
70 /*
71 * Dispatch stubs are of fixed size and never freed. Thus, we do not need to
72 * overlay a heap, we just mmap a page and manage through an index.
73 */
74
75 static int
76 init_map(void)
77 {
78 #ifdef MESA_SELINUX
79 if (is_selinux_enabled()) {
80 if (!security_get_boolean_active("allow_execmem") ||
81 !security_get_boolean_pending("allow_execmem"))
82 return 0;
83 }
84 #endif
85
86 if (!exec_mem)
87 exec_mem = mmap(NULL, EXEC_MAP_SIZE, PROT_EXEC | PROT_READ | PROT_WRITE,
88 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
89
90 return (exec_mem != MAP_FAILED);
91 }
92
93
94 void *
95 _glapi_exec_malloc(unsigned int size)
96 {
97 void *addr = NULL;
98
99 _glthread_LOCK_MUTEX(exec_mutex);
100
101 if (!init_map())
102 goto bail;
103
104 /* free space check, assumes no integer overflow */
105 if (head + size > EXEC_MAP_SIZE)
106 goto bail;
107
108 /* allocation, assumes proper addr and size alignement */
109 addr = exec_mem + head;
110 head += size;
111
112 bail:
113 _glthread_UNLOCK_MUTEX(exec_mutex);
114
115 return addr;
116 }
117
118
119 #else
120
121 void *
122 _glapi_exec_malloc(unsigned int size)
123 {
124 return malloc(size);
125 }
126
127
128 #endif