OMCompiler/Compiler/Util/GCExt.mo
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /* | ||
| 2 | * This file is part of OpenModelica. | ||
| 3 | * | ||
| 4 | * Copyright (c) 1998-2026, Open Source Modelica Consortium (OSMC), | ||
| 5 | * c/o Linköpings universitet, Department of Computer and Information Science, | ||
| 6 | * SE-58183 Linköping, Sweden. | ||
| 7 | * | ||
| 8 | * All rights reserved. | ||
| 9 | * | ||
| 10 | * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF AGPL VERSION 3 LICENSE OR | ||
| 11 | * THIS OSMC PUBLIC LICENSE (OSMC-PL) VERSION 1.8. | ||
| 12 | * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES | ||
| 13 | * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GNU AGPL | ||
| 14 | * VERSION 3, ACCORDING TO RECIPIENTS CHOICE. | ||
| 15 | * | ||
| 16 | * The OpenModelica software and the OSMC (Open Source Modelica Consortium) | ||
| 17 | * Public License (OSMC-PL) are obtained from OSMC, either from the above | ||
| 18 | * address, from the URLs: | ||
| 19 | * http://www.openmodelica.org or | ||
| 20 | * https://github.com/OpenModelica/ or | ||
| 21 | * http://www.ida.liu.se/projects/OpenModelica, | ||
| 22 | * and in the OpenModelica distribution. | ||
| 23 | * | ||
| 24 | * GNU AGPL version 3 is obtained from: | ||
| 25 | * https://www.gnu.org/licenses/licenses.html#GPL | ||
| 26 | * | ||
| 27 | * This program is distributed WITHOUT ANY WARRANTY; without | ||
| 28 | * even the implied warranty of MERCHANTABILITY or FITNESS | ||
| 29 | * FOR A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH | ||
| 30 | * IN THE BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF OSMC-PL. | ||
| 31 | * | ||
| 32 | * See the full OSMC Public License conditions for more details. | ||
| 33 | * | ||
| 34 | */ | ||
| 35 | |||
| 36 | encapsulated package GCExt | ||
| 37 | |||
| 38 | constant Boolean cellsNeedOwners = false | ||
| 39 | "True where a weak cell needs an explicit owner to stay alive, so `InstNode` | ||
| 40 | copies a record to set and clear one. A constant, so the C compiler folds | ||
| 41 | it and drops both the branch and the rooting call inside it: Boehm keeps | ||
| 42 | the cell alive by tracing, and an owner there would only build the cycle | ||
| 43 | the collector then has to reclaim. The Rust port sets it true -- `GCExt` | ||
| 44 | is hand-written there."; | ||
| 45 | |||
| 46 | ✗ | function gcollect | |
| 47 | external "C" GC_gcollect() annotation(Include="#include <gc.h>", Library = {"omcgc"}); | ||
| 48 | end gcollect; | ||
| 49 | |||
| 50 | ✗ | function gcollectAndUnmap | |
| 51 | external "C" GC_gcollect_and_unmap() annotation(Include="#include <gc.h>", Library = {"omcgc"}); | ||
| 52 | end gcollectAndUnmap; | ||
| 53 | |||
| 54 | ✗ | function enable | |
| 55 | external "C" GC_enable() annotation(Include="#include <gc.h>", Library = {"omcgc"}); | ||
| 56 | end enable; | ||
| 57 | |||
| 58 | ✗ | function disable | |
| 59 | external "C" GC_disable() annotation(Include="#include <gc.h>", Library = {"omcgc"}); | ||
| 60 | end disable; | ||
| 61 | |||
| 62 | ✗ | function free<T> | |
| 63 | input T data; | ||
| 64 | external "C" omc_GC_free_ext(data) annotation(Include=" | ||
| 65 | ✗ | void omc_GC_free_ext(void *data) | |
| 66 | { | ||
| 67 | /* */ | ||
| 68 | ✗ | GC_free(MMC_UNTAGPTR(data)); | |
| 69 | ✗ | } | |
| 70 | ", | ||
| 71 | Library = {"omcgc"}, Documentation(info="<html> | ||
| 72 | <p>GC_free requires \"a pointer to the base of an object\".</p> | ||
| 73 | <p>So the object passed to free must not be allocated by any of the list | ||
| 74 | routines that allocate multiple elements with a single malloc call.</p> | ||
| 75 | <p>Calling GCExt.free is very dangerous. You might be better off trying to | ||
| 76 | set variables to a constant value if you want to GC them. Use this if | ||
| 77 | you are concerned about temporary variables, etc remaining on the stack | ||
| 78 | and not cleared for a long time.</p> | ||
| 79 | </html>")); | ||
| 80 | end free; | ||
| 81 | |||
| 82 | 607811 | function expandHeap | |
| 83 | input Real sz "To avoid the 32-bit signed limit on sizes"; | ||
| 84 | output Boolean success; | ||
| 85 | external "C" success=GC_expand_hp_dbl(sz) annotation(Include="#define GC_expand_hp_dbl(sz) GC_expand_hp(sz)",Library = {"omcgc"}); | ||
| 86 | end expandHeap; | ||
| 87 | |||
| 88 | 140 | function setFreeSpaceDivisor | |
| 89 | input Integer divisor = 3; | ||
| 90 | external "C" GC_set_free_space_divisor(divisor) annotation(Include="#define GC_set_free_space_divisor_int(divisor) GC_set_free_space_divisor(divisor)",Library = {"omcgc"},Documentation(info="<html> | ||
| 91 | <p>NOTE: Do not set <3 as that seems to interfere with parallel threads.</p> | ||
| 92 | </html>")); | ||
| 93 | end setFreeSpaceDivisor; | ||
| 94 | |||
| 95 | ✗ | function getForceUnmapOnGcollect | |
| 96 | output Boolean res; | ||
| 97 | external "C" res=GC_get_force_unmap_on_gcollect() annotation(Include="#include <gc.h>", Library = {"omcgc"}); | ||
| 98 | end getForceUnmapOnGcollect; | ||
| 99 | |||
| 100 | ✗ | function setForceUnmapOnGcollect | |
| 101 | input Boolean forceUnmap; | ||
| 102 | external "C" GC_set_force_unmap_on_gcollect(forceUnmap) annotation(Include="#include <gc.h>", Library = {"omcgc"}); | ||
| 103 | end setForceUnmapOnGcollect; | ||
| 104 | |||
| 105 | 2677 | function setMaxHeapSize | |
| 106 | input Real sz "To avoid the 32-bit signed limit on sizes"; | ||
| 107 | external "C" GC_set_max_heap_size_dbl(sz) annotation(Include="#define GC_set_max_heap_size_dbl(sz) omc_GC_set_max_heap_size((size_t)sz)",Library = {"omcgc"}); | ||
| 108 | end setMaxHeapSize; | ||
| 109 | |||
| 110 | uniontype ProfStats "TODO: Support regular records in the bootstrapped compiler to avoid allocation to return the stats in the GCExt..." | ||
| 111 | record PROFSTATS | ||
| 112 | Integer heapsize_full, free_bytes_full, unmapped_bytes, bytes_allocd_since_gc, allocd_bytes_before_gc, non_gc_bytes, gc_no, markers_m1, bytes_reclaimed_since_gc, reclaimed_bytes_before_gc; | ||
| 113 | end PROFSTATS; | ||
| 114 | end ProfStats; | ||
| 115 | |||
| 116 | function profStatsStr | ||
| 117 | input ProfStats stats; | ||
| 118 | input String head = "GC Profiling Stats: "; | ||
| 119 | input String delimiter = "\n "; | ||
| 120 | output String str; | ||
| 121 | algorithm | ||
| 122 | str := match stats | ||
| 123 | ✗ | case PROFSTATS() then | |
| 124 | head + delimiter + | ||
| 125 | "heapsize_full: " + intString(stats.heapsize_full) + delimiter + | ||
| 126 | "free_bytes_full: " + intString(stats.free_bytes_full) + delimiter + | ||
| 127 | "unmapped_bytes: " + intString(stats.unmapped_bytes) + delimiter + | ||
| 128 | "bytes_allocd_since_gc: " + intString(stats.bytes_allocd_since_gc) + delimiter + | ||
| 129 | "allocd_bytes_before_gc: " + intString(stats.allocd_bytes_before_gc) + delimiter + | ||
| 130 | "total_allocd_bytes: " + intString(stats.bytes_allocd_since_gc+stats.allocd_bytes_before_gc) + delimiter + | ||
| 131 | "non_gc_bytes: " + intString(stats.non_gc_bytes) + delimiter + | ||
| 132 | "gc_no: " + intString(stats.gc_no) + delimiter + | ||
| 133 | "markers_m1: " + intString(stats.markers_m1) + delimiter + | ||
| 134 | "bytes_reclaimed_since_gc: " + intString(stats.bytes_reclaimed_since_gc) + delimiter + | ||
| 135 | "reclaimed_bytes_before_gc: " + intString(stats.reclaimed_bytes_before_gc); | ||
| 136 | end match; | ||
| 137 | end profStatsStr; | ||
| 138 | |||
| 139 | function getProfStats | ||
| 140 | output ProfStats stats; | ||
| 141 | protected | ||
| 142 | Integer heapsize_full, free_bytes_full, unmapped_bytes, bytes_allocd_since_gc, allocd_bytes_before_gc, non_gc_bytes, gc_no, markers_m1, bytes_reclaimed_since_gc, reclaimed_bytes_before_gc; | ||
| 143 | protected | ||
| 144 | 16070 | function GC_get_prof_stats_modelica "Inner, dummy function to preserve the full integer sizes" | |
| 145 | output tuple<Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer> stats; | ||
| 146 | external "C" stats=GC_get_prof_stats_modelica() | ||
| 147 | annotation(Include=" | ||
| 148 | 8035 | static inline modelica_metatype GC_get_prof_stats_modelica() | |
| 149 | { | ||
| 150 | #if ((GC_VERSION_MAJOR == 7) && (GC_VERSION_MINOR >= 5)) || (GC_VERSION_MAJOR >= 8) | ||
| 151 | struct GC_prof_stats_s info; | ||
| 152 | 8035 | GC_get_prof_stats(&info,sizeof(struct GC_prof_stats_s)); | |
| 153 | 16070 | return mmc_mk_box10( | |
| 154 | 0, | ||
| 155 | 8035 | mmc_mk_icon(info.heapsize_full), | |
| 156 | 8035 | mmc_mk_icon(info.free_bytes_full), | |
| 157 | 8035 | mmc_mk_icon(info.unmapped_bytes), | |
| 158 | 8035 | mmc_mk_icon(info.bytes_allocd_since_gc), | |
| 159 | 8035 | mmc_mk_icon(info.allocd_bytes_before_gc), | |
| 160 | 8035 | mmc_mk_icon(info.non_gc_bytes), | |
| 161 | 8035 | mmc_mk_icon(info.gc_no), | |
| 162 | 8035 | mmc_mk_icon(info.markers_m1), | |
| 163 | 8035 | mmc_mk_icon(info.bytes_reclaimed_since_gc), | |
| 164 | 8035 | mmc_mk_icon(info.reclaimed_bytes_before_gc)); | |
| 165 | #else /* GC_prof_stats_s NOT available */ | ||
| 166 | return mmc_mk_box10( | ||
| 167 | 0, | ||
| 168 | mmc_mk_icon(0), | ||
| 169 | mmc_mk_icon(0), | ||
| 170 | mmc_mk_icon(0), | ||
| 171 | mmc_mk_icon(0), | ||
| 172 | mmc_mk_icon(0), | ||
| 173 | mmc_mk_icon(0), | ||
| 174 | mmc_mk_icon(0), | ||
| 175 | mmc_mk_icon(0), | ||
| 176 | mmc_mk_icon(0), | ||
| 177 | mmc_mk_icon(0)); | ||
| 178 | #endif | ||
| 179 | } | ||
| 180 | |||
| 181 | ",Library = {"omcgc"}); | ||
| 182 | end GC_get_prof_stats_modelica; | ||
| 183 | algorithm | ||
| 184 | 8035 | (heapsize_full, free_bytes_full, unmapped_bytes, bytes_allocd_since_gc, allocd_bytes_before_gc, non_gc_bytes, gc_no, markers_m1, bytes_reclaimed_since_gc, reclaimed_bytes_before_gc) := GC_get_prof_stats_modelica(); | |
| 185 | 8035 | stats := PROFSTATS(heapsize_full, free_bytes_full, unmapped_bytes, bytes_allocd_since_gc, allocd_bytes_before_gc, non_gc_bytes, gc_no, markers_m1, bytes_reclaimed_since_gc, reclaimed_bytes_before_gc); | |
| 186 | annotation(Documentation(info="<html> | ||
| 187 | <p>Query GC profiling information.</p> | ||
| 188 | </html>")); | ||
| 189 | end getProfStats; | ||
| 190 | |||
| 191 | annotation(__OpenModelica_Interface="util_datatypes_basic"); | ||
| 192 | end GCExt; | ||
| 193 |