From 884fed62d67c3886dda9b9c6335a39ef39882d72 Mon Sep 17 00:00:00 2001 From: verhaegs Date: Thu, 17 Apr 2008 22:52:45 +0000 Subject: [PATCH] r7595@lvps87-230-33-50 (orig r28343): verhaegs | 2008-04-17 23:42:03 +0200 Added peridbase option. This option for a shared library will allow to generate a different library base based on an id. By default the Task pointer is used so that a library opened at different times in the same task get the same base but another base in another task. git-svn-id: https://svn.aros.org/svn/aros/trunk/AROS@28346 fb15a70f-31f2-0310-bbcc-cdcc74a49acc --- tools/genmodule/config.c | 21 +++- tools/genmodule/config.h | 10 +- tools/genmodule/writeinclibdefs.c | 2 + tools/genmodule/writestart.c | 255 ++++++++++++++++++++++++++------------ 4 files changed, 202 insertions(+), 86 deletions(-) diff --git a/tools/genmodule/config.c b/tools/genmodule/config.c index 82029db538..17cb8afb04 100644 --- a/tools/genmodule/config.c +++ b/tools/genmodule/config.c @@ -485,7 +485,7 @@ static void readsectionconfig(struct config *cfg, struct classinfo *cl, int incl "superclass_field", "residentpri", "options", "sysbase_field", "seglist_field", "rootbase_field", "classptr_field", "classptr_var", "classid", "classdatatype", "beginio_func", "abortio_func", "dispatcher", - "initpri", "type" + "initpri", "type", "getidfunc" }; const unsigned int namenums = sizeof(names)/sizeof(char *); unsigned int namenum; @@ -614,7 +614,7 @@ static void readsectionconfig(struct config *cfg, struct classinfo *cl, int incl { static const char *optionnames[] = { - "noautolib", "noexpunge", "noresident", "peropenerbase" + "noautolib", "noexpunge", "noresident", "peropenerbase", "peridbase" }; const unsigned int optionnums = sizeof(optionnames)/sizeof(char *); int optionnum; @@ -648,7 +648,12 @@ static void readsectionconfig(struct config *cfg, struct classinfo *cl, int incl cfg->options |= OPTION_NORESIDENT; cfg->firstlvo = 1; break; + case 5: /* peridbase */ + cfg->options |= OPTION_DUPPERID; + /* Fall through */ case 4: /* peropenerbase */ + if (cfg->options & OPTION_DUPBASE) + exitfileerror(20, "Only one option peropenerbase or peridbase allowed\n"); cfg->options |= OPTION_DUPBASE; break; } @@ -817,6 +822,9 @@ static void readsectionconfig(struct config *cfg, struct classinfo *cl, int incl exit(20); } break; + case 26: /* getidfunc */ + cfg->getidfunc = strdup(s); + break; } } else /* Line starts with ## */ @@ -842,7 +850,7 @@ static void readsectionconfig(struct config *cfg, struct classinfo *cl, int incl atend = 1; } } - + /* When not in a class section fill in default values for fields in cfg */ if (!inclass) { @@ -863,6 +871,11 @@ static void readsectionconfig(struct config *cfg, struct classinfo *cl, int incl exitfileerror(20, "sysbase_field specified when no libbasetype is given\n"); if (cfg->seglist_field != NULL && cfg->libbasetype == NULL) exitfileerror(20, "seglist_field specified when no libbasetype is given\n"); + /* rootbase_field only allowed when duplicating base */ + if (cfg->rootbase_field != NULL && !(cfg->options & OPTION_DUPBASE)) + exitfileerror(20, "rootbasefield only valid for option peropenerbase or peridbase\n"); + if (cfg->getidfunc != NULL && !(cfg->options & OPTION_DUPPERID)) + exitfileerror(20, "getidfunc only valid for option peridbase\n"); /* Set default date to current date */ if (cfg->datestring == NULL) @@ -965,7 +978,7 @@ static void readsectionconfig(struct config *cfg, struct classinfo *cl, int incl /* Only specify superclass or superclass_field */ if (cl->superclass != NULL && cl->superclass_field != NULL) exitfileerror(20, "Only specify one of superclass or superclass_field in config section\n"); - + /* Give default value to superclass if it is not specified */ if (cl->superclass == NULL && cl->superclass == NULL) { diff --git a/tools/genmodule/config.h b/tools/genmodule/config.h index d7a4a878a5..de3c8a3cc2 100644 --- a/tools/genmodule/config.h +++ b/tools/genmodule/config.h @@ -1,5 +1,5 @@ /* - Copyright © 1995-2005, The AROS Development Team. All rights reserved. + Copyright © 1995-2008, The AROS Development Team. All rights reserved. Desc: Define the C structure for storing the command line options and the module config data @@ -19,14 +19,15 @@ enum modtype { UNSPECIFIED, LIBRARY, MCC, MUI, MCP, DEVICE, RESOURCE, IMAGE, GAD }; enum optionbit { BIT_NOAUTOLIB, BIT_NOEXPUNGE, BIT_NORESIDENT, - BIT_DUPBASE + BIT_DUPBASE, BIT_DUPPERID }; enum optionflags { OPTION_NOAUTOLIB = 1<%s)\n", cfg->seglist_field ); + if (cfg->getidfunc != NULL) + fprintf(out, "#define GM_GETID ((IPTR)%s())\n", cfg->getidfunc); for (classlistit = cfg->classlist; classlistit != NULL; classlistit = classlistit->next) { int storeptr; diff --git a/tools/genmodule/writestart.c b/tools/genmodule/writestart.c index 14fc2bcc4a..23d8119fe8 100644 --- a/tools/genmodule/writestart.c +++ b/tools/genmodule/writestart.c @@ -145,81 +145,134 @@ static void writedecl(FILE *out, struct config *cfg) "#define GM_SEGLIST_FIELD(lh) (GM_UNIQUENAME(seglist))\n" "#endif\n" ); - if (cfg->options & OPTION_DUPBASE) - fprintf(out, + } + if (cfg->options & OPTION_DUPBASE) + fprintf(out, "#ifndef GM_ROOTBASE_FIELD\n" "static LIBBASETYPEPTR GM_UNIQUENAME(rootbase);\n" "#define GM_ROOTBASE_FIELD(lh) (GM_UNIQUENAME(rootbase))\n" "#endif\n" - ); - for (classlistit = cfg->classlist; classlistit != NULL; classlistit = classlistit->next) - { - /* For the main class basename is the same a the module basename */ - if (strcmp(classlistit->basename, cfg->basename) == 0) - { - if (classlistit->classptr_var == NULL) - { - fprintf(out, - "#if !defined(GM_CLASSPTR_FIELD) && !defined(%s_CLASSPTR_FIELD)\n" - "static APTR GM_UNIQUENAME(%sClass);\n" - "#define GM_CLASSPTR_FIELD(lh) (GM_UNIQUENAME(%sClass))\n" - "#define %s_CLASSPTR_FIELD(lh) (GM_UNIQUENAME(%sClass))\n" - "#define %s_STORE_CLASSPTR 1\n" - "#elif defined(GM_CLASSPTR_FIELD) && !defined(%s_CLASSPTR_FIELD)\n" - "#define %s_CLASSPTR_FIELD(lh) (GM_CLASSPTR_FIELD(lh))\n" - "#elif !defined(GM_CLASSPTR_FIELD) && defined(%s_CLASSPTR_FIELD)\n" - "#define GM_CLASSPTR_FIELD(lh) (%s_CLASSPTR_FIELD(lh))\n" - "#endif\n", - classlistit->basename, - classlistit->basename, - classlistit->basename, - classlistit->basename, classlistit->basename, - classlistit->basename, - classlistit->basename, - classlistit->basename, - classlistit->basename, - classlistit->basename - ); - } - else - { - fprintf(out, - "#define GM_CLASSPTR_FIELD(lh) (%s)\n" - "#define %s_CLASSPTR_FIELD(lh) (%s)\n" - "#define %s_STORE_CLASSPTR 1\n", - classlistit->classptr_var, - classlistit->basename, classlistit->classptr_var, - classlistit->basename - ); - } - } - else - { - if (classlistit->classptr_var == NULL) - { - fprintf(out, - "#if !defined(%s_CLASSPTR_FIELD)\n" - "static APTR GM_UNIQUENAME(%sClass);\n" - "#define %s_CLASSPTR_FIELD(lh) (GM_UNIQUENAME(%sClass))\n" - "#define %s_STORE_CLASSPTR 1\n" - "#endif\n", - classlistit->basename, - classlistit->basename, - classlistit->basename, classlistit->basename, - classlistit->basename - ); - } - else - { - fprintf(out, - "#define %s_CLASSPTR_FIELD(lh) (%s)\n" - "#define %s_STORE_CLASSPTR 1\n", - classlistit->basename, classlistit->classptr_var, - classlistit->basename - ); - } - } - } + ); + if (cfg->options & OPTION_DUPPERID) + fprintf(out, + "#ifndef GM_GETID\n" + "#define GM_GETID ((IPTR)FindTask(NULL))\n" + "#endif\n" + "struct __GM_AVLNode {\n" + " struct AVLNode node;\n" + " struct Library *lh;\n" + " IPTR libid;\n" + " ULONG dupopencount;\n" + "};\n" + "struct __GM_BaseAVL {\n" + " LIBBASETYPE base;\n" + " struct __GM_AVLNode avlnode;\n" + "};\n" + "static AROS_UFH2(LONG, __GM_CompKey,\n" + " AROS_UFHA(const struct __GM_AVLNode *, gm_avlnode, A0),\n" + " AROS_UFHA(IPTR, libid, A1)\n" + ")\n" + "{\n" + " AROS_USERFUNC_INIT\n" + "\n" + " if (gm_avlnode->libid == libid)\n" + " return (LONG)0;\n" + " else if (gm_avlnode->libid < libid)\n" + " return (LONG)-1;\n" + " else\n" + " return (LONG)1;\n" + "\n" + " AROS_USERFUNC_EXIT\n" + "}\n" + "static AROS_UFH2(LONG, __GM_CompNode,\n" + " AROS_UFHA(const struct __GM_AVLNode *, gm_avlnode1, A0),\n" + " AROS_UFHA(const struct __GM_AVLNode *, gm_avlnode2, A1)\n" + ")\n" + "{\n" + " AROS_USERFUNC_INIT\n" + "\n" + " if (gm_avlnode1->libid == gm_avlnode2->libid)\n" + " return (LONG)0;\n" + " else if (gm_avlnode1->libid < gm_avlnode2->libid)\n" + " return (LONG)-1;\n" + " else\n" + " return (LONG)1;\n" + "\n" + " AROS_USERFUNC_EXIT\n" + "}\n" + "#define LIBBASESIZE sizeof(struct __GM_BaseAVL)\n" + "struct AVLNode *__GM_AVLRoot = NULL;\n" + ); + else + fprintf(out, "#define LIBBASESIZE sizeof(LIBBASETYPE)\n"); + + for (classlistit = cfg->classlist; classlistit != NULL; classlistit = classlistit->next) + { + /* For the main class basename is the same a the module basename */ + if (strcmp(classlistit->basename, cfg->basename) == 0) + { + if (classlistit->classptr_var == NULL) + { + fprintf(out, + "#if !defined(GM_CLASSPTR_FIELD) && !defined(%s_CLASSPTR_FIELD)\n" + "static APTR GM_UNIQUENAME(%sClass);\n" + "#define GM_CLASSPTR_FIELD(lh) (GM_UNIQUENAME(%sClass))\n" + "#define %s_CLASSPTR_FIELD(lh) (GM_UNIQUENAME(%sClass))\n" + "#define %s_STORE_CLASSPTR 1\n" + "#elif defined(GM_CLASSPTR_FIELD) && !defined(%s_CLASSPTR_FIELD)\n" + "#define %s_CLASSPTR_FIELD(lh) (GM_CLASSPTR_FIELD(lh))\n" + "#elif !defined(GM_CLASSPTR_FIELD) && defined(%s_CLASSPTR_FIELD)\n" + "#define GM_CLASSPTR_FIELD(lh) (%s_CLASSPTR_FIELD(lh))\n" + "#endif\n", + classlistit->basename, + classlistit->basename, + classlistit->basename, + classlistit->basename, classlistit->basename, + classlistit->basename, + classlistit->basename, + classlistit->basename, + classlistit->basename, + classlistit->basename + ); + } + else + { + fprintf(out, + "#define GM_CLASSPTR_FIELD(lh) (%s)\n" + "#define %s_CLASSPTR_FIELD(lh) (%s)\n" + "#define %s_STORE_CLASSPTR 1\n", + classlistit->classptr_var, + classlistit->basename, classlistit->classptr_var, + classlistit->basename + ); + } + } + else + { + if (classlistit->classptr_var == NULL) + { + fprintf(out, + "#if !defined(%s_CLASSPTR_FIELD)\n" + "static APTR GM_UNIQUENAME(%sClass);\n" + "#define %s_CLASSPTR_FIELD(lh) (GM_UNIQUENAME(%sClass))\n" + "#define %s_STORE_CLASSPTR 1\n" + "#endif\n", + classlistit->basename, + classlistit->basename, + classlistit->basename, classlistit->basename, + classlistit->basename + ); + } + else + { + fprintf(out, + "#define %s_CLASSPTR_FIELD(lh) (%s)\n" + "#define %s_STORE_CLASSPTR 1\n", + classlistit->basename, classlistit->classptr_var, + classlistit->basename + ); + } + } } /* Write out the defines for the functions of the function table */ @@ -317,6 +370,13 @@ static void writeresident(FILE *out, struct config *cfg) "do {\\\n" " UWORD negsize, possize;\\\n" " UBYTE *negptr = (UBYTE *)lh;\\\n" + ); + if (cfg->options & OPTION_DUPPERID) + fprintf(out, + " struct __GM_AVLNode *avlnode = &((struct __GM_BaseAVL *)lh)->avlnode;\\\n" + " AVL_RemNodeByAddress(&__GM_AVLRoot, (struct AVLNode *)avlnode);\\\n" + ); + fprintf(out, " negsize = ((struct Library *)lh)->lib_NegSize;\\\n" " negptr -= negsize;\\\n" " possize = ((struct Library *)lh)->lib_PosSize;\\\n" @@ -395,7 +455,7 @@ static void writeresident(FILE *out, struct config *cfg) "}\n" "const GM_UNIQUENAME(InitTable) =\n" "{\n" - " sizeof(LIBBASETYPE),\n" + " LIBBASESIZE,\n" " &GM_UNIQUENAME(FuncTable)[0],\n" " NULL,\n" " (APTR)GM_UNIQUENAME(InitLib)\n" @@ -518,7 +578,7 @@ static void writeinitlib(FILE *out, struct config *cfg) { fprintf(out, "\n" - " FreeMem(mem, vecsize+sizeof(LIBBASETYPE));\n" + " FreeMem(mem, vecsize+LIBBASESIZE);\n" ); } fprintf(out, @@ -618,12 +678,28 @@ static void writeopenlib(FILE *out, struct config *cfg) "\n" ); } - else + else /* OPTION_DUPBASE */ { fprintf(out, - " struct Library *newlib;\n" - " UWORD possize = ((struct Library *)lh)->lib_PosSize;\n" + " struct Library *newlib = NULL;\n" + " UWORD possize = ((struct Library *)lh)->lib_PosSize;\n" + ); + if (cfg->options & OPTION_DUPPERID) + fprintf(out, + " IPTR libid = GM_GETID;\n" + " struct __GM_AVLNode *avlnode;\n" + "\n" + " avlnode = (struct __GM_AVLNode *)AVL_FindNode(__GM_AVLRoot, (AVLKey)libid, (AVLKEYCOMP)__GM_CompKey);\n" + " if (avlnode != NULL)\n" + " {\n" + " newlib = avlnode->lh;\n" + " avlnode->dupopencount++;\n" + " }\n" + ); + fprintf(out, "\n" + " if (newlib == NULL)\n" + " {\n" " newlib = MakeLibrary(GM_UNIQUENAME(InitTable).FuncTable,\n" " GM_UNIQUENAME(InitTable).DataTable,\n" " NULL,\n" @@ -631,9 +707,20 @@ static void writeopenlib(FILE *out, struct config *cfg) " (BPTR)NULL\n" " );\n" " if (newlib == NULL)\n" - " return 0;\n" + " return NULL;\n" "\n" " CopyMem(lh, newlib, possize);\n" + ); + if (cfg->options & OPTION_DUPPERID) + fprintf(out, + " avlnode = &((struct __GM_BaseAVL *)newlib)->avlnode;\n" + " avlnode->lh = newlib;\n" + " avlnode->libid = libid;\n" + " avlnode->dupopencount = 1;\n" + " AVL_AddNode((struct AVLNode **)&__GM_AVLRoot, (struct AVLNode *)avlnode, (AVLNODECOMP)__GM_CompNode);\n" + ); + fprintf(out, + " }\n" "\n" " if ( set_call_libfuncs(SETNAME(OPENLIB), 1, 1, newlib) )\n" " {\n" @@ -695,11 +782,21 @@ static void writecloselib(FILE *out, struct config *cfg) else { fprintf(out, + " set_call_libfuncs(SETNAME(CLOSELIB), -1, 0, lh);\n" " if (lh != GM_ROOTBASE_FIELD(lh))\n" " {\n" " LIBBASETYPEPTR rootbase = GM_ROOTBASE_FIELD(lh);\n" - " set_call_libfuncs(SETNAME(CLOSELIB), -1, 0, lh);\n" - " __freebase(lh);\n" + ); + if (cfg->options & OPTION_DUPPERID) + fprintf(out, + " struct __GM_AVLNode *avlnode = &((struct __GM_BaseAVL *)lh)->avlnode;\n" + " avlnode->dupopencount--;\n" + " if (avlnode->dupopencount == 0)\n" + " __freebase(lh);\n" + ); + else + fprintf(out, " __freebase(lh);\n"); + fprintf(out, " lh = rootbase;\n" " }\n" " ((struct Library *)lh)->lib_OpenCnt--;\n" -- 2.11.4.GIT