YAP 7.1.0
or.memory.c
1/************************************************************************
2** **
3** The YapTab/YapOr/OPTYap systems **
4** **
5** YapTab extends the Yap Prolog engine to support sequential tabling **
6** YapOr extends the Yap Prolog engine to support or-parallelism **
7** OPTYap extends the Yap Prolog engine to support or-parallel tabling **
8** **
9** **
10** Yap Prolog was developed at University of Porto, Portugal **
11** **
12************************************************************************/
13
14/**************************************
15** Includes & Declarations **
16**************************************/
17
18#include "Yap.h"
19#if defined(YAPOR_COPY) || defined(YAPOR_COW) || defined(YAPOR_SBA)
20#include <signal.h>
21#if HAVE_UNISTD_H
22#include <unistd.h>
23#endif
24#include <fcntl.h>
25#include <string.h>
26#include <sys/shm.h>
27#include <sys/mman.h>
28#include "Yatom.h"
29#include "alloc.h"
30#include "or.macros.h"
31#include "amiops.h"
32
33
34
35/************************************
36** Macros & Declarations **
37************************************/
38
39#define GLOBAL_LOCAL_STRUCTS_AREA ADJUST_SIZE_TO_PAGE(sizeof(struct global_data) + MAX_WORKERS * sizeof(struct worker_local))
40
41#ifdef MMAP_MEMORY_MAPPING_SCHEME
42#define PATH_MAX 1000
43char mapfile_path[PATH_MAX];
44#elif defined(SHM_MEMORY_MAPPING_SCHEME)
45int shm_mapid[MAX_WORKERS + 2];
46#endif /* MEMORY_MAPPING_SCHEME */
47
48
49
50/******************************************
51** Local functions declaration **
52******************************************/
53
54#ifdef SHM_MEMORY_MAPPING_SCHEME
55void shm_map_memory(int id, int size, void *shmaddr);
56void shm_unmap_memory(int id);
57#endif /* SHM_MEMORY_MAPPING_SCHEME */
58
59
60
61/********************************
62** Global functions **
63********************************/
64
65void Yap_init_yapor_global_local_memory(void) {
66 Yap_local = (struct worker_local *)(MMAP_ADDR - GLOBAL_LOCAL_STRUCTS_AREA);
67 Yap_global = (struct global_data *)(MMAP_ADDR - sizeof(struct global_data));
68
69#ifdef MMAP_MEMORY_MAPPING_SCHEME
70 { int fd_mapfile;
71 if (getcwd(mapfile_path,PATH_MAX) == NULL)
72 Yap_Error(SYSTEM_ERROR_FATAL, TermNil, "getcwd error (Yap_init_yapor_global_local_memory)");
73 strcat(mapfile_path,"/mapfile");
74 itos(getpid(), &mapfile_path[strlen(mapfile_path)]);
75 if (strlen(mapfile_path) >= PATH_MAX)
76 Yap_Error(SYSTEM_ERROR_FATAL, TermNil, "PATH_MAX error (Yap_init_yapor_global_local_memory)");
77 if ((fd_mapfile = open(mapfile_path, O_RDWR|O_CREAT|O_TRUNC, 0666)) < 0)
78 Yap_Error(SYSTEM_ERROR_FATAL, TermNil, "open error (Yap_init_yapor_global_local_memory)");
79 if (lseek(fd_mapfile, GLOBAL_LOCAL_STRUCTS_AREA, SEEK_SET) < 0)
80 Yap_Error(SYSTEM_ERROR_FATAL, TermNil, "lseek error (Yap_init_yapor_global_local_memory)");
81 if (write(fd_mapfile, "", 1) < 0)
82 Yap_Error(SYSTEM_ERROR_FATAL, TermNil, "write error (Yap_init_yapor_global_local_memory)");
83 if (mmap((void *) Yap_local, (size_t) GLOBAL_LOCAL_STRUCTS_AREA, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd_mapfile, 0) == (void *) -1)
84 Yap_Error(SYSTEM_ERROR_FATAL, TermNil, "mmap error (Yap_init_global_local_memory)");
85 if (close(fd_mapfile) == -1)
86 Yap_Error(SYSTEM_ERROR_FATAL, TermNil, "close error (Yap_init_yapor_global_local_memory)");
87 }
88#elif defined(SHM_MEMORY_MAPPING_SCHEME)
89 /* place as segment MAX_WORKERS (0..MAX_WORKERS-1 reserved for worker areas) */
90 shm_map_memory(MAX_WORKERS, GLOBAL_LOCAL_STRUCTS_AREA, (void *) Yap_local);
91#endif /* MEMORY_MAPPING_SCHEME */
92
93 return;
94}
95
96
97void Yap_init_yapor_stacks_memory(UInt TrailStackArea, UInt HeapStackArea, UInt GlobalLocalStackArea, int n_workers) {
98 long StacksArea;
99
100 HeapStackArea *= (K);
101 GlobalLocalStackArea *= (K);
102 TrailStackArea *= (K);
103 TrailStackArea = ADJUST_SIZE_TO_PAGE(TrailStackArea);
104 HeapStackArea = ADJUST_SIZE_TO_PAGE(HeapStackArea);
105 GlobalLocalStackArea = ADJUST_SIZE_TO_PAGE(GlobalLocalStackArea);
106 Yap_worker_area_size = GlobalLocalStackArea + TrailStackArea;
107#if defined(YAPOR_COPY) || defined(YAPOR_SBA)
108 StacksArea = HeapStackArea + Yap_worker_area_size * n_workers;
109#elif defined(YAPOR_COW)
110 StacksArea = HeapStackArea;
111#endif /* YAPOR_COPY || YAPOR_SBA || YAPOR_COW */
112
113 Yap_HeapBase = (ADDR) MMAP_ADDR;
114 LOCAL_GlobalBase = (ADDR) (MMAP_ADDR + HeapStackArea);
115
116#ifdef MMAP_MEMORY_MAPPING_SCHEME
117 /* map stacks in a single go */
118 { int fd_mapfile;
119 if ((fd_mapfile = open(mapfile_path, O_RDWR)) < 0)
120 Yap_Error(SYSTEM_ERROR_FATAL, TermNil, "open error ( Yap_init_yapor_stacks_memory)");
121 if (lseek(fd_mapfile, GLOBAL_LOCAL_STRUCTS_AREA + StacksArea, SEEK_SET) < 0)
122 Yap_Error(SYSTEM_ERROR_FATAL, TermNil, "lseek error (Yap_init_yapor_stacks_memory)");
123 if (write(fd_mapfile, "", 1) < 0)
124 Yap_Error(SYSTEM_ERROR_FATAL, TermNil, "write error (Yap_init_yapor_stacks_memory)");
125 if (mmap((void *) Yap_HeapBase, (size_t) StacksArea, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd_mapfile, GLOBAL_LOCAL_STRUCTS_AREA) == (void *) -1)
126 Yap_Error(SYSTEM_ERROR_FATAL, TermNil, "mmap error (Yap_init_yapor_stacks_memory)");
127 if (close(fd_mapfile) == -1)
128 Yap_Error(SYSTEM_ERROR_FATAL, TermNil, "close error (Yap_init_yapor_stacks_memory)");
129 }
130#elif defined(SHM_MEMORY_MAPPING_SCHEME)
131 /* place heap stack segment as MAX_WORKERS+1 */
132 shm_map_memory(MAX_WORKERS + 1, HeapStackArea, (void *) Yap_HeapBase);
133#if defined(YAPOR_COPY) || defined(YAPOR_SBA)
134 /* map segments for worker areas as 0..MAX_WORKERS-1 */
135 { int i;
136 for (i = 0; i < n_workers; i++)
137 shm_map_memory(i, Yap_worker_area_size, LOCAL_GlobalBase + Yap_worker_area_size * i);
138 }
139#endif /* YAPOR_COPY || YAPOR_SBA */
140#endif /* MEMORY_MAPPING_SCHEME */
141
142#ifdef YAPOR_COW
143 /* just allocate local space for stacks */
144 { int private_fd_mapfile;
145 if ((private_fd_mapfile = open("/dev/zero", O_RDWR)) < 0)
146 Yap_Error(SYSTEM_ERROR_FATAL, TermNil, "open error (Yap_init_yapor_stacks_memory)");
147 if (mmap(LOCAL_GlobalBase, Yap_worker_area_size, PROT_READ|PROT_WRITE,
148 MAP_PRIVATE|MAP_FIXED, private_fd_mapfile, 0) == (void *) -1)
149 Yap_Error(SYSTEM_ERROR_FATAL, TermNil, "mmap error (Yap_init_yapor_stacks_memory)");
150 close(private_fd_mapfile);
151 }
152#endif /* YAPOR_COW */
153
154#ifdef YAPOR_SBA
155 /* alloc space for the sparse binding array */
156 sba_size = Yap_worker_area_size * n_workers;
157 if ((binding_array = (char *)malloc(sba_size)) == NULL)
158 Yap_Error(SYSTEM_ERROR_FATAL, TermNil, "malloc error (Yap_init_yapor_stacks_memory)");
159 if ((CELL)binding_array & MBIT)
160 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil, "binding_array start address conflicts with tag used in IDB (Yap_init_yapor_stacks_memory)");
161 sba_offset = binding_array - LOCAL_GlobalBase;
162 sba_end = (int)binding_array + sba_size;
163#endif /* YAPOR_SBA */
164
165 LOCAL_TrailBase = LOCAL_GlobalBase + GlobalLocalStackArea;
166 LOCAL_LocalBase = LOCAL_TrailBase - CellSize;
167 LOCAL_TrailTop = LOCAL_TrailBase + TrailStackArea;
168 Yap_InitHeap(Yap_HeapBase);
169 HeapLim = LOCAL_GlobalBase;
170 return;
171}
172
173
174void Yap_remap_yapor_memory(void) {
175#if defined(YAPOR_COPY)
176 int i;
177 void *remap_addr = LOCAL_GlobalBase;
178#ifdef MMAP_MEMORY_MAPPING_SCHEME
179 int fd_mapfile;
180 long remap_offset = (ADDR) remap_addr - (ADDR) Yap_local;
181 if ((fd_mapfile = open(mapfile_path, O_RDWR)) < 0)
182 Yap_Error(SYSTEM_ERROR_FATAL, TermNil, "open error (Yap_remap_yapor_memory)");
183 if (munmap(remap_addr, (size_t)(Yap_worker_area_size * GLOBAL_number_workers)) == -1)
184 Yap_Error(SYSTEM_ERROR_FATAL, TermNil, "munmap error (Yap_remap_yapor_memory)");
185 for (i = 0; i < GLOBAL_number_workers; i++)
186 if (mmap(remap_addr + worker_offset(i), (size_t)Yap_worker_area_size, PROT_READ|PROT_WRITE,
187 MAP_SHARED|MAP_FIXED, fd_mapfile, remap_offset + i * Yap_worker_area_size) == (void *) -1)
188 Yap_Error(SYSTEM_ERROR_FATAL, TermNil, "mmap error (Yap_remap_yapor_memory)");
189 if (close(fd_mapfile) == -1)
190 Yap_Error(SYSTEM_ERROR_FATAL, TermNil, "close error (Yap_remap_yapor_memory)");
191#else /* SHM_MEMORY_MAPPING_SCHEME */
192 for (i = 0; i < GLOBAL_number_workers; i++)
193 if (shmdt(remap_addr + Yap_worker_area_size * i) == -1)
194 Yap_Error(SYSTEM_ERROR_FATAL, TermNil, "shmdt error (Yap_remap_yapor_memory)");
195 for (i = 0; i < GLOBAL_number_workers; i++)
196 if(shmat(shm_mapid[i], remap_addr + worker_offset(i), 0) == (void *) -1)
197 Yap_Error(SYSTEM_ERROR_FATAL, TermNil, "shmat error (Yap_remap_yapor_memory)");
198#endif /* MEMORY_MAPPING_SCHEME */
199#elif defined(YAPOR_SBA)
200 /* setup workers so that they have different areas */
201 LOCAL_GlobalBase += worker_id * Yap_worker_area_size;
202 LOCAL_TrailBase += worker_id * Yap_worker_area_size;
203 LOCAL_LocalBase += worker_id * Yap_worker_area_size;
204 LOCAL_TrailTop += worker_id * Yap_worker_area_size;
205#endif /* YAPOR_COPY || YAPOR_SBA */
206}
207
208
209void Yap_unmap_yapor_memory (void) {
210 int i;
211
212 INFORMATION_MESSAGE("Worker %d exiting...", worker_id);
213 for (i = 0; i < GLOBAL_number_workers; i++)
214 if (i != worker_id && GLOBAL_worker_pid(i) != 0) {
215 if (kill(GLOBAL_worker_pid(i), SIGKILL) != 0)
216 INFORMATION_MESSAGE("Can't kill process %d", GLOBAL_worker_pid(i));
217 else
218 INFORMATION_MESSAGE("Killing process %d", GLOBAL_worker_pid(i));
219 }
220#ifdef YAPOR_COW
221 if (GLOBAL_number_workers > 1) {
222 if (kill(GLOBAL_master_worker, SIGINT) != 0)
223 INFORMATION_MESSAGE("Can't kill process %d", GLOBAL_master_worker);
224 else
225 INFORMATION_MESSAGE("Killing process %d", GLOBAL_master_worker);
226 }
227#endif /* YAPOR_COW */
228
229#ifdef MMAP_MEMORY_MAPPING_SCHEME
230 if (remove(mapfile_path) == 0)
231 INFORMATION_MESSAGE("Removing mapfile \"%s\"", mapfile_path);
232 else
233 INFORMATION_MESSAGE("Can't remove mapfile \"%s\"", mapfile_path);
234#elif defined(SHM_MEMORY_MAPPING_SCHEME)
235#if defined(YAPOR_COPY) || defined(YAPOR_SBA)
236 shm_unmap_memory(MAX_WORKERS);
237 shm_unmap_memory(MAX_WORKERS + 1);
238 for (i = 0; i < GLOBAL_number_workers; i++)
239 shm_unmap_memory(i);
240#elif defined(YAPOR_COW)
241 shm_unmap_memory(0);
242#endif /* YAPOR_COPY || YAPOR_SBA || YAPOR_COW */
243#endif /* MEMORY_MAPPING_SCHEME */
244 return;
245}
246
247
248
249/* ------------------------- **
250** Local functions **
251** ------------------------- */
252
253#ifdef SHM_MEMORY_MAPPING_SCHEME
254void shm_map_memory(int id, int size, void *shmaddr) {
255 if ((shm_mapid[id] = shmget(IPC_PRIVATE, size, SHM_R|SHM_W)) == -1)
256 Yap_Error(SYSTEM_ERROR_FATAL, TermNil, "shmget error (shm_map_memory)");
257 if (shmat(shm_mapid[id], shmaddr, 0) == (void *) -1)
258 Yap_Error(SYSTEM_ERROR_FATAL, TermNil, "shmat error (shm_map_memory)");
259 return;
260}
261
262
263void shm_unmap_memory(int id) {
264 if (shmctl(shm_mapid[id], IPC_RMID, 0) == 0)
265 INFORMATION_MESSAGE("Removing shared memory segment %d", shm_mapid[id]);
266 else
267 INFORMATION_MESSAGE("Can't remove shared memory segment %d", shm_mapid[id]);
268 return;
269}
270#endif /* SHM_MEMORY_MAPPING_SCHEME */
271#endif /* YAPOR_COPY || YAPOR_COW || YAPOR_SBA */
Main definitions.