sábado, 24 de maio de 2008

Implementação da Função malloc da linguagem C no UNIX Versão 6

Para você que como eu, sempre teve curiosidade de saber como é implementada a função de alocação dinâmica da linguagem C , void *malloc (unsigned int num);
E seu proferssor de linguagem de Programação (Linguagem C), não fazia a mínima idéia de como o Sistema Operacional implementa a alocação Dinâmica, ai vai um exemplo de alocação dinâmica do Sistema operacional Unix versão 6:






2500: #
2501: /*
2502: */

2503:
2504: /*
2505: * Structure of the coremap and swapmap
2506: * arrays. Consists of non-zero count
2507: * and base address of that many

2508: * contiguous units.
2509: * (The coremap unit is 64 bytes,
2510: * the swapmap unit is 512 bytes)
2511: * The addresses are increasing and
2512: * the list is terminated with the

2513: * first zero count.
2514: */
2515: struct map
2516: {
2517: char *m_size;
2518: char *m_addr;

2519: };
2520: /* --------------------------- */
2521:
2522: /*
2523: * Allocate size units from the given
2524: * map. Return the base of the allocated

2525: * space.
2526: * Algorithm is first fit.
2527: */
2528: malloc(mp, size)
2529: struct map *mp;

2530: {
2531: register int a;
2532: register struct map *bp;
2533:
2534: for (bp = mp; bp->m_size; bp++) {

2535: if (bp->m_size >= size) {
2536: a = bp->m_addr;
2537: bp->m_addr =+ size;
2538: if ((bp->m_size =- size) == 0)

2539: do {
2540: bp++;
2541: (bp-1)->m_addr = bp->m_addr;
2542: } while ((bp-1)->m_size = bp->m_size);

2543: return(a);
2544: }
2545: }
2546: return(0);
2547: }
2548: /* --------------------------- */

2549:
2550: /*
2551: * Free the previously allocated space aa
2552: * of size units into the specified map.
2553: * Sort aa into map and combine on

2554: * one or both ends if possible.
2555: */
2556: mfree(mp, size, aa)
2557: struct map *mp;
2558: {
2559: register struct map *bp;

2560: register int t;
2561: register int a;
2562:
2563: a = aa;
2564: for (bp = mp; bp->m_addr<=a && bp->m_size!=0; bp++);

2565: if (bp>mp && (bp-1)->m_addr+(bp-1)->m_size == a) {
2566: (bp-1)->m_size =+ size;
2567: if (a+size == bp->m_addr) {

2568: (bp-1)->m_size =+ bp->m_size;
2569: while (bp->m_size) {
2570: bp++;
2571: (bp-1)->m_addr = bp->m_addr;

2572: (bp-1)->m_size = bp->m_size;
2573: }
2574: }
2575: } else {

2576: if (a+size == bp->m_addr && bp->m_size) {
2577: bp->m_addr =- size;
2578: bp->m_size =+ size;

2579: } else if (size) do {
2580: t = bp->m_addr;
2581: bp->m_addr = a;

2582: a = t;
2583: t = bp->m_size;
2584: bp->m_size = size;
2585: bp++;
2586: } while (size = t);

2587: }
2588: }
2589: /* --------------------------- */



Observe que a alocação não passa de uma simples manipulação de estrutura de dados, onde vai se incrementando o endereço de memória, até se achar uma região de memório com o tamanho que se deseja (size), disponível ...

O cara que colocou isso na net é um japonês, se desejar de uma conferidinha no arquivo do malloc em: www.tom-yam.or.jp
Se dejar ver os outros arquivos .c que ele colocou lá veja a página:
http://www.tom-yam.or.jp/2238/src/
Se Desejar ver onde ele linkou isso veja: http://www.tom-yam.or.jp/2238/"

Agora você finalmente pode dizer a seu professor de linguagem de programação como é que se implementa um malloc da vida ...!
Oserve que é algo relativamente simples ...!
Bom, abração a todos e se cuidem!

Acabei percebendo que uma galerinha ficou boiando na declaração dessa função malloc, devido a não conhecer os estilo clássico de declaração de funções, lembrando que esse código acima é da década de 70, logo é velho para burro!


Esse texto abaixo foi extraído integralmente sem alterações de:

http://br.geocities.com/sdiasneto/c_int/funcoes.htm

8.4 Parâmetros

Existem duas formas de declaração de parâmetros em funções: a forma clássica e a forma moderna.

A forma clássica tem a seguinte sintaxe:







TIPO NOME(PARÂMETRO1, PARÂMETRO2, ... , PARÂMETROn)
TIPO DO PARÂMETRO1;
TIPO DO PARÂMETRO2;
...
...
TIPO DO PARÂMETROn;
{
CORPO DA FUNÇÃO
}




Já a forma moderna tem a seguinte sintaxe:






TIPO NOME(TIPO PARÂMETRO1, TIPO PARÂMETRO2, ... , TIPO PARÂMETROn)
{
CORPO DA FUNÇÃO
}




Abaixo segue um exemplo de função com os dois tipos de declaração de parâmetros.









/* Com declaração clássica */
int soma(a, b)
int a;
int b;
{
int resultado;
resultado = a + b;
return(resultado);
}



/* Com declaração moderna */
int soma(int a, int b)
{
int resultado;
resultado = a + b;
return(resultado);
}




Atualmente utiliza-se a forma moderna, porém, em programas mais antigos você encontrará a forma clássica.

Fim do comentário dextraído da página mencionada.

Repare que na declaração clássica, dentro dos parêntesis "(" e ")", vão apenas os nomes dos parâmetos ("variáveis"), os respectivos tipos dela são declarados logo após o fecha parêntesis")" e antes do símbolo, abre chaves "{", o símbolo que indica onde começa a função.

Na função malloc acima mp é u ponteiro que aponta para uma estrutura do tipo map (a estrutura do tipo map possui, dois ponteiras para char )
Size deve ser definido em uma diretiva de compilação, aqueles # no cabeçalho do arquivo, mas infelizmente ele não está nessa parte do código para saber ...
Então .., observe que no laço for, você anda alguns endereços de memória até achar uma área de memória livre com um tamanho maior ou igual ao que necessita, nesse caso o tamanho é bp->m_size, e o tamanho que vc necessita é size.
Se você achar você vai indicar ao Sistema operacional que aquela região de memória será ocupada através da operação: bp->m_addr =+ size;
ai você retorna um valor inteiro, que supostamente seria a região de memória alocada ...!

Esse algoritmo acima é o First-fit, ou seja o primeiro que encontrar, podem existir implementações com algoritmos best-fit, worst-fit, FCFS ..., mas esses algoritmos ai o professor Rafael Obelheiro ensina bem lá na Disciplina de Sistemas Operacionais na UDESC, se voc acha que não ensina pelo menos ele cobra bem ..., você tem que saber ...!
Quando fizer a disciplina de SOP com ele entenderá melhor isso ai acima ...!

Nenhum comentário: