GC_INNER GC_bool GC_have_errors = FALSE;
+#if !defined(EAGER_SWEEP) && defined(MARK_UNCONDITIONALLY)
+void GC_reclaim_unconditionally_marked(void);
+#endif
+
GC_INLINE void GC_add_leaked(ptr_t leaked)
{
# ifndef SHORT_DBG_HDRS
/* This is a very stupid thing to do. We make it possible anyway, */
/* so that you can convince yourself that it really is very stupid. */
GC_reclaim_all((GC_stop_func)0, FALSE);
+# elif defined(MARK_UNCONDITIONALLY)
+ /* However, make sure to clear reclaimable objects of kinds with */
+ /* unconditional marking enabled before we do any significant */
+ /* marking work. */
+ GC_reclaim_unconditionally_marked();
# endif
# if defined(PARALLEL_MARK)
GC_ASSERT(0 == GC_fl_builder_count);
# endif
return(TRUE);
}
+
+#if !defined(EAGER_SWEEP) && defined(MARK_UNCONDITIONALLY)
+/* Part of disclaim patch. This could be merged with the above, but I don't
+ * want to clobber the original source too much by changing the prototype and
+ * testing for defined(MARK_UNCONDITIONALLY). */
+void GC_reclaim_unconditionally_marked(void)
+{
+ word sz;
+ unsigned kind;
+ hdr * hhdr;
+ struct hblk * hbp;
+ struct obj_kind * ok;
+ struct hblk ** rlp;
+ struct hblk ** rlh;
+ for (kind = 0; kind < GC_n_kinds; kind++) {
+ ok = &(GC_obj_kinds[kind]);
+ if (!ok->ok_mark_unconditionally) continue;
+ rlp = ok->ok_reclaim_list;
+ if (rlp == 0) continue;
+ for (sz = 1; sz <= MAXOBJGRANULES; sz++) {
+ rlh = rlp + sz;
+ while ((hbp = *rlh) != 0) {
+ hhdr = HDR(hbp);
+ *rlh = hhdr->hb_next;
+ GC_reclaim_small_nonempty_block(hbp, FALSE, &GC_bytes_found);
+ }
+ }
+ }
+}
+#endif
#include "gc_disclaim.h"
+#include "atomic_ops.h"
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
-static int nf = 0;
+static AO_t free_count = 0;
typedef struct testobj_s *testobj_t;
struct testobj_s {
void testobj_finalize(void *obj, void *carg)
{
#define obj ((testobj_t)obj)
- ++*(int *)carg;
+ AO_fetch_and_add1((AO_t *)carg);
assert(obj->i++ == 109);
#undef obj
}
static struct GC_finalizer_closure fclos = {
testobj_finalize,
- &nf
+ &free_count
};
testobj_t testobj_new(int model)
switch (model) {
case 0:
obj = GC_malloc(sizeof(struct testobj_s));
- GC_register_finalizer_no_order(obj, testobj_finalize, &nf,
+ GC_register_finalizer_no_order(obj, testobj_finalize, &free_count,
NULL, NULL);
break;
case 1:
default:
abort();
}
+ assert(obj->i == 0 && obj->keep_link == NULL);
obj->i = 109;
- obj->keep_link = NULL;
return obj;
}
#define ALLOC_CNT (4*1024*1024)
-#define KEEP_CNT (32*1024)
+#define KEEP_CNT ( 32*1024)
int main(int argc, char **argv)
{
t /= CLOCKS_PER_SEC;
if (model < 2)
printf("%20s: %12.4lf %12lg %12lg\n", model_str[model],
- nf/(double)ALLOC_CNT, t, t/nf);
+ free_count/(double)ALLOC_CNT, t, t/free_count);
else
printf("%20s: 0 %12lg N/A\n",
model_str[model], t);