* malloc.c(GC_free): Ignore bad frees on MSWIN32 with REDIRECT_MALLOC.
* NT_MAKEFILE: msvc_dbg.h is in include/private. Don't use cvars
rc.
* misc.c (WIN32 GC_write): Define GC_need_to_lock in single-threaded
case.
* win32_threads.c: Test for __MINGW32__ in addition to _MINGW_VER.
(GC_CreateThread, GC_beginthreadex): Deallocate args even if we fail.
* include/gc.h: Add GC_reachable_here(). (GC_WinMain): Add GC_API.
(GC_beginthreadex, GC_endthreadex, GC_ExitThread): Declare.
* tests/test.c: Add GC_reachable_here() call.
+2007-05-22 Hans Boehm <Hans.Boehm@hp.com>
+
+ * malloc.c(GC_free): Ignore bad frees on MSWIN32 with REDIRECT_MALLOC.
+ * NT_MAKEFILE: msvc_dbg.h is in include/private. Don't use cvars
+ rc.
+ * misc.c (WIN32 GC_write): Define GC_need_to_lock in single-threaded
+ case.
+ * win32_threads.c: Test for __MINGW32__ in addition to _MINGW_VER.
+ (GC_CreateThread, GC_beginthreadex): Deallocate args even if we fail.
+ * include/gc.h: Add GC_reachable_here(). (GC_WinMain): Add GC_API.
+ (GC_beginthreadex, GC_endthreadex, GC_ExitThread): Declare.
+ * tests/test.c: Add GC_reachable_here() call.
+
2007-05-21 Hans Boehm <Hans.Boehm@hp.com>
* alloc.c (GC_try_to_collect): Call GC_init if necessary.
.cpp.obj:
$(cc) $(cdebug) $(cflags) $(cvars) -Iinclude -DALL_INTERIOR_POINTERS -DGC_NOT_DLL -DGC_BUILD $*.CPP /Fo$*.obj
-$(OBJS) tests\test.obj: include\private\gc_priv.h include\private\gc_hdrs.h include\gc.h include\private\gcconfig.h include\private\gc_locks.h include\private\gc_pmark.h include\gc_mark.h include\msvc_dbg.h
+$(OBJS) tests\test.obj: include\private\gc_priv.h include\private\gc_hdrs.h include\gc.h include\private\gcconfig.h include\private\gc_locks.h include\private\gc_pmark.h include\gc_mark.h include\private\msvc_dbg.h
gc.lib: $(OBJS)
lib /MACHINE:i386 /out:gc.lib $(OBJS)
cord\de.obj cord\de_win.obj: include\cord.h include\private\cord_pos.h cord\de_win.h cord\de_cmds.h
cord\de_win.res: cord\de_win.rc cord\de_win.h cord\de_cmds.h
- $(rc) $(rcvars) -r -fo cord\de_win.res $(cvars) cord\de_win.rc
+ $(rc) $(rcvars) -r -fo cord\de_win.res cord\de_win.rc
# Cord/de is a real win32 gui application.
cord\de.exe: cord\cordbscs.obj cord\cordxtra.obj cord\de.obj cord\de_win.obj cord\de_win.rbj gc.lib
/* GC-finalize_on_demand is nonzero, it must be called */
/* explicitly. */
+/* Explicitly tell the collector that an object is reachable */
+/* at a particular program point. This prevents the argument */
+/* pointer from being optimized away, even it is otherwise no */
+/* longer needed. It should have no visible effect in the */
+/* absence of finalizers or disappearing links. But it may be */
+/* needed to prevent finalizers from running while the */
+/* associated external resource is still in use. */
+/* The function is sometimes called keep_alive in other */
+/* settings. */
+# if defined(__GNUC__) && !defined(__INTEL_COMPILER)
+# define GC_reachable_here(ptr) \
+ __asm__ volatile(" " : : "X"(ptr) : "memory");
+# else
+ GC_API void GC_noop1(GC_word x);
+# define GC_reachable_here(ptr) GC_noop1((GC_word)(ptr));
+#endif
+
/* GC_set_warn_proc can be used to redirect or filter warning messages. */
/* p may not be a NULL pointer. */
typedef void (*GC_warn_proc) (char *msg, GC_word arg);
* win32_threads.c implements the real WinMain, which will start a new thread
* to call GC_WinMain after initializing the garbage collector.
*/
- int WINAPI GC_WinMain(
+ GC_API int WINAPI GC_WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPWSTR lpCmdLine,
int nCmdShow );
+ GC_API uintptr_t GC_beginthreadex(
+ void *security, unsigned stack_size,
+ unsigned ( __stdcall *start_address )( void * ),
+ void *arglist, unsigned initflag, unsigned *thrdaddr);
+
+ GC_API void GC_endthreadex(unsigned retval);
+
+ GC_API void WINAPI GC_ExitThread(DWORD dwExitCode);
+
# ifndef GC_BUILD
# define WinMain GC_WinMain
# endif
GC_ASSERT(GC_base(p) == p);
# if defined(REDIRECT_MALLOC) && \
(defined(GC_SOLARIS_THREADS) || defined(GC_LINUX_THREADS) \
- || defined(__MINGW32__)) /* Should this be MSWIN32 in general? */
+ || defined(MSWIN32))
/* For Solaris, we have to redirect malloc calls during */
/* initialization. For the others, this seems to happen */
/* implicitly. */
}
}
+# ifndef THREADS
+# define GC_need_to_lock 0 /* Not defined without threads */
+# endif
int GC_write(buf, len)
const char * buf;
size_t len;
if (GC_need_to_lock) LeaveCriticalSection(&GC_write_cs);
return tmp ? (int)written : -1;
}
+# undef GC_need_to_lock
#endif
GC_printf("GC_general_register_disappearing_link failed 2\n");
FAIL;
}
+ GC_reachable_here(result);
}
return(result);
}
#if defined(GC_WIN32_THREADS)
-#if defined( _MINGW_VER )
+#if defined( _MINGW_VER ) || defined( __MINGW32__ )
# include <stdint.h>
/* We mention uintptr_t. */
/* Perhaps this should be included in pure msft environments */
dwStackSize, GC_win32_start,
args, dwCreationFlags,
lpThreadId);
-
+ if( thread_h == 0 ) GC_free( args );
return thread_h;
}
}
GC_need_to_lock = TRUE;
thread_h = _beginthreadex(security, stack_size, GC_win32_start,
args, initflag, thrdaddr);
-
+ if( thread_h == 0 ) GC_free( args );
return thread_h;
}
}