-4
$\begingroup$

Am I having any chance if I implement a system programming from scratch? I have some ideas. The first is to fix malloc in C. Add a last parameter to all function calls, use LINE and ThreadId and make a hash and if that hash is same it is the same path of code and don't need to malloc twice. We don't need to free anything.. It eases multi-threaded programming much easier.. I thought about multi-threaded, too, we can let function itself malloc and return pointer and we keep it.. I didn't implement it fully yet. But the idea is below in C:

This idea works IF we use each block of memory only in its own thread..

void* Simple_Malloc_AutoFree(size_t Size, char* File, long long line, int m_index)
{
#define Mlk1
    if (123 != IsInit_Mem_AF)
    {
        return NULL;
    }
    //static int i = 0;
    //i++;
    long long l_indx = modfun(line + m_index, 1);
    //printf("%lld, %llu\n", ListofMems0[l_indx].line, l_indx);
//printf("%lld %lld\n",m_index, ListofMems[l_indx].line);
    if (ListofMems0[l_indx].line != -1)
    {

        if (ListofMems0[l_indx].line == line)
        {
            if (TRUE)//ListofMems0[l_indx].threadID == threadID)
            {
                if (ListofMems0[l_indx].Size == Size)
                {

                    if (m_index == ListofMems0[l_indx].m_index)
                        return ListofMems0[l_indx].memory;

                }
                else
                {
                    if (ListofMems0[l_indx].memory != NULL)
                    {
                        if ((ListofMems0[l_indx].memory = realloc(ListofMems0[l_indx].memory, Size)) == NULL)
                            return NULL;
                    }
                    else
                    {
                        if ((ListofMems0[l_indx].memory = malloc(Size)) == NULL)
                            return NULL;
                    }
                    ListofMems0[l_indx].line = line;
                    ListofMems0[l_indx].m_index = m_index;
                    ListofMems0[l_indx].Size = Size;
                    strcpy_s(ListofMems0[l_indx].fileName, 512, File);
                    //ListofMems0[l_indx].threadID = threadID;
                }
            }
        }
        else
        {
            int i = 0;

            for (; i < memoryBlocks; i++)
            {
                if (ListofMems[i].line == -1)
                {
                    ListofMems[i].memory = malloc(Size);
                    ListofMems[i].line = line;
                    ListofMems[i].m_index = m_index;
                    ListofMems[i].Size = Size;
                    strcpy_s(ListofMems[i].fileName, 512, File);
                    //ListofMems[i].threadID = threadID;
                    return ListofMems[i].memory;
                }

                if (strcmp(ListofMems[i].fileName, File) == 0)
                {
                    if (ListofMems[i].line == line)
                    {
                        if (TRUE)//ListofMems[i].threadID == threadID)
                        {
                            if (ListofMems[i].Size == Size)
                            {
                                if (m_index == ListofMems[i].m_index)
                                    return ListofMems[i].memory;
                                else
                                    continue;
                            }
                            else
                            {
                                if (ListofMems[i].memory != NULL)
                                {
                                    if ((ListofMems[i].memory = realloc(ListofMems[i].memory, Size)) == NULL)
                                        return NULL;
                                }
                                else
                                {
                                    if ((ListofMems[i].memory = malloc(Size)) == NULL)
                                        return NULL;
                                }
                                ListofMems[i].line = line;
                                ListofMems[i].m_index = m_index;
                                ListofMems[i].Size = Size;
                                strcpy_s(ListofMems[i].fileName, 512, File);
                                //ListofMems[i].threadID = threadID;
                            }
                        }
                        else
                        {
                            continue;
                        }
                        return ListofMems[i].memory;
                    }
                }
            }
            if (memoryBlocks == i)
            {

                i = 0;
                free(ListofMems[i].memory);
                ListofMems[i].memory = malloc(Size);
                ListofMems[i].line = line;
                ListofMems[i].m_index = m_index;
                ListofMems[i].Size = Size;
                strcpy_s(ListofMems[i].fileName, 512, File);
                //ListofMems[i].threadID = threadID;
                return ListofMems[i].memory;
            }
        }
    }
    else
    {
        static int jk = 0;
        jk++;

        ListofMems0[l_indx].memory = malloc(Size);
        ListofMems0[l_indx].line = line;
        ListofMems0[l_indx].m_index = m_index;
        ListofMems0[l_indx].Size = Size;
        strcpy_s(ListofMems0[l_indx].fileName, 512, File);
        //ListofMems0[l_indx].threadID = threadID;

        return ListofMems0[l_indx].memory;
    }

    return NULL;
}

There is an index variable that you can change/add if you use that memory block in another thread... Another idea of mine is to use bitwise operation to make collections library without memory pointers. It can be much faster if we use SIMD and multiple threads OR even in opencl/GPU.. I have the idea, but didn't implement yet..

Am I right? Are my ideas good?

$\endgroup$
8
  • 3
    $\begingroup$ char* p = malloc(100); char* q = malloc(100); so what does your LINE argument do? Calling malloc from multiple threads efficiently is a long solved problem. And you seem to have substantial overhead. The implementation used by my phone usually has one bit (not byte) overhead per malloc block. What's the time used for a million blocks? $\endgroup$
    – gnasher729
    Commented Jun 10 at 11:43
  • $\begingroup$ line is used as identifier of code to make hash. If that malloc is repeated, then, hash is computed & the previously allocated memory is returned. I know about overhead, it must be used by array of pointers and mod % operation on hash number.. $\endgroup$
    – mostafas
    Commented Jun 10 at 12:53
  • $\begingroup$ 512 bytes to store the filename for a malloc block of say 16 byte is on one hand a massive amount of overhead. On the other hand it's not enough; because typically paths of 1024 bytes and possibly longer ones are possible. Ad i expect malloc to run in ningle digit nanoseconds on average. Any hasinging during malloc makes it unacceptably slow. $\endgroup$
    – gnasher729
    Commented Jun 10 at 12:54
  • 4
    $\begingroup$ What's good is complete source code with comments. $\endgroup$
    – gnasher729
    Commented Jun 10 at 12:56
  • 3
    $\begingroup$ Since you are asking: No, it is not a good idea. But while your concrete idea does not work (and it also breaks some uses of malloc), you are going in the right direction, as you seem to be describing hash consing. $\endgroup$ Commented Jun 10 at 16:36

2 Answers 2

0
$\begingroup$

There are craftmanship problems like not handling hash collisions.
There are conceptual problems like not accounting for overlapping lifetimes for objects created from "the same source-code site".

Deeming C heap storage management in need of improvement is OK.

You can discuss your ideas with others "knowledgeable in the field" (this Q&As to wit).

It may be a good thing CS@SE isn't the place to discuss "computing related careers", see Which computer science / programming Stack Exchange sites do I post on?

$\endgroup$
2
$\begingroup$

What if the user of this malloc is making a node-based datastructure and expects each node to survive multiple calls to its addNode()? I assume that is what the m_index is about but that feels like a hack.

What if there is a common allocation path for different objects you need a way to propagate the relevant stacktrace information to get hashed.

Quite often you do want to reuse memory when you do something that only happens once or rarely, your system doesn't have facilities for that, instead it leaks.

In other words it's not a drop-in replacement, you need to make changes to your program to use this kind of mechanism.


Much more convenient systems exist if you are already willing to do some rearchitecting of your code to avoid malloc/free.

$\endgroup$
3
  • $\begingroup$ Code runs line by line, so, there is no problem when you call malloc because it stores all stacks by calculating hashes of lines of codes until malloc, It's why I said all functions must have extra parameters that pass line number to next function & I multiplied & the hash is from it. Survive doesn't have meaning in single thread because if line is different it store in another location of memory.. Even in loop all codes run line by line unless you want to fork new proc or thread that in that case you must change index.. I don't understand, object is C++ & not functional C/otherwise it calls.. $\endgroup$
    – mostafas
    Commented Jun 10 at 16:04
  • $\begingroup$ Even in OOP, you can pass object # as a static value & it's index, but even if you don't want it then you call functions in different lines.. I mean function pointers are called in different lines as well.. $\endgroup$
    – mostafas
    Commented Jun 10 at 16:11
  • 1
    $\begingroup$ (@mostafas [C] code runs line by line no, it does not - C is "format free". C code runs synchronisation point to synchronisation point (sort of, and ignoring exceptional events). $\endgroup$
    – greybeard
    Commented Jun 11 at 8:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.