Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Eliminate Tcl_Obj usage by pages object #25

Merged
merged 2 commits into from
Jun 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
2024-06-07 Konstantin Kushnir <[email protected]>
* Thread support preparation: eliminate Tcl_Obj usage by pages object

2024-06-06 Konstantin Kushnir <[email protected]>
* Bumped version to 1.7.0

Expand Down
5 changes: 4 additions & 1 deletion configure
Original file line number Diff line number Diff line change
Expand Up @@ -8729,7 +8729,7 @@ if test ${USECPAGES} = yes; then
COOKFS_PKGCONFIG_USECPAGES=1
COOKFS_PKGCONFIG_FEATURE_ASIDE=1

vars="pages.c pagesCompr.c pagesCmd.c"
vars="pageObj.c pages.c pagesCompr.c pagesCmd.c"
for i in $vars; do
case $i in
\$*)
Expand Down Expand Up @@ -8805,6 +8805,9 @@ if test ${USECPAGES} = yes; then
printf "%s\n" "#define COOKFS_USEBZ2 1" >>confdefs.h

COOKFS_PKGCONFIG_USEBZ2=1
# This is required to compile bz2 sources.
# See: https://github.com/Perl/perl5/issues/17528
#TEA_ADD_CFLAGS([-Wno-implicit-fallthrough])
else
COOKFS_PKGCONFIG_USEBZ2=0
fi
Expand Down
5 changes: 4 additions & 1 deletion configure.in
Original file line number Diff line number Diff line change
Expand Up @@ -146,14 +146,17 @@ if test ${USECPAGES} = yes; then
AC_DEFINE(COOKFS_USECPAGES)
COOKFS_PKGCONFIG_USECPAGES=1
COOKFS_PKGCONFIG_FEATURE_ASIDE=1
TEA_ADD_SOURCES([pages.c pagesCompr.c pagesCmd.c])
TEA_ADD_SOURCES([pageObj.c pages.c pagesCompr.c pagesCmd.c])

# enable bz2 files only if pages are handled using C
if test ${USEBZ2} = yes; then
BUILDCCODE=yes
TEA_ADD_SOURCES([bzip2/blocksort.c bzip2/huffman.c bzip2/crctable.c bzip2/randtable.c bzip2/compress.c bzip2/decompress.c bzip2/bzlib.c])
AC_DEFINE(COOKFS_USEBZ2)
COOKFS_PKGCONFIG_USEBZ2=1
# This is required to compile bz2 sources.
# See: https://github.com/Perl/perl5/issues/17528
#TEA_ADD_CFLAGS([-Wno-implicit-fallthrough])
else
COOKFS_PKGCONFIG_USEBZ2=0
fi
Expand Down
1 change: 1 addition & 0 deletions generic/cookfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
#include "hashes.h"

#ifdef COOKFS_USECPAGES
#include "pageObj.h"
#include "pages.h"
#include "pagesCmd.h"
#include "pagesCompr.h"
Expand Down
4 changes: 2 additions & 2 deletions generic/fsindexCmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ static int CookfsRegisterFsindexObjectCmd(ClientData clientData, Tcl_Interp *int

/* import fsindex from specified data if specified, otherwise create new fsindex */
if (objc == 2) {
i = Cookfs_FsindexFromObject(interp, NULL, objv[1]);
i = Cookfs_FsindexFromTclObj(interp, NULL, objv[1]);
CookfsLog(printf("CookfsRegisterFsindexObjectCmd: created fsindex from obj [%p]", (void *)i));
} else {
i = Cookfs_FsindexInit(interp, NULL);
Expand Down Expand Up @@ -420,7 +420,7 @@ static int CookfsFsindexCmdImport(Cookfs_Fsindex *fsIndex, Tcl_Interp *interp, i
return TCL_ERROR;
}

Cookfs_Fsindex *result = Cookfs_FsindexFromObject(interp, fsIndex, objv[2]);
Cookfs_Fsindex *result = Cookfs_FsindexFromTclObj(interp, fsIndex, objv[2]);

return (result == NULL ? TCL_ERROR : TCL_OK);
}
Expand Down
76 changes: 54 additions & 22 deletions generic/fsindexIO.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,22 @@ static int CookfsFsindexImportMetadata(Cookfs_Fsindex *fsIndex, unsigned char *b
* subdirectories are inlined completely and recursively
*/

#ifdef COOKFS_USECPAGES

Cookfs_PageObj Cookfs_FsindexToPageObj(Cookfs_Fsindex *fsindex) {
Cookfs_PageObj rc;
Tcl_Obj *obj = Cookfs_FsindexToObject(fsindex);
if (obj != NULL) {
Tcl_IncrRefCount(obj);
rc = Cookfs_PageObjNewFromByteArray(obj);
Tcl_DecrRefCount(obj);
} else {
rc = NULL;
}
return rc;
}

#endif /* COOKFS_USECPAGES */

/*
*----------------------------------------------------------------------
Expand Down Expand Up @@ -102,17 +118,28 @@ Cookfs_Fsindex *Cookfs_FsindexFromPages(Tcl_Interp *interp, Cookfs_Fsindex *fsin
Cookfs_Fsindex *rc;

CookfsLog(printf("Cookfs_FsindexFromPages: get index data from pages..."));
Tcl_Obj *indexDataObj = Cookfs_PagesGetIndex(pages);
Tcl_IncrRefCount(indexDataObj);
Cookfs_PageObj indexDataObj = Cookfs_PagesGetIndex(pages);

Tcl_Size indexDataLen;
Tcl_GetByteArrayFromObj(indexDataObj, &indexDataLen);
CookfsLog(printf("Cookfs_FsindexFromPages: got index data %"
TCL_SIZE_MODIFIER "d bytes", indexDataLen));
if (indexDataObj == NULL) {
CookfsLog(printf("Cookfs_FsindexFromPages: got NULL as index data"));
indexDataLen = 0;
} else {
Cookfs_PageObjIncrRefCount(indexDataObj);
indexDataLen = Cookfs_PageObjSize(indexDataObj);
CookfsLog(printf("Cookfs_FsindexFromPages: got index data %"
TCL_SIZE_MODIFIER "d bytes", indexDataLen));
// If data is empty, then free the object now as at the end we
// will release the object only if indexDataLen > 0
if (!indexDataLen) {
Cookfs_PageObjDecrRefCount(indexDataObj);
}
}

if (indexDataLen) {
CookfsLog(printf("Cookfs_FsindexFromPages: import from the object..."));
rc = Cookfs_FsindexFromObject(interp, fsindex, indexDataObj);
rc = Cookfs_FsindexFromPageObj(interp, fsindex, indexDataObj);
Cookfs_PageObjDecrRefCount(indexDataObj);
} else {
if (fsindex == NULL) {
CookfsLog(printf("Cookfs_FsindexFromPages: create a new clean index"));
Expand All @@ -124,20 +151,30 @@ Cookfs_Fsindex *Cookfs_FsindexFromPages(Tcl_Interp *interp, Cookfs_Fsindex *fsin
}
}

Tcl_DecrRefCount(indexDataObj);
CookfsLog(printf("Cookfs_FsindexFromPages: return [%p]", (void *)rc));
return rc;
}

Cookfs_Fsindex *Cookfs_FsindexFromPageObj(Tcl_Interp *interp, Cookfs_Fsindex *fsindex, Cookfs_PageObj o) {
return Cookfs_FsindexFromBytes(interp, fsindex, o, Cookfs_PageObjSize(o));
}

#endif /* COOKFS_USECPAGES */

Cookfs_Fsindex *Cookfs_FsindexFromTclObj(Tcl_Interp *interp, Cookfs_Fsindex *fsindex, Tcl_Obj *o) {
Tcl_Size size;
unsigned char *bytes = Tcl_GetByteArrayFromObj(o, &size);
return Cookfs_FsindexFromBytes(interp, fsindex, bytes, size);

}

/*
*----------------------------------------------------------------------
*
* Cookfs_FsindexFromObject --
* Cookfs_FsindexFromBytes --
*
* Imports fsindex information from byte array object
* storing platform-independant binary data
* Imports fsindex information from raw buffer storing platform-independant
* binary data
*
* Results:
* Pointer to imported Cookfs_Fsindex; NULL in case of import error
Expand All @@ -148,10 +185,8 @@ Cookfs_Fsindex *Cookfs_FsindexFromPages(Tcl_Interp *interp, Cookfs_Fsindex *fsin
*----------------------------------------------------------------------
*/

Cookfs_Fsindex *Cookfs_FsindexFromObject(Tcl_Interp *interp, Cookfs_Fsindex *fsindex, Tcl_Obj *o) {
Tcl_Size objLength;
Cookfs_Fsindex *Cookfs_FsindexFromBytes(Tcl_Interp *interp, Cookfs_Fsindex *fsindex, unsigned char *bytes, Tcl_Size size) {
int i;
unsigned char *bytes;
Cookfs_Fsindex *result;

CookfsLog(printf("Cookfs_FsindexFromObject - BEGIN"))
Expand All @@ -169,10 +204,7 @@ Cookfs_Fsindex *Cookfs_FsindexFromObject(Tcl_Interp *interp, Cookfs_Fsindex *fsi
return NULL;
}

/* get bytes from binary data and check if they contain proper header */
bytes = Tcl_GetByteArrayFromObj(o, &objLength);

if (objLength < COOKFS_FSINDEX_HEADERLENGTH) {
if (size < COOKFS_FSINDEX_HEADERLENGTH) {
CookfsLog(printf("Cookfs_FsindexFromObject - unable to compare header 1"))
return NULL;
}
Expand All @@ -182,17 +214,17 @@ Cookfs_Fsindex *Cookfs_FsindexFromObject(Tcl_Interp *interp, Cookfs_Fsindex *fsi
}

/* import root entry; import of subdirectories happens recursively */
i = CookfsFsindexImportDirectory(result, result->rootItem, bytes, objLength, 8);
i = CookfsFsindexImportDirectory(result, result->rootItem, bytes, size, 8);

CookfsLog(printf("Cookfs_FsindexFromObject - Import directory done -"
" %d vs %" TCL_SIZE_MODIFIER "d", i, objLength))
if (i < objLength) {
" %d vs %" TCL_SIZE_MODIFIER "d", i, size))
if (i < size) {
// cppcheck-suppress unreadVariable symbolName=i
i = CookfsFsindexImportMetadata(result, bytes, objLength, i);
i = CookfsFsindexImportMetadata(result, bytes, size, i);
}

CookfsLog(printf("Cookfs_FsindexFromObject - Import metadata done -"
" %d vs %" TCL_SIZE_MODIFIER "d", i, objLength))
" %d vs %" TCL_SIZE_MODIFIER "d", i, size))

Cookfs_FsindexResetChangeCount(result);

Expand Down
5 changes: 4 additions & 1 deletion generic/fsindexIO.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@
#ifdef COOKFS_USECFSINDEX

Tcl_Obj *Cookfs_FsindexToObject(Cookfs_Fsindex *fsindex);
Cookfs_Fsindex *Cookfs_FsindexFromObject(Tcl_Interp *interp, Cookfs_Fsindex *fsindex, Tcl_Obj *o);
Cookfs_Fsindex *Cookfs_FsindexFromBytes(Tcl_Interp *interp, Cookfs_Fsindex *fsindex, unsigned char *bytes, Tcl_Size size);
Cookfs_Fsindex *Cookfs_FsindexFromTclObj(Tcl_Interp *interp, Cookfs_Fsindex *fsindex, Tcl_Obj *o);
#ifdef COOKFS_USECPAGES
Cookfs_PageObj Cookfs_FsindexToPageObj(Cookfs_Fsindex *fsindex);
Cookfs_Fsindex *Cookfs_FsindexFromPageObj(Tcl_Interp *interp, Cookfs_Fsindex *fsindex, Cookfs_PageObj o);
Cookfs_Fsindex *Cookfs_FsindexFromPages(Tcl_Interp *interp, Cookfs_Fsindex *fsindex, Cookfs_Pages *pages);
#endif /* COOKFS_USECPAGES */

Expand Down
38 changes: 38 additions & 0 deletions generic/pageObj.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* pageObj.c
*
* Provides functions creating and managing a page object
*
* (c) 2024 Konstantin Kushnir
*/

#include "cookfs.h"

Cookfs_PageObj Cookfs_PageObjAlloc(Tcl_Size size) {
// Align physical page size to 16 bytes. This will be usefull for
// AES encryption.
Tcl_Size bufferSize = size + (16 - (size % 16));
CookfsLog(printf("Cookfs_PageObjAlloc: want bytes %" TCL_SIZE_MODIFIER "d"
" alloc %" TCL_SIZE_MODIFIER "d bytes", size, bufferSize));
Cookfs_PageObj p = ckalloc(bufferSize + sizeof(Cookfs_PageObjStruct));
if (p != NULL) {
Cookfs_PageObjStruct *s = (Cookfs_PageObjStruct *)p;
s->bufferSize = bufferSize;
s->effectiveSize = size;
s->refCount = 0;
p += sizeof(Cookfs_PageObjStruct);
}
CookfsLog(printf("Cookfs_PageObjAlloc: return %p", (void *)p));
return p;
}

Cookfs_PageObj Cookfs_PageObjNewFromByteArray(Tcl_Obj *obj) {
Tcl_Size size;
unsigned char *bytes = Tcl_GetByteArrayFromObj(obj, &size);
Cookfs_PageObj rc = Cookfs_PageObjAlloc(size);
if (rc != NULL) {
memcpy(rc, bytes, size);
}
return rc;
}

59 changes: 59 additions & 0 deletions generic/pageObj.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
(c) 2024 Konstantin Kushnir
*/

#ifndef COOKFS_PAGEOBJ_H
#define COOKFS_PAGEOBJ_H 1

typedef unsigned char* Cookfs_PageObj;

typedef struct Cookfs_PageObjStruct {
Tcl_Size bufferSize;
Tcl_Size effectiveSize;
int refCount;
} Cookfs_PageObjStruct;

/*
#define Cookfs_PageObjIncrRefCount(p) \
((Cookfs_PageObjStruct *)((Cookfs_PageObj)(p) - \
sizeof(Cookfs_PageObjStruct)))->refCount++
*/

#define Cookfs_PageObjIncrRefCount(p) \
{ \
((Cookfs_PageObjStruct *)((Cookfs_PageObj)(p) - \
sizeof(Cookfs_PageObjStruct)))->refCount++; \
CookfsLog(printf("Cookfs_PageObjIncrRefCount: %p", (void *)p)); \
}

/*
#define Cookfs_PageObjDecrRefCount(p) \
{ \
Cookfs_PageObjStruct *tmp = (Cookfs_PageObjStruct *)( \
(Cookfs_PageObj)(p) - sizeof(Cookfs_PageObjStruct)); \
if (!(--tmp->refCount)) { ckfree(tmp); } \
}
*/

#define Cookfs_PageObjDecrRefCount(p) \
{ \
CookfsLog(printf("Cookfs_PageObjDecrRefCount: %p", (void *)p)); \
Cookfs_PageObjStruct *tmp = (Cookfs_PageObjStruct *)( \
(Cookfs_PageObj)(p) - sizeof(Cookfs_PageObjStruct)); \
if (!(--tmp->refCount)) { \
ckfree(tmp); \
CookfsLog(printf("Cookfs_PageObjDecrRefCount: release %p", (void *)p)); \
} \
}

#define Cookfs_PageObjSize(p) \
(((Cookfs_PageObjStruct *)((Cookfs_PageObj)(p) - \
sizeof(Cookfs_PageObjStruct)))->effectiveSize)

#define Cookfs_PageObjCopyAsByteArray(p) \
Tcl_NewByteArrayObj(p, Cookfs_PageObjSize(p))

Cookfs_PageObj Cookfs_PageObjAlloc(Tcl_Size size);
Cookfs_PageObj Cookfs_PageObjNewFromByteArray(Tcl_Obj *obj);

#endif /* COOKFS_PAGEOBJ_H */
Loading