Пример #1
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
}
Пример #2
0
MR_Dlist *
MR_dlist_makelist0(void)
{
    MR_Dlist    *list;

    list = MR_GC_NEW_ATTRIB(MR_Dlist, MR_ALLOC_SITE_RUNTIME);
    MR_dlist_data(list) = NULL;
    MR_dlist_next(list) = list;
    MR_dlist_prev(list) = list;

    return list;
}
Пример #3
0
void
MR_insert_internal_label(const char *name, MR_Code *addr,
    const MR_LabelLayout *label_layout)
{
    MR_Internal *internal;
    MR_Internal *prev_internal;

    MR_do_init_label_tables();

    internal = MR_GC_NEW_ATTRIB(MR_Internal, MR_ALLOC_SITE_RUNTIME);
    internal->MR_internal_addr = addr;
    internal->MR_internal_layout = label_layout;
    internal->MR_internal_name = name;

#ifdef  MR_LOWLEVEL_DEBUG
    if (MR_progdebug) {
        /*
        ** We can't assume that MR_LOWLEVEL_DEBUG was turned on in the code
        ** that generated the call to this function just because
        ** MR_LOWLEVEL_DEBUG is turned on here.
        */
        if (name != NULL) {
            printf("inserting internal label %s at %p\n", name, addr);
        } else {
            printf("inserting internal label at %p\n", addr);
        }
    }
#endif

    prev_internal = (MR_Internal *)
        MR_insert_hash_table(internal_addr_table, internal);

    if (prev_internal != NULL) {
        /*
        ** Two labels at same location will happen quite often, when the code
        ** generated between them turns out to be empty. In this case,
        ** MR_insert_hash_table will not have inserted internal into the table.
        **
        ** If only one of internal and prev_internal have a layout structure,
        ** make sure that we associate the layout structure with the label
        ** address.
        **
        ** If both internal and prev_internal have a layout structure,
        ** we rely on the compiler to make sure that it is ok to use
        ** either of their layout structures.
        */

        if (prev_internal->MR_internal_layout == NULL) {
            prev_internal->MR_internal_layout = label_layout;
        }
    }
}
Пример #4
0
void
MR_STM_record_transaction(MR_STM_TransLog *tlog, MR_STM_Var *var,
    MR_Word old_value, MR_Word new_value)
{
    MR_STM_TransRecord  *new_record;

    new_record = MR_GC_NEW_ATTRIB(MR_STM_TransRecord,
        MR_ALLOC_SITE_RUNTIME);
    new_record->MR_STM_tr_var = var;
    new_record->MR_STM_tr_old_value = old_value;
    new_record->MR_STM_tr_new_value = new_value;
    new_record->MR_STM_tr_next = tlog->MR_STM_tl_records;
    tlog->MR_STM_tl_records = new_record;
}
Пример #5
0
void
MR_STM_attach_waiter(MR_STM_Var *var, MR_ThreadId tid,
    MR_STM_ConditionVar *cvar)
{
    MR_STM_Waiter   *new_waiter;

    new_waiter = MR_GC_NEW_ATTRIB(MR_STM_Waiter, MR_ALLOC_SITE_RUNTIME);
    new_waiter->MR_STM_cond_var = cvar;

    if (var->MR_STM_var_waiters == NULL) {
        var->MR_STM_var_waiters = new_waiter;
        new_waiter->MR_STM_waiter_prev = NULL;
        new_waiter->MR_STM_waiter_next = NULL;
    } else {
        new_waiter->MR_STM_waiter_prev = NULL;
        new_waiter->MR_STM_waiter_next = var->MR_STM_var_waiters;
        var->MR_STM_var_waiters->MR_STM_waiter_prev = new_waiter;
        var->MR_STM_var_waiters = new_waiter;
    }
}
Пример #6
0
MR_Dlist *
MR_dlist_addtail(MR_Dlist *list, const void *data)
{
    MR_Dlist    *item;

    if (list == NULL) {
        list = MR_dlist_makelist0();
    }

    item = MR_GC_NEW_ATTRIB(MR_Dlist, MR_ALLOC_SITE_RUNTIME);
    MR_dlist_data(item) = data;
    MR_dlist_length_field(list)++;

    // Item's pointers.
    MR_dlist_next(item) = list;
    MR_dlist_prev(item) = MR_dlist_prev(list);
    // Neighbours' pointers.
    MR_dlist_next(MR_dlist_prev(item)) = item;
    MR_dlist_prev(MR_dlist_next(item)) = item;

    return list;
}