Skip to content

Commit

Permalink
kernel: trying fix mem leaks
Browse files Browse the repository at this point in the history
  • Loading branch information
james-d-mitchell committed Sep 12, 2023
1 parent c4fb7e2 commit 85dee8d
Show file tree
Hide file tree
Showing 7 changed files with 163 additions and 22 deletions.
8 changes: 3 additions & 5 deletions etc/tst-local-vars.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#!/usr/bin/env python3
"""
TODO
This simple script adds the local variables used in a GAP tst file to the top
of the file.
"""
import os
import re
Expand All @@ -24,10 +25,7 @@ def main():
lvars.extend([x.group(1) for x in re.finditer(pattern1, lines)])
lvars.extend([x.group(1) for x in re.finditer(pattern2, lines)])
lvars = ", ".join(sorted([*{*lvars}]))
lvars = [
x if x[-1] != "," else x[:-1]
for x in textwrap.wrap(lvars, width=72)
]
lvars = [x if x[-1] != "," else x[:-1] for x in textwrap.wrap(lvars, width=72)]
lvars = [""] + ["#@local " + x for x in lvars]
lines = lines.split("\n")
pos = next(i for i in range(len(lines)) if "START_TEST" in lines[i])
Expand Down
50 changes: 50 additions & 0 deletions etc/tst-unbind-local-vars.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#!/usr/bin/env python3
"""
This simple script adds the "Unbind" statements to the end of GAP tst file of
the file.
"""
import os
import re
import sys
import textwrap

import yaml
from bs4 import BeautifulSoup


def main():
if sys.version_info[0] < 3:
raise Exception("Python 3 is required")
args = sys.argv[1:]
pattern1 = re.compile(r"(\w+)\s*:=")
pattern2 = re.compile(r"for (\w+) in")
for fname in args:
lvars = []
with open(fname, "r") as f:
lines = f.read()
lvars.extend([x.group(1) for x in re.finditer(pattern1, lines)])
lvars.extend([x.group(1) for x in re.finditer(pattern2, lines)])
lvars = sorted([*{*lvars}])
lvars = [
"# Unbind local variables, auto-generated by etc/tst-unbind-local-vars.py"
] + [f"gap> Unbind({lvar});" for lvar in lvars]
lvars.append("")
lines = lines.split("\n")
pos1 = next(i for i in range(len(lines)) if "STOP_TEST" in lines[i]) - 1
try:
pos0 = next(
i
for i in range(len(lines))
if "etc/tst-unbind-local-vars.py" in lines[i]
)
except StopIteration:
pos0 = pos1
lines = lines[:pos0] + lvars + lines[pos1:]
lines = "\n".join(lines)
with open(fname, "w") as f:
print(f"Writing local variables to {fname}...")
f.write(lines)


if __name__ == "__main__":
main()
23 changes: 19 additions & 4 deletions gapbind14/include/gapbind14/gapbind14.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@
#include <utility> // for make_pair
#include <vector> // for vector

#include <iostream> // for std::cout

#include "gap_include.hpp" // for Obj etc
#include "tame_free_fn.hpp" // for tame free functions
#include "tame_mem_fn.hpp" // for tame member functions
Expand Down Expand Up @@ -114,6 +116,7 @@ namespace gapbind14 {
////////////////////////////////////////////////////////////////////////
// Helper functions
////////////////////////////////////////////////////////////////////////
extern int64_t count; // TODO delete

namespace detail {

Expand Down Expand Up @@ -187,6 +190,9 @@ namespace gapbind14 {
: SubtypeBase(nm, sbtyp) {}

void free(Obj o) override {
static_assert(IsGapBind14Type<T>::value,
"template parameter T must satisfy IsGapbind14Type<T>");
GAPBIND14_ASSERT(obj_subtype(o) == module().subtype<T>());
delete detail::obj_cpp_ptr<T>(o);
}
};
Expand Down Expand Up @@ -214,12 +220,20 @@ namespace gapbind14 {
_subtypes(),
_type_to_subtype() {}

Module(Module const&) = delete;
Module(Module&&) = delete;
Module(Module const&) = delete;
Module(Module&&) = delete;
Module& operator=(Module const&) = delete;
Module& operator=(Module&&) = delete;
Module& operator=(Module&&) = delete;

~Module() = default;
// TODO to cpp file
~Module() {
clear();
for (auto* subtype : _subtypes) {
delete subtype;
}
std::cout << "Total remaining allocations at Module destruction = "
<< count << "\n";
}

void clear();

Expand Down Expand Up @@ -343,6 +357,7 @@ namespace gapbind14 {
using cpp_type = T;

Obj operator()(T* ptr) const {
count++;
Obj o = NewBag(T_GAPBIND14_OBJ, 2 * sizeof(Obj));
ADDR_OBJ(o)[0] = reinterpret_cast<Obj>(module().subtype<T>());
ADDR_OBJ(o)[1] = reinterpret_cast<Obj>(ptr);
Expand Down
32 changes: 25 additions & 7 deletions gapbind14/src/gapbind14.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@

#include "gapbind14/gapbind14.hpp"

#include <stdio.h> // for fprintf, stderr
#include <string.h> // for memcpy, strchr, strrchr
//
#include <stdio.h> // for fprintf, stderr
#include <string.h> // for memcpy, strchr, strrchr

#include <unordered_set> // for unordered_set, unordered_set<>::iterator

#include "gapbind14/gap_include.hpp" // for Obj etc
Expand All @@ -29,7 +29,8 @@
{ #name, nparam, params, (GVarFunc) name, srcfile ":Func" #name }

namespace gapbind14 {
UInt T_GAPBIND14_OBJ = 0;
int64_t count = 0;
UInt T_GAPBIND14_OBJ = 0;

namespace detail {
std::unordered_map<std::string, void (*)()> &init_funcs() {
Expand Down Expand Up @@ -94,9 +95,24 @@ namespace gapbind14 {
// Module implementations

void Module::clear() {
for (auto &func : _funcs) {
delete func.name;
if (func.nargs != 0) {
delete func.args;
}
delete func.cookie;
}
_funcs.clear();
for (auto &funcs : _mem_funcs) {
funcs.clear();

for (auto &vec : _mem_funcs) {
for (auto &func : vec) {
delete func.name;
if (func.nargs != 0) {
delete func.args;
}
delete func.cookie;
}
vec.clear();
}
}

Expand Down Expand Up @@ -151,6 +167,8 @@ namespace gapbind14 {
void TGapBind14ObjCleanFunc(Obj o) {}

void TGapBind14ObjFreeFunc(Obj o) {
count--;
std::cout << "Total remaining allocations = " << count << std::endl;
module().free(o);
}

Expand Down Expand Up @@ -266,7 +284,7 @@ namespace gapbind14 {
first_call = false;
InitGVarFuncsFromTable(GVarFuncs);
}
auto & m = module();
auto &m = module();
StructGVarFunc const *tab = m.funcs();

// init functions from m in the record named name
Expand Down
45 changes: 45 additions & 0 deletions tst/standard/attributes/homomorph.tst
Original file line number Diff line number Diff line change
Expand Up @@ -1079,6 +1079,51 @@ gap> hom2 := SemigroupHomomorphismByImages(S, S, GeneratorsOfSemigroup(S),
gap> hom1 = hom2;
false
# Unbind local variables, auto-generated by etc/tst-unbind-local-vars.py
gap> Unbind(BruteForceHomoCheck);
gap> Unbind(BruteForceInverseCheck);
gap> Unbind(BruteForceIsoCheck);
gap> Unbind(F);
gap> Unbind(J);
gap> Unbind(K);
gap> Unbind(S);
gap> Unbind(T);
gap> Unbind(U);
gap> Unbind(V);
gap> Unbind(acting);
gap> Unbind(cong);
gap> Unbind(congs);
gap> Unbind(g);
gap> Unbind(gens);
gap> Unbind(gens1);
gap> Unbind(gens2);
gap> Unbind(gens3);
gap> Unbind(gensS);
gap> Unbind(gensT);
gap> Unbind(gensU);
gap> Unbind(gensV);
gap> Unbind(h);
gap> Unbind(hom);
gap> Unbind(hom1);
gap> Unbind(hom1bf);
gap> Unbind(hom1bfbi);
gap> Unbind(hom2);
gap> Unbind(hom3);
gap> Unbind(images);
gap> Unbind(images1);
gap> Unbind(images2);
gap> Unbind(images3);
gap> Unbind(imgs);
gap> Unbind(imgs2);
gap> Unbind(inv);
gap> Unbind(iso);
gap> Unbind(j);
gap> Unbind(map);
gap> Unbind(relations);
gap> Unbind(x);
gap> Unbind(y);
gap> Unbind(z);
#
gap> SEMIGROUPS.StopTest();
gap> STOP_TEST("Semigroups package: standard/attributes/homomorph.tst");
24 changes: 19 additions & 5 deletions tst/standard/semigroups/semifp.tst
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
##
#############################################################################
##

## We don't use local variables in this test file because it doesn't play nice
## with AssignGeneratorVariables, which is used repeatedly here.

gap> START_TEST("Semigroups package: standard/semigroups/semifp.tst");
gap> LoadPackage("semigroups", false);;

Expand Down Expand Up @@ -2666,23 +2670,33 @@ true
gap> IsSubsemigroupOfFpMonoid(Range(map));
true
# SEMIGROUPS_UnbindVariables
gap> Unbind(a);
gap> Unbind(b);
# Unbind local variables, auto-generated by etc/tst-unbind-local-vars.py
gap> Unbind(BruteForceInverseCheck);
gap> Unbind(BruteForceIsoCheck);
gap> Unbind(f);
gap> Unbind(F);
gap> Unbind(G);
gap> Unbind(LoopIterator);
gap> Unbind(Noop);
gap> Unbind(R);
gap> Unbind(S);
gap> Unbind(T);
gap> Unbind(TestEnumerator);
gap> Unbind(TestIterator);
gap> Unbind(a);
gap> Unbind(b);
gap> Unbind(f);
gap> Unbind(factorizable);
gap> Unbind(inv);
gap> Unbind(iso);
gap> Unbind(len);
gap> Unbind(map);
gap> Unbind(rels);
gap> Unbind(s);
gap> Unbind(tst);
gap> Unbind(valid);
gap> Unbind(w);
gap> Unbind(x);
gap> Unbind(y);
#
gap> SEMIGROUPS.StopTest();
gap> STOP_TEST("Semigroups package: standard/semigroups/semifp.tst");
3 changes: 2 additions & 1 deletion tst/standard/tools/display.tst
Original file line number Diff line number Diff line change
Expand Up @@ -1025,7 +1025,8 @@ gap> TikzRightCayleyDigraph(S);
Error, no method found! For debugging hints type ?Recovery from NoMethodFound
Error, no 2nd choice method found for `TikzString' on 1 arguments

# SEMIGROUPS_UnbindVariables
# Unbind local variables, auto-generated by etc/tst-unbind-local-vars.py
gap> Unbind(S);
gap> Unbind(x);
gap> Unbind(y);

Expand Down

0 comments on commit 85dee8d

Please sign in to comment.