NO

Author Topic: reanimate a perished fish  (Read 29488 times)

czerny

  • Guest
Re: reanimate a perished fish
« Reply #30 on: March 30, 2013, 01:56:25 PM »
now the header file is much longer.
Convert that file to ANSI, that program generate UNICODE file.
I have done it before. But even so the difference is 91K to 137K.
Quote
It's very difficult to understand, what you have changed (and way).
Modified ComTypeLibWorker code generate that header.
I will have a look.

btw. ComTypeLibList produces the same empty struct with 'msado20.tlb'.
AdoText4 works for me.
Where do you find the error list?

czerny

czerny

  • Guest
Re: reanimate a perished fish
« Reply #31 on: May 18, 2013, 12:27:38 PM »
I have made a little excerpt from the pool implementation of c2lib, just to get the idea. In the original there is much more.
jj2007: I want to get back to our discussion about a circular buffer.

Have you inspected the pool example (pool.zip) above?

czerny

  • Guest
Re: reanimate a perished fish
« Reply #32 on: May 18, 2013, 02:53:24 PM »
This is a MS example in using WMI translated to Pelles C.

Offline jj2007

  • Member
  • *
  • Posts: 536
Re: reanimate a perished fish
« Reply #33 on: May 18, 2013, 06:05:44 PM »
jj2007: I want to get back to our discussion about a circular buffer.
Have you inspected the pool example (pool.zip) above?

I've had a look. From what I see (and apologies if my eyes are not very good at understanding C ;))...
void *PoolMalloc(POOL P, size_t n)
..
   ptr = malloc(n);

... you are using malloc for every slot. This is different from my MasmBasic pool, which allocates one 640000 bytes buffer from which every user picks the next available slot until the end is reached, and at this point the next available one is slot #1 again. And previous content gets merciless discarded.

Your version, if I understand it correctly, provides permanent slots, but it uses malloc for each slot. That is more flexible but malloc is slow, of course.

My version is blazing fast for many small allocations (say: 10-20 cycles to get a pointer to an empty buffer) but it is naturally limited to 1. small buffers up to 640/4kB, 2. to allocations that are temporary, e.g. the buffer for a
Print Str$(n), " allocations", CrLf$, "are the limit"
Once it's printed, you don't need it any more.
Similar, you can use
Let MyString=Str$(n)+" allocations"+CrLf$+"are the limit"
and again, Str$() would use a temporary slot in the circular buffer. But MyString is a permanent heapalloc'ed slot.

But I don't want to advertise anything here. What are your intentions, what is your philosophy?

czerny

  • Guest
Re: reanimate a perished fish
« Reply #34 on: May 18, 2013, 07:05:52 PM »
As I wrote, 'pool' is an essential part of c2lib. At first a wanted to discuss alternative memory managment techniques, with the c2lib 'pool' as an example.

In the meantime, due to your understanding of that what a pool is, i was thinking about circular buffers. This was a little excursus.

Now I would like to come back to the original theme.

Offline jj2007

  • Member
  • *
  • Posts: 536
Re: reanimate a perished fish
« Reply #35 on: May 18, 2013, 09:35:51 PM »
At first a wanted to discuss alternative memory managment techniques, with the c2lib 'pool' as an example.

There is some documentation of the 'pool' here:
Quote
Advanced used of pools

So far we have only touched upon pools, and it may not be clear in the examples above why they don't in fact leak memory. There appears to be no deallocation being done, which is quite counter-intuitive to most C programmers!

Pools are collections of related objects (where an "object" is some sort of memory allocation).

I may be wrong, but this sounds as if pools are simply arrays of malloc handles that can "deleted in one go just by calling delete_pool(3)". That makes sense for multi-threaded apps which must clean memory at the end of a thread (although a simple loop freeing all entries in the array of handles could do the job, too).

Re memory managers: Ultrano has invested a lot into this question, google for Ultrano SmallAlloc to see some refs.

P.S.: I've made some simple benchmarks HeapAlloc vs circular buffer, the latter is about a factor 40 faster. Whether that matters in real life apps is another question - one Million MAX_PATH allocations take less than a second on my trusty notebook, HeapFree included.

czerny

  • Guest
Re: reanimate a perished fish
« Reply #36 on: May 19, 2013, 02:11:56 PM »
I may be wrong, but this sounds as if pools are simply arrays of malloc handles ...
No, there is only one malloc (with further reallocs if needed).

Offline DMac

  • Member
  • *
  • Posts: 272
Re: reanimate a perished fish
« Reply #37 on: May 20, 2013, 07:17:06 PM »
Ever since I discovered the simple circular buffer employed by BCX I've used it for any application where I needed to manipulate a lot of strings of arbitrary length.  (One such project is the script generator for POINST wizard which can be downloaded from the Smorgasbordet site.)

Code: [Select]
static LPTSTR BCX_TmpStr(size_t Bites)
{
    static INT StrCnt;
    static LPTSTR StrFunc[2048];
    StrCnt = (StrCnt + 1) & 2047;
    if (StrFunc[StrCnt])
        free(StrFunc[StrCnt]);
    return StrFunc[StrCnt] = (LPTSTR)calloc(Bites + 128, sizeof(TCHAR));
}

Here is the BCX Join() method for easily concatinating any number of substrings that uses the circular buffer.

Code: [Select]
static LPTSTR Join(UINT nStrings, ...)
{
    register int i = nStrings, tmplen = 0;
    register LPTSTR str;
    register LPTSTR strtmp;
    va_list marker;
    va_start(marker, nStrings); // Initialize variable arguments
    while (i-- > 0)
    {
        str = va_arg(marker, LPTSTR);
        tmplen += _tcslen(str);
    }
    strtmp = BCX_TmpStr(tmplen);
    va_end(marker); // Reset variable arguments
    i = nStrings;
    va_start(marker, nStrings); // Initialize variable arguments
    while (i-- > 0)
    {
        str = va_arg(marker, LPTSTR);
        _tcscat(strtmp, str);
    }
    va_end(marker); // Reset variable arguments
    return strtmp;
}

The only thing that one has to remember when using this kind of thing is that all returned strings are temporary.  Any that you want to keep you need to copy to an allocated buffer before they are garbage collected.


No one cares how much you know,
until they know how much you care.

Offline jj2007

  • Member
  • *
  • Posts: 536
Re: reanimate a perished fish
« Reply #38 on: May 20, 2013, 10:47:02 PM »
Nice example, DMac. Can the inputs also come from the circular buffer, as in the example below? How would you code that message box in BCX?

Code: [Select]
include \masm32\MasmBasic\MasmBasic.inc
Init
MsgBox 0, Cat$(String$(11, "*")+CrLf$+Hex$(123h)+"="+Tb$+\
Str$(123h)+CrLf$+Hex$(123)+"="+Tb$+Str$(123)+CrLf$+\
String$(11, "*")), "Hi", MB_OK
Exit
end start

Output:
***********
0123=   291
7B=     123
***********

czerny

  • Guest
Re: reanimate a perished fish
« Reply #39 on: May 20, 2013, 11:09:31 PM »
Ever since I discovered the simple circular buffer employed by BCX I've used it for any application where I needed to manipulate a lot of strings of arbitrary length.
Sorry, I do not see the point.
The circular buffer consist only of pointers. You have one calloc per call.In your example you could replace your BCX_TmpStr with calloc and free after the last loop.

Offline DMac

  • Member
  • *
  • Posts: 272
Re: reanimate a perished fish
« Reply #40 on: May 21, 2013, 03:32:47 AM »
The circular buffer consist only of pointers. You have one calloc per call.In your example you could replace your BCX_TmpStr with calloc and free after the last loop.
True, that wasn't the point.  BCX uses this for many basic style string manipulations so for instance I might do the following:
Code: [Select]
strSCRIPT = Join(3, strSCRIPT, "Append sub strings:",
Left(strPath, i), Right(strPath2, j));
In this case the call to Right will yield a temp string, Left will yield the next, and Join will yield a third comprised of the original plus three appended strings.  Eventually all of these will be freed but I can assemble an entire script easily without worrying about memory leaks and such, even if I am nesting allocations.
No one cares how much you know,
until they know how much you care.

Offline DMac

  • Member
  • *
  • Posts: 272
Re: reanimate a perished fish
« Reply #41 on: May 21, 2013, 03:42:29 AM »
Nice example, DMac. Can the inputs also come from the circular buffer, as in the example below? How would you code that message box in BCX?

Code: [Select]
include \masm32\MasmBasic\MasmBasic.inc
Init
MsgBox 0, Cat$(String$(11, "*")+CrLf$+Hex$(123h)+"="+Tb$+\
Str$(123h)+CrLf$+Hex$(123)+"="+Tb$+Str$(123)+CrLf$+\
String$(11, "*")), "Hi", MB_OK
Exit
end start

Output:
***********
0123=   291
7B=     123
***********


BCX - the basic to C compiler by Kevin Diggins (Mr. BCX) is a basic syntax that gets translated to the C constructs.  So it's not all that differen't than what you have here.

I found it very helpful when I was learning C.  I could type in Basic for something I wanted to do and see how it translated.

Some things, like the circular buffer, I borrowed for a project or two when it made sense.  Mostly for parsers and script generators.
No one cares how much you know,
until they know how much you care.