source: trunk/kernel/mm/kmem.c

Last change on this file was 683, checked in by alain, 17 months ago

All modifications required to support the <tcp_chat> application
including error recovery in case of packet loss.A

File size: 6.0 KB
Line 
1/*
2 * kmem.c - kernel memory allocator implementation.
3 *
4 * Authors  Alain Greiner     (2016,2017,2018,2019,2020)
5 *
6 * Copyright (c) UPMC Sorbonne Universites
7 *
8 * This file is part of ALMOS-MKH.
9 *
10 * ALMOS-MKH is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; version 2.0 of the License.
13 *
14 * ALMOS-MKH is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
21 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24#include <kernel_config.h>
25#include <hal_kernel_types.h>
26#include <hal_special.h>
27#include <printk.h>
28#include <cluster.h>
29#include <thread.h>
30#include <memcpy.h>
31#include <ppm.h>
32#include <kcm.h>
33#include <page.h>
34#include <kmem.h>
35
36///////////////////////////////////
37void * kmem_alloc( uint32_t  order,
38                   uint32_t  flags )
39{
40
41#if DEBUG_KMEM || DEBUG_KMEM_ERROR
42thread_t * this  = CURRENT_THREAD;
43uint32_t   cycle = (uint32_t)hal_get_cycles();
44#endif
45
46        if( order >= CONFIG_PPM_PAGE_ORDER )     // use PPM
47        {
48                // allocate memory from PPM
49                page_t * page = (void *)ppm_alloc_pages( order - CONFIG_PPM_PAGE_ORDER );
50
51                if( page == NULL )
52                {
53
54#if DEBUG_KMEM_ERROR
55if (DEBUG_KMEM_ERROR < cycle)
56printk("\n[ERROR] in %s : thread[%x,%x] failed for PPM / order %d / cluster %x / cycle %d\n",
57__FUNCTION__ , this->process->pid , this->trdid , order , local_cxy , cycle );
58#endif
59                        return NULL;
60                }
61
62                // reset page if requested
63                if( flags & AF_ZERO ) page_zero( page );
64
65        // get pointer on buffer from the page descriptor
66        xptr_t page_xp = XPTR( local_cxy , page );
67        void * ptr     = GET_PTR( ppm_page2base( page_xp ) );
68
69#if DEBUG_KMEM
70if( (DEBUG_KMEM < cycle) && (DEBUG_KMEM_CXY == local_cxy) && (DEBUG_KMEM_ORDER == order) )
71printk("\n[%s] thread[%x,%x] from PPM / order %d / ppn %x / cxy %x / cycle %d\n",
72__FUNCTION__, this->process->pid, this->trdid,
73order, ppm_page2ppn(XPTR(local_cxy,ptr)), local_cxy, cycle );
74#endif
75        return ptr;
76        }
77        else                                     // use KCM
78        {
79                // allocate memory from KCM
80                void * ptr = kcm_alloc( order );
81
82                if( ptr == NULL )
83                {
84
85#if DEBUG_KMEM_ERROR
86if (DEBUG_KMEM_ERROR < cycle)
87printk("\n[ERROR] in %s : thread[%x,%x] failed for KCM / order %d / cluster %x / cycle %d\n",
88__FUNCTION__ , this->process->pid , this->trdid , order , local_cxy , cycle );
89#endif
90                        return NULL;
91                }
92
93                // reset memory if requested
94                if( flags & AF_ZERO ) memset( ptr , 0 , 1<<order );
95
96#if DEBUG_KMEM
97if( (DEBUG_KMEM < cycle) && (DEBUG_KMEM_CXY == local_cxy) && (DEBUG_KMEM_ORDER == order) )
98printk("\n[%s] thread [%x,%x] from KCM / order %d / base %x / cxy %x / cycle %d\n",
99__FUNCTION__, this->process->pid, this->trdid,
100order, ptr, local_cxy, cycle ); 
101#endif
102        return ptr;
103        }
104}  // end kmem_alloc()
105
106//////////////////////////////
107void kmem_free( void    * ptr,
108                uint32_t  order )
109{
110        if( order >= CONFIG_PPM_PAGE_ORDER )     // use PPM
111        {
112        page_t * page = GET_PTR( ppm_base2page( XPTR( local_cxy , ptr ) ) );
113
114        ppm_free_pages( page );
115    }
116        else                                     // use KCM
117    {
118        kcm_free( ptr , order );
119        }
120}  // end kmem_free()
121
122
123
124////////////////////////////////////////
125void * kmem_remote_alloc( cxy_t     cxy,
126                          uint32_t  order,
127                          uint32_t  flags )
128{
129
130#if DEBUG_KMEM || DEBUG_KMEM_ERROR
131thread_t * this = CURRENT_THREAD;
132uint32_t   cycle = (uint32_t)hal_get_cycles();
133#endif
134
135        if( order >= CONFIG_PPM_PAGE_ORDER )     // use PPM
136        {
137                // allocate memory from PPM
138                xptr_t page_xp = ppm_remote_alloc_pages( cxy , order - CONFIG_PPM_PAGE_ORDER );
139
140                if( page_xp == XPTR_NULL )
141                {
142
143#if DEBUG_KMEM_ERROR
144if( DEBUG_KMEM_ERROR < cycle )
145printk("\n[ERROR] in %s : thread[%x,%x] failed for PPM / order %d / cluster %x / cycle %d\n",
146__FUNCTION__ , this->process->pid , this->trdid , order , cxy , cycle );
147#endif
148                        return NULL;
149                }
150
151        // get extended pointer on remote buffer
152        xptr_t base_xp = ppm_page2base( page_xp );
153
154                // reset memory if requested
155                if( flags & AF_ZERO ) hal_remote_memset( base_xp , 0 , 1<<order );
156
157#if DEBUG_KMEM
158if( (DEBUG_KMEM < cycle) && (DEBUG_KMEM_CXY == local_cxy) && (DEBUG_KMEM_ORDER == order) )
159printk("\n[%s] thread[%x,%x] from PPM / order %d / ppn %x / cxy %x / cycle %d\n",
160__FUNCTION__, this->process->pid, this->trdid,
161order, ppm_page2ppn( page_xp ), cxy, cycle );
162#endif
163        return GET_PTR( base_xp );
164        }
165        else                                     // use KCM
166        {
167                // allocate memory from KCM
168                void * ptr = kcm_remote_alloc( cxy , order );
169
170                if( ptr == NULL )
171                {
172
173#if DEBUG_KMEM_ERROR
174if( DEBUG_KMEM_ERROR < cycle )
175printk("\n[ERROR] in %s : thread[%x,%x] failed for KCM / order %d / cluster %x / cycle %d\n",
176__FUNCTION__ , this->process->pid , this->trdid , order , cxy , cycle );
177#endif
178                        return NULL;
179                }
180
181                // reset memory if requested
182                if( flags & AF_ZERO )  hal_remote_memset( XPTR( cxy , ptr ) , 0 , 1<<order );
183
184#if DEBUG_KMEM
185if( (DEBUG_KMEM < cycle) && (DEBUG_KMEM_CXY == local_cxy) && (DEBUG_KMEM_ORDER == order) )
186printk("\n[%s] thread [%x,%x] from KCM / order %d / base %x / cxy %x / cycle %d\n",
187__FUNCTION__, this->process->pid, this->trdid,
188order, ptr, cxy, cycle );
189#endif
190        return ptr;
191        }
192}  // kmem_remote_malloc()
193
194/////////////////////////////////////
195void kmem_remote_free( cxy_t     cxy,
196                       void    * ptr,
197                       uint32_t  order )
198{
199        if( order >= CONFIG_PPM_PAGE_ORDER )     // use PPM
200        {
201        page_t * page = GET_PTR( ppm_base2page( XPTR( cxy , ptr ) ) );
202
203        ppm_remote_free_pages( cxy , page );
204    }
205        else                                     // use KCM
206    {
207        kcm_remote_free( cxy , ptr , order );
208        }
209}  // end kmem_remote_free()
210
211
212
Note: See TracBrowser for help on using the repository browser.