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

Last change on this file since 626 was 626, checked in by alain, 2 years ago

This version has been tested on the sort multithreaded application
for TSAR_IOB architectures ranging from 1 to 8 clusters.
It fixes three bigs bugs:
1) the dev_ioc device API has been modified: the dev_ioc_sync_read()
and dev_ioc_sync_write() function use now extended pointers on the
kernel buffer to access a mapper stored in any cluster.
2) the hal_uspace API has been modified: the hal_copy_to_uspace()
and hal_copy_from_uspace() functions use now a (cxy,ptr) couple
to identify the target buffer (equivalent to an extended pointer.
3) an implementation bug has been fixed in the assembly code contained
in the hal_copy_to_uspace() and hal_copy_from_uspace() functions.

File size: 23.1 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 * @ cxy      : [in] target cluster identifier.
138 * @ pid      : [in] process identifier.
139 * @ return 0 if success / return -1 if illegal argument.
140 **************************************************************************************/
141int display_vmm(unsigned int cxy, unsigned int pid );
142
143/***************************************************************************************
144 * This debug syscall displays on the kernel terminal TXT0
145 * the state of the core scheduler identified by the <cxy> and <lid> arguments.
146 * It can be called by any thread running in any cluster.
147 ***************************************************************************************
148 * @ cxy      : [in] target cluster identifier.
149 * @ lid      : [in] target core local index.
150 * @ return 0 if success / return -1 if illegal arguments.
151 **************************************************************************************/
152int display_sched( unsigned int  cxy,
153                   unsigned int  lid );
154
155/***************************************************************************************
156 * This debug syscall displays on the kernel terminal TXT0
157 * the list of process registered in a given cluster identified by the <cxy> argument.
158 * Only the owned processes are displayed when the <owned> argument is non zero.
159 * It can be called by any thread running in any cluster.
160 ***************************************************************************************
161 * @ cxy      : [in] target cluster identifier.
162 * @ owned    : [in] only owned processes if non zero.
163 * @ return 0 if success / return -1 if illegal argument.
164 **************************************************************************************/
165int display_cluster_processes( unsigned int  cxy,
166                               unsigned int  owned );
167
168/***************************************************************************************
169 * This debug syscall displays on the kernel terminal TXT0
170 * the list of processes attached to a given TXT channel.
171 * It can be called by any thread running in any cluster.
172 ***************************************************************************************
173 * @ txt_id   : [in] TXT terminal indes.
174 * @ return 0 if success / return -1 if illegal argument.
175 **************************************************************************************/
176int display_txt_processes( unsigned int txt_id );
177
178/***************************************************************************************
179 * This debug syscall displays on the kernel terminal TXT0
180 * the set of busylocks hold by a thread identified by the <pid> and <trdid> arguments.
181 * It can be called by any thread running in any cluster.
182 ***************************************************************************************
183 * @ pid      : [in] process identifier.
184 * @ trdid    : [in] thread identifier.
185 * @ return 0 if success / return -1 if illegal arguments.
186 **************************************************************************************/
187int display_busylocks( unsigned int pid,
188                       unsigned int trdid );
189
190/***************************************************************************************
191 * This debug syscall displays on the kernel terminal TXT0
192 * the list of channel devices available in the architecture.
193 * It can be called by any thread running in any cluster.
194 ***************************************************************************************
195 * @ return always 0.
196 **************************************************************************************/
197int display_chdev( void );
198
199/***************************************************************************************
200 * This debug syscall displays on the kernel terminal TXT0
201 * the list of channel device or pseudo-files registered in the VFS cache.
202 * It can be called by any thread running in any cluster.
203 ***************************************************************************************
204 * @ return always 0.
205 **************************************************************************************/
206int display_vfs( void );
207
208/***************************************************************************************
209 * This debug syscall displays on the kernel terminal TXT0 the current DQDT state.
210 * It can be called by any thread running in any cluster.
211 ***************************************************************************************
212 * @ return always 0.
213 **************************************************************************************/
214int display_dqdt( void );
215
216/***************************************************************************************
217 * This debug syscall displays on the kernel terminal TXT0 the content of a given
218 * page of a given VFS mapper.
219 * It can be called by any thread running in any cluster.
220 ***************************************************************************************
221 * @ path      : pathname identifying the file/directory in VFS.
222 * @ page_id   : page index in file.
223 * @ nbytes    : number of bytes to display.
224 * @ return 0 if success / return -1 if file or page not found.
225 **************************************************************************************/
226int display_mapper( char        * path,
227                    unsigned int  page_id,
228                    unsigned int  nbytes);
229
230/***************************************************************************************
231 * This debug syscall displays on the kernel terminal TXT0
232 * the state of the barrier used by the process identified by the <pid> argument.
233 * It can be called by any thread running in any cluster.
234 ***************************************************************************************
235 * @ pid      : [in] process identifier.
236 * @ return 0 if success / return -1 if illegal arguments.
237 **************************************************************************************/
238int display_barrier( unsigned int pid );
239
240/***************************************************************************************
241 * This debug syscall displays on the kernel terminal TXT0 the content of one given
242 * page of the FAT mapper.
243 * It can be called by any thread running in any cluster.
244 ***************************************************************************************
245 * @ page_id    : page index in file.
246 * @ nb_entries : number of bytes to display.
247 * @ return 0 if success / return -1 if page not found.
248 **************************************************************************************/
249int display_fat( unsigned int page_id,
250                 unsigned int nb_entries );
251
252/*****************************************************************************************
253* This debug syscall is used to activate / desactivate the context switches trace
254* for a core identified by the <cxy> and <lid> arguments.
255* It can be called by any thread running in any cluster.
256*****************************************************************************************
257* @ active     : activate trace if non zero / desactivate if zero.
258* @ cxy        : cluster identifier.
259* @ lid        : core local index.
260* @ returns O if success / returns -1 if illegal arguments.
261****************************************************************************************/
262int trace( unsigned int active,
263           unsigned int cxy, 
264           unsigned int lid );
265
266/****************************************************************************************
267 * This syscall implements an user-level interactive debugger that can be
268 * introduced in any user application to display various kernel distributed structures.
269 * The supported commands are:
270 * - p (cxy)     : display all processes descriptors in a given cluster.
271 * - s (cxy,lid) : display all threads attached to a given core in a given cluster.
272 * - v (cxy)     : display the calling process VMM in a given cluster.
273 * - t (tid)     : display all owner process descriptors attached to a TXT terminal.
274 * - x           : force the calling process to exit.
275 * - c           : continue calling process execution.
276 * - h           : list the supported commands
277 ***************************************************************************************/
278void idbg( void );
279
280
281/****************** Non standard (ALMOS-MKH specific) malloc operations  ***************/
282
283/////////////////////////////////////////////////////////////////////////////////////////
284// General principles:
285// - In user space the HEAP zone spread between the ELF zone and the STACK zone,
286//   as defined in the kernel_config.h file.
287// - The malloc library uses the mmap() syscall to create - on demand -
288//   one vseg in a given cluster. The size of this vseg is defined below
289//   by the MALLOC_LOCAL_STORE_SIZE parameter.
290// - For a standard malloc(), the target cluster is the cluster containing
291//   the core running the client thread.
292// - For a remote_malloc(), the target cluster is explicitely defined
293//   by the argument.
294// - In each cluster, the available storage in virtual space is handled by a
295//   local allocator using the buddy algorithm.
296//
297// TODO : In this first implementation one single - fixed size - vseg
298//        is allocated on demand in each cluster.
299//        We should introduce the possibility to dynamically allocate
300//        several vsegs in each cluster, using several mmap when required.
301/////////////////////////////////////////////////////////////////////////////////////////
302// Free blocks organisation in each cluster :
303// - All free blocks have a size that is a power of 2, larger or equal
304//   to MALLOC_MIN_BLOCK_SIZE (typically 64 bytes).
305// - All free blocks are aligned.
306// - They are pre-classed in an array of linked lists, where all blocks in a
307//   given list have the same size.
308// - The NEXT pointer implementing those linked lists is written
309//   in the first bytes of the block itself, using the unsigned int type.
310// - The pointers on the first free block for each size are stored in an
311//   array of pointers free[32] in the storage(x,y) descriptor.
312/////////////////////////////////////////////////////////////////////////////////////////
313// Allocation policy:
314// - The block size required by the user can be any value, but the allocated
315//   block size can be larger than the requested size:
316// - The allocator computes actual_size, that is the smallest power of 2
317//   value larger or equal to the requested size AND larger or equal to
318//   MALLOC_MIN_BLOCK_SIZE.
319// - It pop the linked list of free blocks corresponding to actual_size,
320//   and returns the block B if the list[actual_size] is not empty.
321// - If the list[actual_size] is empty, it pop the list[actual_size * 2].
322//   If a block B' is found, it breaks this block in 2 B/2 blocks, returns
323//   the first B/2 block and push the other B/2 block into list[actual_size].
324// - If the list[actual_size * 2] is empty, it pop the list[actual_size * 4].
325//   If a block B is found, it break this block in 3 blocks B/4, B/4 and B/2,
326//   returns the first B/4 block, push the other blocks B/4 and B/2 into
327//   the proper lists. etc...
328// - If no block satisfying the request is available it returns a failure
329//   (NULL pointer).
330// - This allocation policy has the nice following property:
331//   If the vseg is aligned (the vseg base is a multiple of the
332//   vseg size), all allocated blocks are aligned on the actual_size.
333/////////////////////////////////////////////////////////////////////////////////////////
334// Free policy:
335// - Each allocated block is registered in an alloc[] array of unsigned char.
336// - This registration is required by the free() operation, because the size
337//   of the allocated block must be obtained from the base address of the block. 
338// - The number of entries in this array is equal to the max number
339//   of allocated block : MALLOC_LOCAL_STORE_SIZE / MALLOC_MIN_BLOCK_SIZE.
340// - For each allocated block, the value registered in the alloc[] array
341//   is log2( size_of_allocated_block ).
342// - The index in this array is computed from the allocated block base address:
343//      index = (block_base - vseg_base) / MALLOC_MIN_BLOCK_SIZE
344// - The alloc[] array is stored at the end of heap segment. This consume
345//   (1 / MALLOC_MIN_BLOCK_SIZE) of the total storage capacity.
346/////////////////////////////////////////////////////////////////////////////////////////
347
348
349#define MALLOC_INITIALIZED         0xBABEF00D   // magic number when initialised
350#define MALLOC_MIN_BLOCK_SIZE      0x40         // 64 bytes
351#define MALLOC_LOCAL_STORE_SIZE    0x800000     // 8 Mbytes     
352#define MALLOC_MAX_CLUSTERS        0x100        // 256 clusters
353
354/////////////////////////////////////////////////////////////////////////////////////////
355//               store(x,y) descriptor (one per cluster)
356/////////////////////////////////////////////////////////////////////////////////////////
357
358typedef struct malloc_store_s
359{
360    pthread_mutex_t mutex;           // lock protecting exclusive access to local heap
361    unsigned int    initialized;     // initialised when value == MALLOC_INITIALIZED
362    unsigned int    cxy;             // cluster identifier 
363    unsigned int    store_base;      // store base address
364    unsigned int    store_size;      // store size (bytes)
365    unsigned int    alloc_base;      // alloc[] array base address
366    unsigned int    alloc_size;      // alloc[] array size (bytes)
367    unsigned int    free[32];        // array of addresses of first free block
368} 
369malloc_store_t;
370
371/*****************************************************************************************
372 * This function allocates <size> bytes of memory in user space, and returns a pointer
373 * to the allocated buffer. The pysical memory is allocated from store located in
374 * cluster identified by the <cxy> argument.
375 *****************************************************************************************
376 * @ size    : number of requested bytes.
377 * @ cxy     : target cluster identifier.
378 * @ returns a pointer on the allocated buffer if success / returns NULL if failure
379 ****************************************************************************************/
380void * remote_malloc( unsigned int size, 
381                      unsigned int cxy );
382
383/*****************************************************************************************
384 * This function releases the memory buffer identified by the <ptr> argument,
385 * to the store identified by the <cxy> argument.
386 * It displays an error message, but does nothing if the ptr is illegal.
387 *****************************************************************************************
388 * @ ptr   : pointer on the released buffer.
389 * @ cxy   : target cluster identifier.
390 ****************************************************************************************/
391void remote_free( void        * ptr,
392                  unsigned int  cxy );
393
394/*****************************************************************************************
395 * This function releases the memory buffer identified by the <ptr> argument,
396 * to the store located in cluster identified by the <cxy> argument, and allocates
397 * a new buffer containing <size> bytes from this store.
398 * The content of the old buffer is copied to the new buffer, up to <size> bytes.
399 * It displays an error message, but does nothing if the ptr is illegal.
400 *****************************************************************************************
401 * @ ptr     : pointer on the released buffer.
402 * @ size    : new buffer requested size (bytes).
403 * @ cxy     : target cluster identifier.
404 * @ return a pointer on allocated buffer if success / return NULL if failure
405 ****************************************************************************************/
406void * remote_realloc( void        * ptr,
407                       unsigned int  size,
408                       unsigned int  cxy );
409
410/*****************************************************************************************
411 * This function allocates enough space for <count> objects that are <size> bytes
412 * of memory each from the store located in cluster identied by the <cxy> argument.
413 * The allocated memory is filled with bytes of value zero.
414 *****************************************************************************************
415 * @ count   : number of requested objects.
416 * @ size    : number of bytes per object.
417 * @ cxy     : target cluster identifier.
418 * @ returns a pointer on allocated buffer if success / returns NULL if failure
419 ****************************************************************************************/
420void * remote_calloc( unsigned int count,
421                      unsigned int size,
422                      unsigned int cxy );
423
424#endif /* _LIBALMOSMKH_H_ */
425
Note: See TracBrowser for help on using the repository browser.