source: trunk/libs/libalmosmkh/almosmkh.h @ 623

Last change on this file since 623 was 623, checked in by alain, 3 years ago

Introduce three new types of vsegs (KCODE,KDATA,KDEV)
to map the kernel vsegs in the process VSL and GPT.
This now used by both the TSAR and the I86 architectures.

File size: 22.4 KB
Line 
1/*
2 * almosmkh.h - User level ALMOS-MKH specific library definition.
3 *
4 * Author     Alain Greiner (2016,2017,2018)
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#ifndef _LIBALMOSMKH_H_
25#define _LIBALMOSMKH_H_
26
27/***************************************************************************************
28 * This file defines an user level, ALMOS-MKH specific library, containing:
29 * - non standard system calls.
30 * - debug functions.
31 * - remote malloc extensions.
32 **************************************************************************************/
33
34#include <pthread.h>
35#include <shared_almos.h>
36
37/****************** Non standard (ALMOS_MKH specific) system calls ********************/
38
39
40/***************************************************************************************
41 * This syscall gives the process identified by the <pid> argument the exclusive
42 * ownership of its TXT terminal.
43 ***************************************************************************************
44 * @ pid        : process identifier.
45 * @ returns O if success / returns -1 if process not found.
46 **************************************************************************************/
47int fg( unsigned int pid );
48
49/***************************************************************************************
50 * This syscall stores in the buffer identified by the <owner> argument a non zero
51 * value when the process identified by the <pid> argument is currently the exclusive
52 * owner of its TXT terminal.
53 ***************************************************************************************
54 * @ pid        : [in]  process identifier.
55 * @ owner      : [out] pointer on buffer to store the
56 * @ returns O if success / returns -1 if process not found.
57 **************************************************************************************/
58int is_fg( unsigned int pid,
59           unsigned int * owner );
60
61/***************************************************************************************
62 * This syscall returns the hardware platform parameters.
63 ***************************************************************************************
64 * @ x_size   : [out] number of clusters in a row.
65 * @ y_size   : [out] number of clusters in a column.
66 * @ ncores   : [out] number of cores per cluster.
67 * @ return always 0.
68 **************************************************************************************/
69int get_config( unsigned int * x_size,
70                unsigned int * y_size,
71                unsigned int * ncores );
72
73/***************************************************************************************
74 * This syscall returns the cluster an local index for the calling core.
75 ***************************************************************************************
76 * @ cxy      : [out] cluster identifier.
77 * @ lid      : [out] core local index in cluster.
78 * @ return always 0.
79 **************************************************************************************/
80int get_core( unsigned int * cxy,
81              unsigned int * lid );
82
83/***************************************************************************************
84 * This function returns the calling core cycles counter,
85 * taking into account a possible overflow on 32 bits architectures.
86 ***************************************************************************************
87 * @ cycle    : [out] current cycle value.
88 * @ return always 0.
89 **************************************************************************************/
90int get_cycle( unsigned long long * cycle );
91
92/***************************************************************************************
93 * This syscall allows the calling thread to specify the target cluster for
94 * a subsequent fork(). It must be called for each fork().
95 ***************************************************************************************
96 * @ cxy      : [in] target cluster identifier.
97 * @ return 0 if success / returns -1 if illegal cxy argument.
98 **************************************************************************************/
99int place_fork( unsigned int cxy );
100
101/***************************************************************************************
102 * This syscall implements the operations related to User Thread Local Storage.
103 ***************************************************************************************
104 * @ operation  : UTLS operation type as defined in "shared_sycalls.h" file.
105 * @ value      : argument value for the UTLS_SET operation.
106 * @ return value for the UTLS_GET and UTLS_GET_ERRNO / return -1 if failure.
107 **************************************************************************************/
108int utls( unsigned int operation,
109          unsigned int value );
110
111/***************************************************************************************
112 * This syscall returns an unsigned 32 bits integer from the standard "stdin" stream.
113 * Both decimal numbers and hexadecimal numbers (prefixed by 0x) are supported.
114 ***************************************************************************************
115 * returns the integer value if success / returns -1 if failure.
116 **************************************************************************************/
117unsigned int get_uint32( void );
118
119
120/***************** Non standard (ALMOS-MKH specific) debug functions ******************/
121
122
123/***************************************************************************************
124 * This debug syscall displays on the kernel terminal TXT0
125 * the thread / process / core identifiers, the current cycle, plus a user defined
126 * message as specified by the <string> argument.
127 ***************************************************************************************
128 * @ string    : [in] user defined message.
129 **************************************************************************************/
130void display_string( char * string );
131
132/***************************************************************************************
133 * This debug function displays on the kernel terminal TXT0
134 * the state of the  VMM for the process <pid> in cluster <cxy>.
135 * It can be called by any thread running in any cluster.
136 ***************************************************************************************
137 * @ pid      : [in] process identifier.
138 * @ return 0 if success / return -1 if illegal argument.
139 **************************************************************************************/
140int display_vmm(unsigned int cxy, unsigned int pid );
141
142/***************************************************************************************
143 * This debug syscall displays on the kernel terminal TXT0
144 * the state of the core scheduler identified by the <cxy> and <lid> arguments.
145 * It can be called by any thread running in any cluster.
146 ***************************************************************************************
147 * @ cxy      : [in] target cluster identifier.
148 * @ lid      : [in] target core local index.
149 * @ return 0 if success / return -1 if illegal arguments.
150 **************************************************************************************/
151int display_sched( unsigned int  cxy,
152                   unsigned int  lid );
153
154/***************************************************************************************
155 * This debug syscall displays on the kernel terminal TXT0
156 * the list of process registered in a given cluster identified by the <cxy> argument.
157 * Only the owned processes are displayed when the <owned> argument is non zero.
158 * It can be called by any thread running in any cluster.
159 ***************************************************************************************
160 * @ cxy      : [in] target cluster identifier.
161 * @ owned    : [in] only owned processes if non zero.
162 * @ return 0 if success / return -1 if illegal argument.
163 **************************************************************************************/
164int display_cluster_processes( unsigned int  cxy,
165                               unsigned int  owned );
166
167/***************************************************************************************
168 * This debug syscall displays on the kernel terminal TXT0
169 * the list of processes attached to a given TXT channel.
170 * It can be called by any thread running in any cluster.
171 ***************************************************************************************
172 * @ txt_id   : [in] TXT terminal indes.
173 * @ return 0 if success / return -1 if illegal argument.
174 **************************************************************************************/
175int display_txt_processes( unsigned int txt_id );
176
177/***************************************************************************************
178 * This debug syscall displays on the kernel terminal TXT0
179 * the set of busylocks hold by a thread identified by the <pid> and <trdid> arguments.
180 * It can be called by any thread running in any cluster.
181 ***************************************************************************************
182 * @ pid      : [in] process identifier.
183 * @ trdid    : [in] thread identifier.
184 * @ return 0 if success / return -1 if illegal arguments.
185 **************************************************************************************/
186int display_busylocks( unsigned int pid,
187                       unsigned int trdid );
188
189/***************************************************************************************
190 * This debug syscall displays on the kernel terminal TXT0
191 * the list of channel devices available in the architecture.
192 * It can be called by any thread running in any cluster.
193 ***************************************************************************************
194 * @ return always 0.
195 **************************************************************************************/
196int display_chdev( void );
197
198/***************************************************************************************
199 * This debug syscall displays on the kernel terminal TXT0
200 * the list of channel device or pseudo-files registered in the VFS cache.
201 * It can be called by any thread running in any cluster.
202 ***************************************************************************************
203 * @ return always 0.
204 **************************************************************************************/
205int display_vfs( void );
206
207/***************************************************************************************
208 * This debug syscall displays on the kernel terminal TXT0 the current DQDT state.
209 * It can be called by any thread running in any cluster.
210 ***************************************************************************************
211 * @ return always 0.
212 **************************************************************************************/
213int display_dqdt( void );
214
215/***************************************************************************************
216 * This debug syscall displays on the kernel terminal TXT0 the content of a given
217 * page of a given VFS mapper.
218 * It can be called by any thread running in any cluster.
219 ***************************************************************************************
220 * @ path      : pathname identifying the file/directory in VFS.
221 * @ page_id   : page index in file.
222 * @ nbytes    : number of bytes to display.
223 * @ return 0 if success / return -1 if file or page not found.
224 **************************************************************************************/
225int display_mapper( char        * path,
226                    unsigned int  page_id,
227                    unsigned int  nbytes);
228
229/***************************************************************************************
230 * This debug syscall displays on the kernel terminal TXT0
231 * the state of the barrier used by the process identified by the <pid> argument.
232 * It can be called by any thread running in any cluster.
233 ***************************************************************************************
234 * @ pid      : [in] process identifier.
235 * @ return 0 if success / return -1 if illegal arguments.
236 **************************************************************************************/
237int display_barrier( unsigned int pid );
238
239/*****************************************************************************************
240* This debug syscall is used to activate / desactivate the context switches trace
241* for a core identified by the <cxy> and <lid> arguments.
242* It can be called by any thread running in any cluster.
243*****************************************************************************************
244* @ active     : activate trace if non zero / desactivate if zero.
245* @ cxy        : cluster identifier.
246* @ lid        : core local index.
247* @ returns O if success / returns -1 if illegal arguments.
248****************************************************************************************/
249int trace( unsigned int active,
250           unsigned int cxy, 
251           unsigned int lid );
252
253/****************************************************************************************
254 * This syscall implements an user-level interactive debugger that can be
255 * introduced in any user application to display various kernel distributed structures.
256 * The supported commands are:
257 * - p (cxy)     : display all processes descriptors in a given cluster.
258 * - s (cxy,lid) : display all threads attached to a given core in a given cluster.
259 * - v (cxy)     : display the calling process VMM in a given cluster.
260 * - t (tid)     : display all owner process descriptors attached to a TXT terminal.
261 * - x           : force the calling process to exit.
262 * - c           : continue calling process execution.
263 * - h           : list the supported commands
264 ***************************************************************************************/
265void idbg( void );
266
267
268/****************** Non standard (ALMOS-MKH specific) malloc operations  ***************/
269
270/////////////////////////////////////////////////////////////////////////////////////////
271// General principles:
272// - In user space the HEAP zone spread between the ELF zone and the STACK zone,
273//   as defined in the kernel_config.h file.
274// - The malloc library uses the mmap() syscall to create - on demand -
275//   one vseg in a given cluster. The size of this vseg is defined below
276//   by the MALLOC_LOCAL_STORE_SIZE parameter.
277// - For a standard malloc(), the target cluster is the cluster containing
278//   the core running the client thread.
279// - For a remote_malloc(), the target cluster is explicitely defined
280//   by the argument.
281// - In each cluster, the available storage in virtual space is handled by a
282//   local allocator using the buddy algorithm.
283//
284// TODO : In this first implementation one single - fixed size - vseg
285//        is allocated on demand in each cluster.
286//        We should introduce the possibility to dynamically allocate
287//        several vsegs in each cluster, using several mmap when required.
288/////////////////////////////////////////////////////////////////////////////////////////
289// Free blocks organisation in each cluster :
290// - All free blocks have a size that is a power of 2, larger or equal
291//   to MALLOC_MIN_BLOCK_SIZE (typically 64 bytes).
292// - All free blocks are aligned.
293// - They are pre-classed in an array of linked lists, where all blocks in a
294//   given list have the same size.
295// - The NEXT pointer implementing those linked lists is written
296//   in the first bytes of the block itself, using the unsigned int type.
297// - The pointers on the first free block for each size are stored in an
298//   array of pointers free[32] in the storage(x,y) descriptor.
299/////////////////////////////////////////////////////////////////////////////////////////
300// Allocation policy:
301// - The block size required by the user can be any value, but the allocated
302//   block size can be larger than the requested size:
303// - The allocator computes actual_size, that is the smallest power of 2
304//   value larger or equal to the requested size AND larger or equal to
305//   MALLOC_MIN_BLOCK_SIZE.
306// - It pop the linked list of free blocks corresponding to actual_size,
307//   and returns the block B if the list[actual_size] is not empty.
308// - If the list[actual_size] is empty, it pop the list[actual_size * 2].
309//   If a block B' is found, it breaks this block in 2 B/2 blocks, returns
310//   the first B/2 block and push the other B/2 block into list[actual_size].
311// - If the list[actual_size * 2] is empty, it pop the list[actual_size * 4].
312//   If a block B is found, it break this block in 3 blocks B/4, B/4 and B/2,
313//   returns the first B/4 block, push the other blocks B/4 and B/2 into
314//   the proper lists. etc...
315// - If no block satisfying the request is available it returns a failure
316//   (NULL pointer).
317// - This allocation policy has the nice following property:
318//   If the vseg is aligned (the vseg base is a multiple of the
319//   vseg size), all allocated blocks are aligned on the actual_size.
320/////////////////////////////////////////////////////////////////////////////////////////
321// Free policy:
322// - Each allocated block is registered in an alloc[] array of unsigned char.
323// - This registration is required by the free() operation, because the size
324//   of the allocated block must be obtained from the base address of the block. 
325// - The number of entries in this array is equal to the max number
326//   of allocated block : MALLOC_LOCAL_STORE_SIZE / MALLOC_MIN_BLOCK_SIZE.
327// - For each allocated block, the value registered in the alloc[] array
328//   is log2( size_of_allocated_block ).
329// - The index in this array is computed from the allocated block base address:
330//      index = (block_base - vseg_base) / MALLOC_MIN_BLOCK_SIZE
331// - The alloc[] array is stored at the end of heap segment. This consume
332//   (1 / MALLOC_MIN_BLOCK_SIZE) of the total storage capacity.
333/////////////////////////////////////////////////////////////////////////////////////////
334
335
336#define MALLOC_INITIALIZED         0xBABEF00D   // magic number when initialised
337#define MALLOC_MIN_BLOCK_SIZE      0x40         // 64 bytes
338#define MALLOC_LOCAL_STORE_SIZE    0x800000     // 8 Mbytes     
339#define MALLOC_MAX_CLUSTERS        0x100        // 256 clusters
340
341/////////////////////////////////////////////////////////////////////////////////////////
342//               store(x,y) descriptor (one per cluster)
343/////////////////////////////////////////////////////////////////////////////////////////
344
345typedef struct malloc_store_s
346{
347    pthread_mutex_t mutex;           // lock protecting exclusive access to local heap
348    unsigned int    initialized;     // initialised when value == MALLOC_INITIALIZED
349    unsigned int    cxy;             // cluster identifier 
350    unsigned int    store_base;      // store base address
351    unsigned int    store_size;      // store size (bytes)
352    unsigned int    alloc_base;      // alloc[] array base address
353    unsigned int    alloc_size;      // alloc[] array size (bytes)
354    unsigned int    free[32];        // array of addresses of first free block
355} 
356malloc_store_t;
357
358/*****************************************************************************************
359 * This function allocates <size> bytes of memory in user space, and returns a pointer
360 * to the allocated buffer. The pysical memory is allocated from store located in
361 * cluster identified by the <cxy> argument.
362 *****************************************************************************************
363 * @ size    : number of requested bytes.
364 * @ cxy     : target cluster identifier.
365 * @ returns a pointer on the allocated buffer if success / returns NULL if failure
366 ****************************************************************************************/
367void * remote_malloc( unsigned int size, 
368                      unsigned int cxy );
369
370/*****************************************************************************************
371 * This function releases the memory buffer identified by the <ptr> argument,
372 * to the store identified by the <cxy> argument.
373 * It displays an error message, but does nothing if the ptr is illegal.
374 *****************************************************************************************
375 * @ ptr   : pointer on the released buffer.
376 * @ cxy   : target cluster identifier.
377 ****************************************************************************************/
378void remote_free( void        * ptr,
379                  unsigned int  cxy );
380
381/*****************************************************************************************
382 * This function releases the memory buffer identified by the <ptr> argument,
383 * to the store located in cluster identified by the <cxy> argument, and allocates
384 * a new buffer containing <size> bytes from this store.
385 * The content of the old buffer is copied to the new buffer, up to <size> bytes.
386 * It displays an error message, but does nothing if the ptr is illegal.
387 *****************************************************************************************
388 * @ ptr     : pointer on the released buffer.
389 * @ size    : new buffer requested size (bytes).
390 * @ cxy     : target cluster identifier.
391 * @ return a pointer on allocated buffer if success / return NULL if failure
392 ****************************************************************************************/
393void * remote_realloc( void        * ptr,
394                       unsigned int  size,
395                       unsigned int  cxy );
396
397/*****************************************************************************************
398 * This function allocates enough space for <count> objects that are <size> bytes
399 * of memory each from the store located in cluster identied by the <cxy> argument.
400 * The allocated memory is filled with bytes of value zero.
401 *****************************************************************************************
402 * @ count   : number of requested objects.
403 * @ size    : number of bytes per object.
404 * @ cxy     : target cluster identifier.
405 * @ returns a pointer on allocated buffer if success / returns NULL if failure
406 ****************************************************************************************/
407void * remote_calloc( unsigned int count,
408                      unsigned int size,
409                      unsigned int cxy );
410
411#endif /* _LIBALMOSMKH_H_ */
412
Note: See TracBrowser for help on using the repository browser.