Update of /cvsroot/sbcl/sbcl/src/runtime
In directory sc8-pr-cvs1:/tmp/cvs-serv4177/src/runtime
Modified Files:
Tag: dan_native_threads_2_branch
gencgc.c gencgc.h runtime.c thread.c
Log Message:
0.7.11.10.thread.15
Accidentally reindented gencgc.c
free_pages_lock is a spinlock controlling access to
page table for gc_alloc_large and gc_alloc_new_region
Some messing around with header files to cut down on the
number of gcc warnings
all_threads_lock is a spinlock controlling access to
all_threads for operations that wish to add/remove
threads from the list
Index: gencgc.c
===================================================================
RCS file: /cvsroot/sbcl/sbcl/src/runtime/gencgc.c,v
retrieving revision 1.24.8.3
retrieving revision 1.24.8.4
diff -u -d -r1.24.8.3 -r1.24.8.4
--- gencgc.c 25 Feb 2003 21:27:46 -0000 1.24.8.3
+++ gencgc.c 25 Feb 2003 22:28:00 -0000 1.24.8.4
@@ -247,6 +247,13 @@
* search of the heap. XX Gencgc obviously needs to be better
* integrated with the Lisp code. */
static int last_free_page;
+
+/* This lock is to prevent multiple threads from simultaneously
+ * allocating new regions which overlap each other. Note that the
+ * majority of GC is single-threaded, but alloc() may be called
+ * from >1 thread at a time and must be thread-safe */
+static lispobj free_pages_lock=0;
+
/*
* miscellaneous heap functions
@@ -482,16 +489,16 @@
int i;
/*
- FSHOW((stderr,
- "/alloc_new_region for %d bytes from gen %d\n",
- nbytes, gc_alloc_generation));
+ FSHOW((stderr,
+ "/alloc_new_region for %d bytes from gen %d\n",
+ nbytes, gc_alloc_generation));
*/
/* Check that the region is in a reset state. */
gc_assert((alloc_region->first_page == 0)
&& (alloc_region->last_page == -1)
&& (alloc_region->free_pointer == alloc_region->end_addr));
-
+ get_spinlock(&free_pages_lock,alloc_region);
if (unboxed) {
first_page =
generations[gc_alloc_generation].alloc_unboxed_start_page;
@@ -501,7 +508,7 @@
}
last_page=gc_find_freeish_pages(&first_page,nbytes,unboxed,alloc_region);
bytes_found=(4096 - page_table[first_page].bytes_used)
- + 4096*(last_page-first_page);
+ + 4096*(last_page-first_page);
/* Set up the alloc_region. */
alloc_region->first_page = first_page;
@@ -511,20 +518,6 @@
alloc_region->free_pointer = alloc_region->start_addr;
alloc_region->end_addr = alloc_region->start_addr + bytes_found;
- if (gencgc_zero_check) {
- int *p;
- for (p = (int *)alloc_region->start_addr;
- p < (int *)alloc_region->end_addr; p++) {
- if (*p != 0) {
- /* KLUDGE: It would be nice to use %lx and explicit casts
- * (long) in code like this, so that it is less likely to
- * break randomly when running on a machine with different
- * word sizes. -- WHN 19991129 */
- lose("The new region at %x is not zero.", p);
- }
- }
- }
-
/* Set up the pages. */
/* The first page may have already been in use. */
@@ -560,7 +553,6 @@
alloc_region->start_addr - page_address(i);
page_table[i].allocated |= OPEN_REGION_PAGE ;
}
-
/* Bump up last_free_page. */
if (last_page+1 > last_free_page) {
last_free_page = last_page+1;
@@ -568,6 +560,23 @@
(lispobj)(((char *)heap_base) + last_free_page*4096),
0);
}
+ free_pages_lock=0;
+
+ /* we can do this after releasing free_pages_lock */
+ if (gencgc_zero_check) {
+ int *p;
+ for (p = (int *)alloc_region->start_addr;
+ p < (int *)alloc_region->end_addr; p++) {
+ if (*p != 0) {
+ /* KLUDGE: It would be nice to use %lx and explicit casts
+ * (long) in code like this, so that it is less likely to
+ * break randomly when running on a machine with different
+ * word sizes. -- WHN 19991129 */
+ lose("The new region at %x is not zero.", p);
+ }
+ }
+ }
+
}
/* If the record_new_objects flag is 2 then all new regions created
@@ -631,18 +640,18 @@
+ (*new_areas)[i].offset
+ (*new_areas)[i].size;
/*FSHOW((stderr,
- "/add_new_area S1 %d %d %d %d\n",
- i, c, new_area_start, area_end));*/
+ "/add_new_area S1 %d %d %d %d\n",
+ i, c, new_area_start, area_end));*/
if (new_area_start == area_end) {
/*FSHOW((stderr,
- "/adding to [%d] %d %d %d with %d %d %d:\n",
- i,
- (*new_areas)[i].page,
- (*new_areas)[i].offset,
- (*new_areas)[i].size,
- first_page,
- offset,
- size);*/
+ "/adding to [%d] %d %d %d with %d %d %d:\n",
+ i,
+ (*new_areas)[i].page,
+ (*new_areas)[i].offset,
+ (*new_areas)[i].size,
+ first_page,
+ offset,
+ size);*/
(*new_areas)[i].size += size;
return;
}
@@ -652,8 +661,8 @@
(*new_areas)[new_areas_index].offset = offset;
(*new_areas)[new_areas_index].size = size;
/*FSHOW((stderr,
- "/new_area %d page %d offset %d size %d\n",
- new_areas_index, first_page, offset, size));*/
+ "/new_area %d page %d offset %d size %d\n",
+ new_areas_index, first_page, offset, size));*/
new_areas_index++;
/* Note the max new_areas used. */
@@ -680,9 +689,9 @@
int byte_cnt;
/*
- FSHOW((stderr,
- "/gc_alloc_update_page_tables() to gen %d:\n",
- gc_alloc_generation));
+ FSHOW((stderr,
+ "/gc_alloc_update_page_tables() to gen %d:\n",
+ gc_alloc_generation));
*/
first_page = alloc_region->first_page;
@@ -777,10 +786,10 @@
add_new_area(first_page,orig_first_page_bytes_used, region_size);
/*
- FSHOW((stderr,
- "/gc_alloc_update_page_tables update %d bytes to gen %d\n",
- region_size,
- gc_alloc_generation));
+ FSHOW((stderr,
+ "/gc_alloc_update_page_tables update %d bytes to gen %d\n",
+ region_size,
+ gc_alloc_generation));
*/
} else {
/* There are no bytes allocated. Unallocate the first_page if
@@ -816,14 +825,14 @@
int large = (nbytes >= large_object_size);
/*
- if (nbytes > 200000)
- FSHOW((stderr, "/alloc_large %d\n", nbytes));
+ if (nbytes > 200000)
+ FSHOW((stderr, "/alloc_large %d\n", nbytes));
*/
/*
- FSHOW((stderr,
- "/gc_alloc_large() for %d bytes from gen %d\n",
- nbytes, gc_alloc_generation));
+ FSHOW((stderr,
+ "/gc_alloc_large() for %d bytes from gen %d\n",
+ nbytes, gc_alloc_generation));
*/
/* If the object is small, and there is room in the current region
@@ -838,6 +847,8 @@
index ahead of the current region and bumped up here to save a
lot of re-scanning. */
+ get_spinlock(&free_pages_lock,alloc_region);
+
if (unboxed) {
first_page =
generations[gc_alloc_generation].alloc_large_unboxed_start_page;
@@ -936,6 +947,7 @@
SetSymbolValue(ALLOCATION_POINTER,
(lispobj)(((char *)heap_base) + last_free_page*4096),0);
}
+ free_pages_lock=0;
return((void *)(page_address(first_page)+orig_first_page_bytes_used));
}
@@ -966,7 +978,7 @@
do {
first_page = restart_page;
/* FIXME we really ought to be able to use part-filled pages. This
- * was disabled while finding strange corruption bugs */
+ * was disabled while finding strange corruption bugs */
if (1 || large)
while ((first_page < NUM_PAGES)
&& (page_table[first_page].allocated != FREE_PAGE))
@@ -1107,7 +1119,7 @@
gc_general_alloc(int nbytes,int unboxed_p,int quick_p)
{
struct alloc_region *my_region =
- unboxed_p ? &unboxed_region : &boxed_region;
+ unboxed_p ? &unboxed_region : &boxed_region;
return gc_alloc_with_region(nbytes,unboxed_p, my_region,quick_p);
}
@@ -1484,8 +1496,8 @@
* code and code-related objects
*/
/*
-static lispobj trans_fun_header(lispobj object);
-static lispobj trans_boxed(lispobj object);
+ static lispobj trans_fun_header(lispobj object);
+ static lispobj trans_boxed(lispobj object);
*/
/* Scan a x86 compiled code object, looking for possible fixups that
@@ -1681,19 +1693,19 @@
nheader_words = HeaderValue(*(lispobj *)new_code);
nwords = ncode_words + nheader_words;
/* FSHOW((stderr,
- "/compiled code object at %x: header words = %d, code words =
%d\n",
- new_code, nheader_words, ncode_words)); */
+ "/compiled code object at %x: header words = %d, code words = %d\n",
+ new_code, nheader_words, ncode_words)); */
constants_start_addr = (void *)new_code + 5*4;
constants_end_addr = (void *)new_code + nheader_words*4;
code_start_addr = (void *)new_code + nheader_words*4;
code_end_addr = (void *)new_code + nwords*4;
/*
- FSHOW((stderr,
- "/const start = %x, end = %x\n",
- constants_start_addr,constants_end_addr));
- FSHOW((stderr,
- "/code start = %x; end = %x\n",
- code_start_addr,code_end_addr));
+ FSHOW((stderr,
+ "/const start = %x, end = %x\n",
+ constants_start_addr,constants_end_addr));
+ FSHOW((stderr,
+ "/code start = %x; end = %x\n",
+ code_start_addr,code_end_addr));
*/
/* The first constant should be a pointer to the fixups for this
@@ -1876,129 +1888,129 @@
weak_p_obj = hash_table[10];
/* index vector */
- {
- lispobj index_vector_obj = hash_table[13];
+ {
+ lispobj index_vector_obj = hash_table[13];
- if (is_lisp_pointer(index_vector_obj) &&
- (widetag_of(*(lispobj *)native_pointer(index_vector_obj)) ==
- SIMPLE_ARRAY_UNSIGNED_BYTE_32_WIDETAG)) {
- index_vector = ((unsigned int *)native_pointer(index_vector_obj)) +
2;
- /*FSHOW((stderr, "/index_vector = %x\n",index_vector));*/
- length = fixnum_value(((unsigned int
*)native_pointer(index_vector_obj))[1]);
- /*FSHOW((stderr, "/length = %d\n", length));*/
- } else {
- lose("invalid index_vector %x", index_vector_obj);
- }
- }
+ if (is_lisp_pointer(index_vector_obj) &&
+ (widetag_of(*(lispobj *)native_pointer(index_vector_obj)) ==
+ SIMPLE_ARRAY_UNSIGNED_BYTE_32_WIDETAG)) {
+ index_vector = ((unsigned int *)native_pointer(index_vector_obj)) + 2;
+ /*FSHOW((stderr, "/index_vector = %x\n",index_vector));*/
+ length = fixnum_value(((unsigned int
*)native_pointer(index_vector_obj))[1]);
+ /*FSHOW((stderr, "/length = %d\n", length));*/
+ } else {
+ lose("invalid index_vector %x", index_vector_obj);
+ }
+ }
- /* next vector */
- {
- lispobj next_vector_obj = hash_table[14];
+ /* next vector */
+ {
+ lispobj next_vector_obj = hash_table[14];
- if (is_lisp_pointer(next_vector_obj) &&
- (widetag_of(*(lispobj *)native_pointer(next_vector_obj)) ==
- SIMPLE_ARRAY_UNSIGNED_BYTE_32_WIDETAG)) {
- next_vector = ((unsigned int *)native_pointer(next_vector_obj)) + 2;
- /*FSHOW((stderr, "/next_vector = %x\n", next_vector));*/
- next_vector_length = fixnum_value(((unsigned int
*)native_pointer(next_vector_obj))[1]);
- /*FSHOW((stderr, "/next_vector_length = %d\n",
next_vector_length));*/
- } else {
- lose("invalid next_vector %x", next_vector_obj);
- }
- }
+ if (is_lisp_pointer(next_vector_obj) &&
+ (widetag_of(*(lispobj *)native_pointer(next_vector_obj)) ==
+ SIMPLE_ARRAY_UNSIGNED_BYTE_32_WIDETAG)) {
+ next_vector = ((unsigned int *)native_pointer(next_vector_obj)) + 2;
+ /*FSHOW((stderr, "/next_vector = %x\n", next_vector));*/
+ next_vector_length = fixnum_value(((unsigned int
*)native_pointer(next_vector_obj))[1]);
+ /*FSHOW((stderr, "/next_vector_length = %d\n", next_vector_length));*/
+ } else {
+ lose("invalid next_vector %x", next_vector_obj);
+ }
+ }
- /* maybe hash vector */
- {
- /* FIXME: This bare "15" offset should become a symbolic
- * expression of some sort. And all the other bare offsets
- * too. And the bare "16" in scavenge(hash_table, 16). And
- * probably other stuff too. Ugh.. */
- lispobj hash_vector_obj = hash_table[15];
+ /* maybe hash vector */
+ {
+ /* FIXME: This bare "15" offset should become a symbolic
+ * expression of some sort. And all the other bare offsets
+ * too. And the bare "16" in scavenge(hash_table, 16). And
+ * probably other stuff too. Ugh.. */
+ lispobj hash_vector_obj = hash_table[15];
- if (is_lisp_pointer(hash_vector_obj) &&
- (widetag_of(*(lispobj *)native_pointer(hash_vector_obj))
- == SIMPLE_ARRAY_UNSIGNED_BYTE_32_WIDETAG)) {
- hash_vector = ((unsigned int *)native_pointer(hash_vector_obj)) + 2;
- /*FSHOW((stderr, "/hash_vector = %x\n", hash_vector));*/
- gc_assert(fixnum_value(((unsigned int
*)native_pointer(hash_vector_obj))[1])
- == next_vector_length);
- } else {
- hash_vector = NULL;
- /*FSHOW((stderr, "/no hash_vector: %x\n", hash_vector_obj));*/
- }
- }
+ if (is_lisp_pointer(hash_vector_obj) &&
+ (widetag_of(*(lispobj *)native_pointer(hash_vector_obj))
+ == SIMPLE_ARRAY_UNSIGNED_BYTE_32_WIDETAG)) {
+ hash_vector = ((unsigned int *)native_pointer(hash_vector_obj)) + 2;
+ /*FSHOW((stderr, "/hash_vector = %x\n", hash_vector));*/
+ gc_assert(fixnum_value(((unsigned int
*)native_pointer(hash_vector_obj))[1])
+ == next_vector_length);
+ } else {
+ hash_vector = NULL;
+ /*FSHOW((stderr, "/no hash_vector: %x\n", hash_vector_obj));*/
+ }
+ }
- /* These lengths could be different as the index_vector can be a
- * different length from the others, a larger index_vector could help
- * reduce collisions. */
- gc_assert(next_vector_length*2 == kv_length);
+ /* These lengths could be different as the index_vector can be a
+ * different length from the others, a larger index_vector could help
+ * reduce collisions. */
+ gc_assert(next_vector_length*2 == kv_length);
- /* now all set up.. */
+ /* now all set up.. */
- /* Work through the KV vector. */
- {
- int i;
- for (i = 1; i < next_vector_length; i++) {
- lispobj old_key = kv_vector[2*i];
- unsigned int old_index = (old_key & 0x1fffffff)%length;
+ /* Work through the KV vector. */
+ {
+ int i;
+ for (i = 1; i < next_vector_length; i++) {
+ lispobj old_key = kv_vector[2*i];
+ unsigned int old_index = (old_key & 0x1fffffff)%length;
- /* Scavenge the key and value. */
- scavenge(&kv_vector[2*i],2);
+ /* Scavenge the key and value. */
+ scavenge(&kv_vector[2*i],2);
- /* Check whether the key has moved and is EQ based. */
- {
- lispobj new_key = kv_vector[2*i];
- unsigned int new_index = (new_key & 0x1fffffff)%length;
+ /* Check whether the key has moved and is EQ based. */
+ {
+ lispobj new_key = kv_vector[2*i];
+ unsigned int new_index = (new_key & 0x1fffffff)%length;
- if ((old_index != new_index) &&
- ((!hash_vector) || (hash_vector[i] == 0x80000000)) &&
- ((new_key != empty_symbol) ||
- (kv_vector[2*i] != empty_symbol))) {
+ if ((old_index != new_index) &&
+ ((!hash_vector) || (hash_vector[i] == 0x80000000)) &&
+ ((new_key != empty_symbol) ||
+ (kv_vector[2*i] != empty_symbol))) {
- /*FSHOW((stderr,
- "* EQ key %d moved from %x to %x; index %d to %d\n",
- i, old_key, new_key, old_index, new_index));*/
+ /*FSHOW((stderr,
+ "* EQ key %d moved from %x to %x; index %d to %d\n",
+ i, old_key, new_key, old_index, new_index));*/
- if (index_vector[old_index] != 0) {
- /*FSHOW((stderr, "/P1 %d\n",
index_vector[old_index]));*/
+ if (index_vector[old_index] != 0) {
+ /*FSHOW((stderr, "/P1 %d\n", index_vector[old_index]));*/
- /* Unlink the key from the old_index chain. */
- if (index_vector[old_index] == i) {
- /*FSHOW((stderr, "/P2a %d\n", next_vector[i]));*/
- index_vector[old_index] = next_vector[i];
- /* Link it into the needing rehash chain. */
- next_vector[i] = fixnum_value(hash_table[11]);
- hash_table[11] = make_fixnum(i);
- /*SHOW("P2");*/
- } else {
- unsigned prior = index_vector[old_index];
- unsigned next = next_vector[prior];
+ /* Unlink the key from the old_index chain. */
+ if (index_vector[old_index] == i) {
+ /*FSHOW((stderr, "/P2a %d\n", next_vector[i]));*/
+ index_vector[old_index] = next_vector[i];
+ /* Link it into the needing rehash chain. */
+ next_vector[i] = fixnum_value(hash_table[11]);
+ hash_table[11] = make_fixnum(i);
+ /*SHOW("P2");*/
+ } else {
+ unsigned prior = index_vector[old_index];
+ unsigned next = next_vector[prior];
- /*FSHOW((stderr, "/P3a %d %d\n", prior, next));*/
+ /*FSHOW((stderr, "/P3a %d %d\n", prior, next));*/
- while (next != 0) {
- /*FSHOW((stderr, "/P3b %d %d\n", prior,
next));*/
- if (next == i) {
- /* Unlink it. */
- next_vector[prior] = next_vector[next];
- /* Link it into the needing rehash
- * chain. */
- next_vector[next] =
- fixnum_value(hash_table[11]);
- hash_table[11] = make_fixnum(next);
- /*SHOW("/P3");*/
- break;
- }
- prior = next;
- next = next_vector[next];
- }
- }
- }
- }
- }
- }
- }
- return (CEILING(kv_length + 2, 2));
+ while (next != 0) {
+ /*FSHOW((stderr, "/P3b %d %d\n", prior, next));*/
+ if (next == i) {
+ /* Unlink it. */
+ next_vector[prior] = next_vector[next];
+ /* Link it into the needing rehash
+ * chain. */
+ next_vector[next] =
+ fixnum_value(hash_table[11]);
+ hash_table[11] = make_fixnum(next);
+ /*SHOW("/P3");*/
+ break;
+ }
+ prior = next;
+ next = next_vector[next];
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return (CEILING(kv_length + 2, 2));
}
@@ -2205,13 +2217,13 @@
}
/* Is it plausible cons? */
if ((is_lisp_pointer(start_addr[0])
- || ((start_addr[0] & 3) == 0) /* fixnum */
- || (widetag_of(start_addr[0]) == BASE_CHAR_WIDETAG)
- || (widetag_of(start_addr[0]) == UNBOUND_MARKER_WIDETAG))
- && (is_lisp_pointer(start_addr[1])
- || ((start_addr[1] & 3) == 0) /* fixnum */
- || (widetag_of(start_addr[1]) == BASE_CHAR_WIDETAG)
- || (widetag_of(start_addr[1]) == UNBOUND_MARKER_WIDETAG)))
+ || ((start_addr[0] & 3) == 0) /* fixnum */
+ || (widetag_of(start_addr[0]) == BASE_CHAR_WIDETAG)
+ || (widetag_of(start_addr[0]) == UNBOUND_MARKER_WIDETAG))
+ && (is_lisp_pointer(start_addr[1])
+ || ((start_addr[1] & 3) == 0) /* fixnum */
+ || (widetag_of(start_addr[1]) == BASE_CHAR_WIDETAG)
+ || (widetag_of(start_addr[1]) == UNBOUND_MARKER_WIDETAG)))
break;
else {
if (gencgc_verbose)
@@ -2787,31 +2799,31 @@
/* Do a limited check for write_protected pages. If all pages
* are write_protected then there is no need to scavenge. */
- {
- int j, all_wp = 1;
- for (j = i; j <= last_page; j++)
- if (page_table[j].write_protected == 0) {
- all_wp = 0;
- break;
- }
+ {
+ int j, all_wp = 1;
+ for (j = i; j <= last_page; j++)
+ if (page_table[j].write_protected == 0) {
+ all_wp = 0;
+ break;
+ }
#if !SC_GEN_CK
- if (all_wp == 0)
+ if (all_wp == 0)
#endif
- {
- scavenge(page_address(i),
(page_table[last_page].bytes_used
- + (last_page-i)*4096)/4);
+ {
+ scavenge(page_address(i), (page_table[last_page].bytes_used
+ + (last_page-i)*4096)/4);
- /* Now scan the pages and write protect those
- * that don't have pointers to younger
- * generations. */
- if (enable_page_protection) {
- for (j = i; j <= last_page; j++) {
- num_wp += update_page_write_prot(j);
- }
- }
+ /* Now scan the pages and write protect those
+ * that don't have pointers to younger
+ * generations. */
+ if (enable_page_protection) {
+ for (j = i; j <= last_page; j++) {
+ num_wp += update_page_write_prot(j);
}
+ }
}
- i = last_page;
+ }
+ i = last_page;
}
}
@@ -2832,9 +2844,9 @@
FSHOW((stderr, "/scavenge_generation() %d\n", generation));
FSHOW((stderr,
"/page bytes_used=%d first_object_offset=%d dont_move=%d\n",
- page_table[i].bytes_used,
- page_table[i].first_object_offset,
- page_table[i].dont_move));
+ page_table[i].bytes_used,
+ page_table[i].first_object_offset,
+ page_table[i].dont_move));
lose("write to protected page %d in scavenge_generation()", i);
}
}
@@ -2911,37 +2923,37 @@
/* Do a limited check for write-protected pages. If all
* pages are write-protected then no need to scavenge,
* except if the pages are marked dont_move. */
- {
- int j, all_wp = 1;
- for (j = i; j <= last_page; j++)
- if ((page_table[j].write_protected == 0)
- || (page_table[j].dont_move != 0)) {
- all_wp = 0;
- break;
- }
+ {
+ int j, all_wp = 1;
+ for (j = i; j <= last_page; j++)
+ if ((page_table[j].write_protected == 0)
+ || (page_table[j].dont_move != 0)) {
+ all_wp = 0;
+ break;
+ }
- if (!all_wp) {
- int size;
+ if (!all_wp) {
+ int size;
- /* Calculate the size. */
- if (last_page == i)
- size = (page_table[last_page].bytes_used
- - page_table[i].first_object_offset)/4;
- else
- size = (page_table[last_page].bytes_used
- + (last_page-i)*4096
- - page_table[i].first_object_offset)/4;
+ /* Calculate the size. */
+ if (last_page == i)
+ size = (page_table[last_page].bytes_used
+ - page_table[i].first_object_offset)/4;
+ else
+ size = (page_table[last_page].bytes_used
+ + (last_page-i)*4096
+ - page_table[i].first_object_offset)/4;
- {
- new_areas_ignore_page = last_page;
+ {
+ new_areas_ignore_page = last_page;
- scavenge(page_address(i) +
- page_table[i].first_object_offset,
- size);
+ scavenge(page_address(i) +
+ page_table[i].first_object_offset,
+ size);
- }
- }
}
+ }
+ }
i = last_page;
}
@@ -2989,8 +3001,8 @@
current_new_areas_index = new_areas_index;
/*FSHOW((stderr,
- "The first scan is finished; current_new_areas_index=%d.\n",
- current_new_areas_index));*/
+ "The first scan is finished; current_new_areas_index=%d.\n",
+ current_new_areas_index));*/
while (current_new_areas_index > 0) {
/* Move the current to the previous new areas */
@@ -3052,8 +3064,8 @@
current_new_areas_index = new_areas_index;
/*FSHOW((stderr,
- "The re-scan has finished; current_new_areas_index=%d.\n",
- current_new_areas_index));*/
+ "The re-scan has finished; current_new_areas_index=%d.\n",
+ current_new_areas_index));*/
}
/* Turn off recording of areas allocated by gc_alloc(). */
@@ -3140,15 +3152,15 @@
/* Remove any write-protection. We should be able to rely
* on the write-protect flag to avoid redundant calls. */
- {
- void *page_start = (void *)page_address(last_page);
+ {
+ void *page_start = (void *)page_address(last_page);
- if (page_table[last_page].write_protected) {
- os_protect(page_start, 4096, OS_VM_PROT_ALL);
- page_table[last_page].write_protected = 0;
- }
+ if (page_table[last_page].write_protected) {
+ os_protect(page_start, 4096, OS_VM_PROT_ALL);
+ page_table[last_page].write_protected = 0;
}
- last_page++;
+ }
+ last_page++;
}
while ((last_page < last_free_page)
&& (page_table[last_page].allocated != FREE_PAGE)
@@ -3275,9 +3287,9 @@
* FIXME: Add a variable to enable this
* dynamically. */
/*
- if (!possibly_valid_dynamic_space_pointer((lispobj *)thing)) {
- lose("ptr %x to invalid object %x", thing, start);
- }
+ if (!possibly_valid_dynamic_space_pointer((lispobj *)thing)) {
+ lose("ptr %x to invalid object %x", thing, start);
+ }
*/
} else {
/* Verify that it points to another valid space. */
@@ -3447,7 +3459,7 @@
- (lispobj*)STATIC_SPACE_START;
struct thread *th;
for_each_thread(th) {
- int binding_stack_size =
+ int binding_stack_size =
(lispobj*)SymbolValue(BINDING_STACK_POINTER,th)
- (lispobj*)th->binding_stack_start;
verify_space(th->binding_stack_start, binding_stack_size);
@@ -3757,68 +3769,68 @@
#if RESCAN_CHECK
/* As a check re-scavenge the newspace once; no new objects should
* be found. */
- {
- int old_bytes_allocated = bytes_allocated;
- int bytes_allocated;
+ {
+ int old_bytes_allocated = bytes_allocated;
+ int bytes_allocated;
- /* Start with a full scavenge. */
- scavenge_newspace_generation_one_scan(new_space);
+ /* Start with a full scavenge. */
+ scavenge_newspace_generation_one_scan(new_space);
- /* Flush the current regions, updating the tables. */
- gc_alloc_update_all_page_tables();
+ /* Flush the current regions, updating the tables. */
+ gc_alloc_update_all_page_tables();
- bytes_allocated = bytes_allocated - old_bytes_allocated;
+ bytes_allocated = bytes_allocated - old_bytes_allocated;
- if (bytes_allocated != 0) {
- lose("Rescan of new_space allocated %d more bytes.",
- bytes_allocated);
- }
- }
+ if (bytes_allocated != 0) {
+ lose("Rescan of new_space allocated %d more bytes.",
+ bytes_allocated);
+ }
+ }
#endif
- scan_weak_pointers();
+ scan_weak_pointers();
- /* Flush the current regions, updating the tables. */
- gc_alloc_update_all_page_tables();
+ /* Flush the current regions, updating the tables. */
+ gc_alloc_update_all_page_tables();
- /* Free the pages in oldspace, but not those marked dont_move. */
- bytes_freed = free_oldspace();
+ /* Free the pages in oldspace, but not those marked dont_move. */
+ bytes_freed = free_oldspace();
- /* If the GC is not raising the age then lower the generation back
- * to its normal generation number */
- if (!raise) {
- for (i = 0; i < last_free_page; i++)
- if ((page_table[i].bytes_used != 0)
- && (page_table[i].gen == NUM_GENERATIONS))
- page_table[i].gen = generation;
- gc_assert(generations[generation].bytes_allocated == 0);
- generations[generation].bytes_allocated =
- generations[NUM_GENERATIONS].bytes_allocated;
- generations[NUM_GENERATIONS].bytes_allocated = 0;
- }
+ /* If the GC is not raising the age then lower the generation back
+ * to its normal generation number */
+ if (!raise) {
+ for (i = 0; i < last_free_page; i++)
+ if ((page_table[i].bytes_used != 0)
+ && (page_table[i].gen == NUM_GENERATIONS))
+ page_table[i].gen = generation;
+ gc_assert(generations[generation].bytes_allocated == 0);
+ generations[generation].bytes_allocated =
+ generations[NUM_GENERATIONS].bytes_allocated;
+ generations[NUM_GENERATIONS].bytes_allocated = 0;
+ }
- /* Reset the alloc_start_page for generation. */
- generations[generation].alloc_start_page = 0;
- generations[generation].alloc_unboxed_start_page = 0;
- generations[generation].alloc_large_start_page = 0;
- generations[generation].alloc_large_unboxed_start_page = 0;
+ /* Reset the alloc_start_page for generation. */
+ generations[generation].alloc_start_page = 0;
+ generations[generation].alloc_unboxed_start_page = 0;
+ generations[generation].alloc_large_start_page = 0;
+ generations[generation].alloc_large_unboxed_start_page = 0;
- if (generation >= verify_gens) {
- if (gencgc_verbose)
- SHOW("verifying");
- verify_gc();
- verify_dynamic_space();
- }
+ if (generation >= verify_gens) {
+ if (gencgc_verbose)
+ SHOW("verifying");
+ verify_gc();
+ verify_dynamic_space();
+ }
- /* Set the new gc trigger for the GCed generation. */
- generations[generation].gc_trigger =
- generations[generation].bytes_allocated
- + generations[generation].bytes_consed_between_gc;
+ /* Set the new gc trigger for the GCed generation. */
+ generations[generation].gc_trigger =
+ generations[generation].bytes_allocated
+ + generations[generation].bytes_consed_between_gc;
- if (raise)
- generations[generation].num_gc = 0;
- else
- ++generations[generation].num_gc;
+ if (raise)
+ generations[generation].num_gc = 0;
+ else
+ ++generations[generation].num_gc;
}
/* Update last_free_page, then SymbolValue(ALLOCATION_POINTER). */
Index: gencgc.h
===================================================================
RCS file: /cvsroot/sbcl/sbcl/src/runtime/gencgc.h,v
retrieving revision 1.5.8.1
retrieving revision 1.5.8.2
diff -u -d -r1.5.8.1 -r1.5.8.2
--- gencgc.h 23 Feb 2003 22:57:55 -0000 1.5.8.1
+++ gencgc.h 25 Feb 2003 22:28:04 -0000 1.5.8.2
@@ -15,6 +15,8 @@
#ifndef _GENCGC_H_
#define _GENCGC_H_
+
+#include "genesis/code.h"
void gc_free_heap(void);
inline int find_page_index(void *);
@@ -81,30 +83,14 @@
#define NUM_PAGES ((DYNAMIC_SPACE_SIZE+4095)/4096)
extern struct page page_table[NUM_PAGES];
-/* Abstract out the data for an allocation region allowing a single
- * routine to be used for allocation and closing. */
-struct alloc_region {
-
- /* These two are needed for quick allocation. */
- void *free_pointer;
- void *end_addr; /* pointer to the byte after the last usable byte */
-
- /* These are needed when closing the region. */
- int first_page;
- int last_page;
- void *start_addr;
-};
-extern struct alloc_region boxed_region;
-extern struct alloc_region unboxed_region;
-
-void gencgc_pickup_dynamic(void);
+void gencgc_pickup_dynamic(void);
void sniff_code_object(struct code *code, unsigned displacement);
int update_x86_dynamic_space_free_pointer(void);
-void gc_alloc_update_page_tables(int unboxed,
+void gc_alloc_update_page_tables(int unboxed,
struct alloc_region *alloc_region);
-void gc_alloc_update_all_page_tables(void);
-
+void gc_alloc_update_all_page_tables(void);
+void gc_set_region_empty(struct alloc_region *region);
#endif _GENCGC_H_
Index: runtime.c
===================================================================
RCS file: /cvsroot/sbcl/sbcl/src/runtime/runtime.c,v
retrieving revision 1.17.4.9
retrieving revision 1.17.4.10
diff -u -d -r1.17.4.9 -r1.17.4.10
--- runtime.c 23 Feb 2003 22:57:55 -0000 1.17.4.9
+++ runtime.c 25 Feb 2003 22:28:04 -0000 1.17.4.10
@@ -385,8 +385,7 @@
if(!th) continue;
if(WIFEXITED(status) || WIFSIGNALED(status)) {
fprintf(stderr,"waitpid : child %d %x exited \n", pid,th);
- destroy_thread(th); /* FIXME lock all_threads */
-
+ destroy_thread(th);
/* FIXME arrange to call or fake (free-mutex *session-lock*)
* if necessary */
}
Index: thread.c
===================================================================
RCS file: /cvsroot/sbcl/sbcl/src/runtime/Attic/thread.c,v
retrieving revision 1.1.4.7
retrieving revision 1.1.4.8
diff -u -d -r1.1.4.7 -r1.1.4.8
--- thread.c 25 Feb 2003 01:40:40 -0000 1.1.4.7
+++ thread.c 25 Feb 2003 22:28:06 -0000 1.1.4.8
@@ -13,13 +13,19 @@
#include "target-arch-os.h"
#include "os.h"
#include "globals.h"
+#ifdef LISP_FEATURE_GENCGC
+#include "gencgc.h"
+#endif
+#include "dynbind.h"
#include "genesis/cons.h"
#define ALIEN_STACK_SIZE (1*1024*1024) /* 1Mb size chosen at random */
+
int dynamic_values_bytes=4096*sizeof(lispobj); /* same for all threads */
struct thread *all_threads;
-
+lispobj all_threads_lock;
extern struct interrupt_data * global_interrupt_data;
+void get_spinlock(lispobj *word,int value);
/* this is the first thing that clone() runs in the child (which is
* why the silly calling convention). Basically it calls the user's
@@ -56,10 +62,7 @@
* thread
*/
-struct thread *create_thread(lispobj initial_function) {
- /* XXX This function or some of it needs to lock all_threads
- */
- /* lispobj trampoline_argv[2]; */
+pid_t create_thread(lispobj initial_function) {
union per_thread_data *per_thread;
struct thread *th=0; /* subdue gcc */
void *spaces=0;
@@ -135,7 +138,6 @@
bind_variable(INTERRUPT_PENDING, NIL,th);
bind_variable(INTERRUPTS_ENABLED,T,th);
- th->next=all_threads;
th->interrupt_data=malloc(sizeof (struct interrupt_data));
if(all_threads)
memcpy(th->interrupt_data,arch_os_get_current_thread()->interrupt_data,
@@ -146,24 +148,26 @@
#if defined(LISP_FEATURE_X86) && defined (LISP_FEATURE_LINUX)
-
th->unbound_marker=initial_function;
kid_pid=
clone(new_thread_trampoline,
(((void*)th->control_stack_start)+THREAD_CONTROL_STACK_SIZE-4),
(((getpid()!=parent_pid)?(CLONE_PARENT):0)
|SIGALRM|CLONE_VM),th);
- if(kid_pid<=0) goto cleanup;
+ if(kid_pid<=0)
+ goto cleanup;
#else
#error this stuff presently only works on x86 Linux
#endif
+
+ get_spinlock(&all_threads_lock,kid_pid);
+ th->next=all_threads;
all_threads=th;
- /* note that th->pid is 0 at this time. If this function is
- * called >once simultaneously, we may end up write-protecting
- * one thread twice and the other not at all. That would be bad.
- * (Access to this function is supposed to be serialised anyway
- * though, for the all_threads manipulation) */
+ /* note that th->pid is 0 at this time. We rely on all_threads_lock
+ * to ensure that we don't have >1 thread with pid=0 on the list at once
+ */
protect_control_stack_guard_page(th->pid,1);
+ all_threads_lock=0;
th->pid=kid_pid; /* child will not start until this is set */
return th->pid;
cleanup:
@@ -179,6 +183,7 @@
/* precondition: the unix task has already been killed and exited.
* This is called by the parent */
gc_alloc_update_page_tables(0, &th->alloc_region);
+ get_spinlock(&all_threads_lock,th->pid);
if(th==all_threads)
all_threads=th->next;
else {
@@ -186,8 +191,9 @@
while(th1->next!=th) th1=th1->next;
th1->next=th->next; /* unlink */
}
+ all_threads_lock=0;
/* if(th && th->tls_cookie>=0) os_free_tls_pointer(th); */
- os_invalidate(th->control_stack_start,
+ os_invalidate((os_vm_address_t) th->control_stack_start,
THREAD_CONTROL_STACK_SIZE+BINDING_STACK_SIZE+
ALIEN_STACK_SIZE+dynamic_values_bytes+
32*SIGSTKSZ);
@@ -204,10 +210,10 @@
struct mutex {
- lispobj header,type,*name,*value,*queuelock, *queue;
+ lispobj header,type,*name,*value,queuelock, *queue;
};
-void spinlock_get(lispobj *word,int value)
+void get_spinlock(lispobj *word,int value)
{
u32 new_val=0;
do {
@@ -221,13 +227,13 @@
void add_thread_to_queue(int pid, lispobj mutex_p)
{
sigset_t oldset,newset;
- struct mutex *mutex=native_pointer(mutex_p);
+ struct mutex *mutex=(struct mutex *)native_pointer(mutex_p);
struct cons *cons;
sigemptyset(&newset);
sigaddset(&newset,SIGALRM);
sigprocmask(SIG_BLOCK, &newset, &oldset);
- spinlock_get(&(mutex->queuelock),pid);
+ get_spinlock(&(mutex->queuelock),pid);
cons=alloc_cons(make_fixnum(pid),mutex->queue);
mutex->queue=cons;
mutex->queuelock=0;
-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf
|