Beispiel #1
0
void
MR_deallocate(MR_MemoryList allocated)
{
    while (allocated != NULL) {
        MR_MemoryList next = allocated->next;
        /*
        ** These were allocated with MR_GC_NEW_ARRAY_ATTRIB so we must free
        ** using MR_GC_free_attrib.
        **/
        MR_GC_free_attrib(allocated->data);
        MR_GC_free_attrib(allocated);
        allocated = next;
    }
}
Beispiel #2
0
/*
** MR_STM_block_thread is called to block the thread in high level C grades,
** using POSIX thread facilities, as there is a POSIX thread for every 
** Mercury thread in these grades. The low level C grade equivalent of this
** code is defined in the stm_builtin library module.
*/
void
MR_STM_block_thread(MR_STM_TransLog *tlog)
{
#if defined(MR_THREAD_SAFE)
        MR_STM_ConditionVar     *thread_condvar;

        thread_condvar = MR_GC_NEW_ATTRIB(MR_STM_ConditionVar,
            MR_ALLOC_SITE_RUNTIME);
        MR_STM_condvar_init(thread_condvar);

        MR_STM_wait(tlog, thread_condvar);

#if defined(MR_STM_DEBUG)
        fprintf(stderr, "STM BLOCKING: log <0x%.8lx>\n", (MR_Word)tlog);
#endif
        MR_STM_condvar_wait(thread_condvar, &MR_STM_lock);

#if defined(MR_STM_DEBUG)
        fprintf(stderr, "STM RESCHEDULING: log <0x%.8lx>\n", (MR_Word)tlog);
#endif
        MR_STM_unwait(tlog, thread_condvar);

        MR_UNLOCK(&MR_STM_lock, "MR_STM_block_thread");

        MR_GC_free_attrib(thread_condvar);
#else
    MR_fatal_error("Blocking thread in non-parallel grade");
#endif
}
Beispiel #3
0
static MR_MemoryZone *
MR_rewind_nondetstack_segments(MR_Word *maxfr)
{
    MR_MemoryZone   *zone_to_reuse;
    MR_MemoryZone   *zone;
    MR_Word         *limit;
    MR_MemoryZones  *list;

    zone_to_reuse = NULL;

    for (;;) {
        zone = MR_CONTEXT(MR_ctxt_nondetstack_zone);
        limit = (MR_Word *) zone->MR_zone_end;
        if (maxfr >= zone->MR_zone_min && maxfr < limit) {
            break;
        }

#ifdef  MR_DEBUG_STACK_SEGMENTS
        printf("\nfreeing zone\n");
        MR_print_zone(stdout, zone);
#endif

        // If there are several currently unneeded segments, this algorithm
        // reuses the zone of the topmost segment (the first segment in the
        // list from the top), since its contents are more likely to have been
        // recently referred to, and thus more likely to be in the cache.
        //
        // However, reusing the zone of the bottom-most unneeded segment
        // would look conceptually a bit neater in that it would preserve
        // the follows/precedes relationship between the zones.

        if (zone_to_reuse == NULL) {
            zone_to_reuse = zone;
        } else {
            MR_release_zone(zone);
        }

        list = MR_CONTEXT(MR_ctxt_prev_nondetstack_zones);
        assert(list != NULL);
        MR_CONTEXT(MR_ctxt_nondetstack_zone) = list->MR_zones_head;
        MR_CONTEXT(MR_ctxt_prev_nondetstack_zones) = list->MR_zones_tail;
        MR_GC_free_attrib(list);
    }

#ifdef  MR_DEBUG_STACK_SEGMENTS
    if (zone_to_reuse == NULL) {
        printf("\nno old nondet segment zone available for reuse\n");
    } else {
        printf("\nreturning zone of old nondet segment for reuse: %p\n",
            zone_to_reuse);
    }
#endif

    return zone_to_reuse;
}