}
}
-#if 0 /* old version */
-ptr_t GC_get_stack_base()
-{
- extern struct WBStartup *_WBenchMsg;
- extern long __base;
- extern long __stack;
- struct Task *task;
- struct Process *proc;
- struct CommandLineInterface *cli;
- long size;
-
- if ((task = FindTask(0)) == 0) {
- GC_err_puts("Cannot find own task structure\n");
- ABORT("task missing");
- }
- proc = (struct Process *)task;
- cli = BADDR(proc->pr_CLI);
-
- if (_WBenchMsg != 0 || cli == 0) {
- size = (char *)task->tc_SPUpper - (char *)task->tc_SPLower;
- } else {
- size = cli->cli_DefaultStack * 4;
- }
- return (ptr_t)(__base + GC_max(size, __stack));
-}
-#endif
-
-
#endif
ABORT("Can`t find correct Segments.\nSolution: Use an newer version of ixemul.library");
}
# endif
- }
-
-#if 0 /* old version */
- void GC_register_data_segments()
- {
- extern struct WBStartup *_WBenchMsg;
- struct Process *proc;
- struct CommandLineInterface *cli;
- BPTR myseglist;
- ULONG *data;
-
- if ( _WBenchMsg != 0 ) {
- if ((myseglist = _WBenchMsg->sm_Segment) == 0) {
- GC_err_puts("No seglist from workbench\n");
- return;
- }
- } else {
- if ((proc = (struct Process *)FindTask(0)) == 0) {
- GC_err_puts("Cannot find process structure\n");
- return;
- }
- if ((cli = BADDR(proc->pr_CLI)) == 0) {
- GC_err_puts("No CLI\n");
- return;
- }
- if ((myseglist = cli->cli_Module) == 0) {
- GC_err_puts("No seglist from CLI\n");
- return;
- }
- }
-
- for (data = (ULONG *)BADDR(myseglist); data != 0;
- data = (ULONG *)BADDR(data[0])) {
-# ifdef AMIGA_SKIP_SEG
- if (((ULONG) GC_register_data_segments < (ULONG) &data[1]) ||
- ((ULONG) GC_register_data_segments > (ULONG) &data[1] + data[-1])) {
-# else
- {
-# endif /* AMIGA_SKIP_SEG */
- GC_add_roots_inner((char *)&data[1],
- ((char *)&data[1]) + data[-1], FALSE);
- }
- }
- }
-#endif /* old version */
-
+ }
#endif
* can be called from within GC_call_with_alloc_lock, and the cord
* package does so. On systems that allow nested lock acquisition, this
* happens to work.
- * On other systems, SET_LOCK_HOLDER and friends must be suitably defined.
*/
-#if 0
-static GC_bool syscall_acquired_lock = FALSE; /* Protected by GC lock. */
-
-void GC_begin_syscall(void)
-{
- /* FIXME: Resurrecting this code would require fixing the */
- /* test, which can spuriously return TRUE. */
- if (!I_HOLD_LOCK()) {
- LOCK();
- syscall_acquired_lock = TRUE;
- }
-}
-
-void GC_end_syscall(void)
-{
- if (syscall_acquired_lock) {
- syscall_acquired_lock = FALSE;
- UNLOCK();
- }
-}
-
-void GC_unprotect_range(ptr_t addr, word len)
-{
- struct hblk * start_block;
- struct hblk * end_block;
- register struct hblk *h;
- ptr_t obj_start;
-
- if (!GC_dirty_maintained) return;
- obj_start = GC_base(addr);
- if (obj_start == 0) return;
- if (GC_base(addr + len - 1) != obj_start) {
- ABORT("GC_unprotect_range(range bigger than object)");
- }
- start_block = (struct hblk *)((word)addr & ~(GC_page_size - 1));
- end_block = (struct hblk *)((word)(addr + len - 1) & ~(GC_page_size - 1));
- end_block += GC_page_size/HBLKSIZE - 1;
- for (h = start_block; (word)h <= (word)end_block; h++) {
- register word index = PHT_HASH(h);
-
- async_set_pht_entry_from_index(GC_dirty_pages, index);
- }
- UNPROTECT(start_block,
- ((ptr_t)end_block - (ptr_t)start_block) + HBLKSIZE);
-}
-
-
/* We no longer wrap read by default, since that was causing too many */
/* problems. It is preferred that the client instead avoids writing */
/* to the write-protected heap with a system call. */
-/* This still serves as sample code if you do want to wrap system calls.*/
-
-#if !defined(MSWIN32) && !defined(MSWINCE) && !defined(GC_USE_LD_WRAP)
-/* Replacement for UNIX system call. */
-/* Other calls that write to the heap should be handled similarly. */
-/* Note that this doesn't work well for blocking reads: It will hold */
-/* the allocation lock for the entire duration of the call. */
-/* Multi-threaded clients should really ensure that it won't block, */
-/* either by setting the descriptor non-blocking, or by calling select */
-/* or poll first, to make sure that input is available. */
-/* Another, preferred alternative is to ensure that system calls never */
-/* write to the protected heap (see above). */
-# include <unistd.h>
-# include <sys/uio.h>
-ssize_t read(int fd, void *buf, size_t nbyte)
-{
- int result;
-
- GC_begin_syscall();
- GC_unprotect_range(buf, (word)nbyte);
-# if defined(IRIX5) || defined(GC_LINUX_THREADS)
- /* Indirect system call may not always be easily available. */
- /* We could call _read, but that would interfere with the */
- /* libpthread interception of read. */
- /* On Linux, we have to be careful with the linuxthreads */
- /* read interception. */
- {
- struct iovec iov;
-
- iov.iov_base = buf;
- iov.iov_len = nbyte;
- result = readv(fd, &iov, 1);
- }
-# else
-# if defined(HURD)
- result = __read(fd, buf, nbyte);
-# else
- /* The two zero args at the end of this list are because one
- IA-64 syscall() implementation actually requires six args
- to be passed, even though they aren't always used. */
- result = syscall(SYS_read, fd, buf, nbyte, 0, 0);
-# endif /* !HURD */
-# endif
- GC_end_syscall();
- return(result);
-}
-#endif /* !MSWIN32 && !MSWINCE && !GC_LINUX_THREADS */
-
-#if defined(GC_USE_LD_WRAP) && !defined(THREADS)
- /* We use the GNU ld call wrapping facility. */
- /* I'm not sure that this actually wraps whatever version of read */
- /* is called by stdio. That code also mentions __read. */
-# include <unistd.h>
- ssize_t __wrap_read(int fd, void *buf, size_t nbyte)
- {
- int result;
-
- GC_begin_syscall();
- GC_unprotect_range(buf, (word)nbyte);
- result = __real_read(fd, buf, nbyte);
- GC_end_syscall();
- return(result);
- }
-
- /* We should probably also do this for __read, or whatever stdio */
- /* actually calls. */
-#endif
-#endif /* 0 */
# ifdef CHECKSUMS
GC_INNER GC_bool GC_page_was_ever_dirty(struct hblk * h GC_ATTR_UNUSED)