Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/GAP/hpcgap/extern/gc/   (Algebra von RWTH Aachen Version 4.15.1©)  Datei vom 18.9.2025 mit Größe 4 kB image not shown  

Quelle  fnlz_mlc.c   Sprache: C

 
/*
 * Copyright (c) 2011 by Hewlett-Packard Company.  All rights reserved.
 *
 * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
 * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
 *
 * Permission is hereby granted to use or copy this program
 * for any purpose,  provided the above notices are retained on all copies.
 * Permission to modify the code and to distribute modified code is granted,
 * provided the above notices are retained, and a notice that the code was
 * modified is included with the above copyright notice.
 *
 */


#include "private/gc_priv.h"

#ifdef ENABLE_DISCLAIM

#include "gc_disclaim.h"
#include "gc_inline.h" /* for GC_malloc_kind */
#include "private/dbg_mlc.h" /* for oh type */

#if defined(KEEP_BACK_PTRS) || defined(MAKE_BACK_GRAPH)
  /* The first bit is already used for a debug purpose. */
define FINALIZER_CLOSURE_FLAG 0x2
#else
define FINALIZER_CLOSURE_FLAG 0x1
#endif

STATIC int GC_CALLBACK GC_finalized_disclaim(void *obj)
{
#   ifdef AO_HAVE_load
        word fc_word = (word)AO_load((volatile AO_t *)obj);
#   else
        word fc_word = *(word *)obj;
#   endif

    if ((fc_word & FINALIZER_CLOSURE_FLAG) != 0) {
       /* The disclaim function may be passed fragments from the        */
       /* free-list, on which it should not run finalization.           */
       /* To recognize this case, we use the fact that the first word   */
       /* on such fragments is always multiple of 4 (a link to the next */
       /* fragment, or NULL).  If it is desirable to have a finalizer   */
       /* which does not use the first word for storing finalization    */
       /* info, GC_reclaim_with_finalization must be extended to clear  */
       /* fragments so that the assumption holds for the selected word. */
        const struct GC_finalizer_closure *fc
                        = (struct GC_finalizer_closure *)(fc_word
                                        & ~(word)FINALIZER_CLOSURE_FLAG);
        GC_ASSERT(!GC_find_leak);
        (*fc->proc)((word *)obj + 1, fc->cd);
    }
    return 0;
}

GC_API void GC_CALL GC_init_finalized_malloc(void)
{
    DCL_LOCK_STATE;

    GC_init();  /* In case it's not already done.       */
    LOCK();
    if (GC_finalized_kind != 0) {
        UNLOCK();
        return;
    }

    /* The finalizer closure is placed in the first word in order to    */
    /* use the lower bits to distinguish live objects from objects on   */
    /* the free list.  The downside of this is that we need one-word    */
    /* offset interior pointers, and that GC_base does not return the   */
    /* start of the user region.                                        */
    GC_register_displacement_inner(sizeof(word));

    /* And, the pointer to the finalizer closure object itself is       */
    /* displaced due to baking in this indicator.                       */
    GC_register_displacement_inner(FINALIZER_CLOSURE_FLAG);
    GC_register_displacement_inner(sizeof(oh) + FINALIZER_CLOSURE_FLAG);

    GC_finalized_kind = GC_new_kind_inner(GC_new_free_list_inner(),
                                          GC_DS_LENGTH, TRUETRUE);
    GC_ASSERT(GC_finalized_kind != 0);
    GC_register_disclaim_proc(GC_finalized_kind, GC_finalized_disclaim, TRUE);
    UNLOCK();
}

GC_API void GC_CALL GC_register_disclaim_proc(int kind, GC_disclaim_proc proc,
                                              int mark_unconditionally)
{
    GC_ASSERT((unsigned)kind < MAXOBJKINDS);
    GC_ASSERT(NONNULL_ARG_NOT_NULL(proc));
    if (!EXPECT(GC_find_leak, FALSE)) {
        GC_obj_kinds[kind].ok_disclaim_proc = proc;
        GC_obj_kinds[kind].ok_mark_unconditionally =
                                        (GC_bool)mark_unconditionally;
    }
}

GC_API GC_ATTR_MALLOC void * GC_CALL GC_finalized_malloc(size_t lb,
                                const struct GC_finalizer_closure *fclos)
{
    void *op;

    GC_ASSERT(GC_finalized_kind != 0);
    GC_ASSERT(NONNULL_ARG_NOT_NULL(fclos));
    GC_ASSERT(((word)fclos & FINALIZER_CLOSURE_FLAG) == 0);
    op = GC_malloc_kind(SIZET_SAT_ADD(lb, sizeof(word)), GC_finalized_kind);
    if (EXPECT(NULL == op, FALSE))
        return NULL;
#   ifdef AO_HAVE_store
        AO_store((volatile AO_t *)op, (AO_t)fclos | FINALIZER_CLOSURE_FLAG);
#   else
        *(word *)op = (word)fclos | FINALIZER_CLOSURE_FLAG;
#   endif
    GC_dirty(op);
    REACHABLE_AFTER_DIRTY(fclos);
    return (word *)op + 1;
}

#endif /* ENABLE_DISCLAIM */

100%


¤ Dauer der Verarbeitung: 0.22 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung ist noch experimentell.