/* doc: <routine name="eif_twin" export="public"> doc: <summary>Default implementation of feature {ANY}.twin.</summary> doc: <thread_safety>Safe</thread_safety> doc: <synchronization>None required</synchronization> doc: </routine> */ rt_public EIF_REFERENCE eif_twin (EIF_REFERENCE Current) { EIF_BOOLEAN a; EIF_REFERENCE Result = NULL; EIF_GET_CONTEXT REQUIRE ("current_attached", Current); RT_GC_PROTECT (Current); /* Protect against GC */ RT_GC_PROTECT (Result); a = c_check_assert (EIF_FALSE); Result = eclone (Current); if (!egc_has_old_copy_semantic) { /* When using the new semantic for `copy', we have to perform * a shallow copy of the object being twined before call `copy'. */ ecopy (Current, Result); } #ifdef WORKBENCH call_copy (Dtype (Result), Result, Current); #else egc_copy [Dtype (Result)] (Result, Current); #endif c_check_assert (a); RT_GC_WEAN_N(2); /* Remove protection */ return Result; }
static int do_eclone(int (*child_fn)(void *), void *child_arg, unsigned int flags_low, int nr_pids, pid_t *pids) { int rc; void *stack; struct clone_args clone_args; int args_size; stack = genstack_alloc(STACKSIZE); if (!stack) { printf("ERROR: setup_stack returns NULL for size %d\n", STACKSIZE); exit(1); } memset(&clone_args, 0, sizeof(clone_args)); clone_args.clone_flags_high = (u64)1 << 33; clone_args.child_stack = (unsigned long)genstack_sp(stack); clone_args.child_stack_size = 0; clone_args.parent_tid_ptr = (unsigned long)(&parent_tid); clone_args.child_tid_ptr = (unsigned long)(&child_tid); clone_args.nr_pids = nr_pids; if (verbose) { printf("[%d, %d]: Parent:\n\t child_stack 0x%p, ptidp %llx, " "ctidp %llx, pids %p\n", getpid(), gettid(), stack, clone_args.parent_tid_ptr, clone_args.child_tid_ptr, pids); } args_size = sizeof(struct clone_args); rc = eclone(child_fn, child_arg, flags_low, &clone_args, pids); if (verbose) { printf("[%d, %d]: eclone() returned %d, error %d\n", getpid(), gettid(), rc, errno); fflush(stdout); } if (rc < 0 && errno == EINVAL) { printf("PASS: eclone() failed (clone_flags_high not 0)\n"); exit(0); } else { printf("FAIL: Expected eclone() to fail with EINVAL"); exit(1); } return rc; }
/* doc: <routine name="eif_standard_twin" export="public"> doc: <summary>Default implementation of feature {ANY}.standard_twin.</summary> doc: <thread_safety>Safe</thread_safety> doc: <synchronization>None required</synchronization> doc: </routine> */ rt_public EIF_REFERENCE eif_standard_twin (EIF_REFERENCE Current) { EIF_BOOLEAN a; EIF_REFERENCE Result = NULL; EIF_GET_CONTEXT REQUIRE ("current_attached", Current); RT_GC_PROTECT (Current); /* Protect against GC */ RT_GC_PROTECT (Result); a = c_check_assert (EIF_FALSE); Result = eclone (Current); ecopy (Current, Result); c_check_assert (a); RT_GC_WEAN_N(2); /* Remove protection */ return Result; }
rt_public EIF_REFERENCE rtclone(EIF_REFERENCE source) { /* Clone source, copy the source in the clone and return the clone */ EIF_GET_CONTEXT EIF_REFERENCE result = NULL; /* Address of the cloned object */ if (source == (EIF_REFERENCE) 0) return (EIF_REFERENCE) 0; /* Object protections in case of GC cycle */ RT_GC_PROTECT(source); RT_GC_PROTECT(result); result = eclone (source); /* Clone object */ ecopy (source, result); /* Performs copy from `source' to `result' */ RT_GC_WEAN_N(2); /* Remove protection */ ENSURE ("result_created", result); return result; /* Pointer to the cloned object */ }