source: soft/giet_vm/giet_libs/remote_malloc.c @ 416

Last change on this file since 416 was 375, checked in by alain, 10 years ago

bug fix

  • Property svn:executable set to *
File size: 5.4 KB
Line 
1//////////////////////////////////////////////////////////////////////////////////
2// File     : remote_malloc.c         
3// Date     : 01/08/2014
4// Author   : alain greiner
5// Copyright (c) UPMC-LIP6
6///////////////////////////////////////////////////////////////////////////////////
7
8#include "giet_config.h"
9#include "hard_config.h"
10#include "remote_malloc.h"
11#include "stdio.h"
12#include "spin_lock.h"
13
14///////////////////////////////////////////////////////////////////////////////////
15// Global variables describing allocators: one heap per cluster.
16// For each cluster, cur[x][y] is the virtual adrress of first free byte
17// in heap, max[x][y] is the virtual address of first forbidden byte on top
18// of heap, and lock[x][y] protect exclusive access to heap[x][y].
19///////////////////////////////////////////////////////////////////////////////////
20
21unsigned int remote_malloc_cur[X_SIZE][Y_SIZE] = {[0 ... X_SIZE-1][0 ... Y_SIZE-1] = 0};
22
23unsigned int remote_malloc_max[X_SIZE][Y_SIZE] = {[0 ... X_SIZE-1][0 ... Y_SIZE-1] = 0};
24
25giet_lock_t  remote_malloc_lock[X_SIZE][Y_SIZE] __attribute__((aligned(512)));
26
27///////////////////////////////////////////////////////////////////////////////////
28// This function returne the virtual base address of the allocated block.
29// - length is the block length (number of bytes)
30// - align is the alignment constrain (vbase multiple of Ox1 << align).
31// - If (x < X_SIZE) and (y < Y_SIZE), it uses the heap defined in cluster(x,y).
32// - It uses the heap in cluster running the calling task if x oy y too large.
33// The calling task exit with an error message if the request cannot be satisfied.
34///////////////////////////////////////////////////////////////////////////////////
35void* remote_malloc( unsigned int length,
36                     unsigned int align,
37                     unsigned int x,
38                     unsigned int y )
39{
40    // checking alignment constraint
41    if ( align > 31  ) 
42    {
43        giet_exit("in remote_malloc(), align constraint > 31\n");
44    }
45
46    // checking requested length
47    if ( length == 0 ) 
48    {
49        giet_exit("in remote_malloc(), requested length = 0\n");
50    }
51
52#if GIET_DEBUG_MALLOC
53unsigned int procid  = giet_procid();
54unsigned int cluster = procid / NB_PROCS_MAX;
55unsigned int proc_x  = cluster >> Y_WIDTH;
56unsigned int proc_y  = cluster & ((1<<Y_WIDTH)-1);
57unsigned int lpid    = procid % NB_PROCS_MAX;
58giet_shr_printf("\n[DEBUG MALLOC] Processor[%d,%d,%d] enters remote_malloc()"
59                " : length = %x / align = %x for heap(%d,%d)\n",
60                proc_x, proc_y, lpid, length, (1<<align), x, y );
61#endif
62
63
64    unsigned int heap_x;        // heap x coordinate
65    unsigned int heap_y;        // heap y coordibnate
66    unsigned int heap_base;     // heap base address
67    unsigned int heap_length;   // heap length
68    unsigned int vbase;         // virtual address to be returned
69
70    unsigned int quantum = 1 << align;
71
72    // compute cluster coordinates
73    if ( (x < X_SIZE) && (y < Y_SIZE) )
74    {
75        heap_x = x;
76        heap_y = y;
77    }
78    else
79    {
80        unsigned int pid = giet_procid();
81        heap_x = (pid / NB_PROCS_MAX) >> Y_WIDTH;
82        heap_y = (pid / NB_PROCS_MAX) & ((1<<Y_WIDTH)-1);
83    }
84
85    // get heap vbase and length if allocator[x][y] not initialised yet
86    if ( remote_malloc_max[heap_x][heap_y] == 0 )
87    {
88        giet_heap_info( &heap_base,
89                        &heap_length,
90                        heap_x, 
91                        heap_y );
92
93        if ( heap_length == 0 ) 
94        {
95            giet_exit("in remote_malloc(): heap length = 0\n");
96        }
97
98        remote_malloc_cur[heap_x][heap_y] = heap_base;
99        remote_malloc_max[heap_x][heap_y] = heap_base + heap_length;
100
101        // initialise lock
102        lock_release( &remote_malloc_lock[heap_x][heap_y] );
103
104#if GIET_DEBUG_MALLOC
105giet_shr_printf("\n[DEBUG MALLOC] Processor[%d,%d,%d] initializes heap(%d,%d)\n"
106                " - heap_base        = %x\n"
107                " - heap_size        = %x\n",
108                proc_x, proc_y, lpid, heap_x, heap_y,
109                heap_base, heap_length );
110#endif
111
112    }
113
114    // take the lock
115    lock_acquire( &remote_malloc_lock[heap_x][heap_y] );
116
117#if GIET_DEBUG_MALLOC
118giet_shr_printf("\n[DEBUG MALLOC] Processor[%d,%d,%d] takes lock for heap(%d,%d)\n",
119                proc_x, proc_y, lpid, heap_x, heap_y );
120#endif
121
122    // compute vbase
123    vbase = remote_malloc_cur[heap_x][heap_y];
124    if ( vbase % quantum )  vbase = ((vbase / quantum) + 1 ) * quantum; 
125
126#if GIET_DEBUG_MALLOC
127giet_shr_printf("\n[DEBUG MALLOC] Processor[%d,%d,%d] allocate vaddr = %x in heap(%d,%d)\n",
128                proc_x, proc_y, lpid, vbase, heap_x, heap_y );
129#endif
130
131    // check overflow
132    if ( (vbase + length) > remote_malloc_max[heap_x][heap_y] )
133    {
134        giet_exit("in remote_malloc(), heap overflow\n");
135    }
136
137    // update heap pointer
138    remote_malloc_cur[heap_x][heap_y] = vbase + length;
139
140    // release the lock
141    lock_release( &remote_malloc_lock[heap_x][heap_y] );
142
143#if GIET_DEBUG_MALLOC
144giet_shr_printf("\n[DEBUG MALLOC] Processor[%d,%d,%d] releases lock for heap(%d,%d)\n",
145                proc_x, proc_y, lpid, heap_x, heap_y );
146#endif
147
148    return (void*)vbase;
149}  // end remote_malloc()
150
151
152
153// Local Variables:
154// tab-width: 4
155// c-basic-offset: 4
156// c-file-offsets:((innamespace . 0)(inline-open . 0))
157// indent-tabs-mode: nil
158// End:
159// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
160
161
162
Note: See TracBrowser for help on using the repository browser.