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

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

Fix a bug in the vmm_remove_vseg() function: the physical pages
associated to an user DATA vseg were released to the kernel when
the target process descriptor was in the reference cluster.
This physical pages release should be done only when the page
forks counter value is zero.
All other modifications are cosmetic.

File size: 22.5 KB
RevLine 
[445]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
[444]24#ifndef _LIBALMOSMKH_H_
25#define _LIBALMOSMKH_H_
26
[445]27/***************************************************************************************
[457]28 * This file defines an user level, ALMOS-MKH specific library, containing:
[445]29 * - non standard system calls.
30 * - debug functions.
31 * - remote malloc extensions.
32 **************************************************************************************/
33
[444]34#include <pthread.h>
[445]35#include <shared_almos.h>
[444]36
[445]37/****************** Non standard (ALMOS_MKH specific) system calls ********************/
[444]38
39
[445]40/***************************************************************************************
[589]41 * This syscall gives the process identified by the <pid> argument the exclusive
42 * ownership of its TXT terminal.
[445]43 ***************************************************************************************
[444]44 * @ pid        : process identifier.
45 * @ returns O if success / returns -1 if process not found.
[445]46 **************************************************************************************/
[444]47int fg( unsigned int pid );
48
49/***************************************************************************************
[589]50 * This syscall stores in the buffer identified by the <owner> argument a non zero
[457]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/***************************************************************************************
[589]62 * This syscall returns the hardware platform parameters.
[444]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/***************************************************************************************
[589]74 * This syscall returns the cluster an local index for the calling core.
[444]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
[589]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
[444]101/***************************************************************************************
[589]102 * This syscall implements the operations related to User Thread Local Storage.
[445]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/***************************************************************************************
[589]112 * This syscall returns an unsigned 32 bits integer from the standard "stdin" stream.
[580]113 * Both decimal numbers and hexadecimal numbers (prefixed by 0x) are supported.
[445]114 ***************************************************************************************
115 * returns the integer value if success / returns -1 if failure.
116 **************************************************************************************/
[589]117unsigned int get_uint32( void );
[445]118
119
120/***************** Non standard (ALMOS-MKH specific) debug functions ******************/
121
122
123/***************************************************************************************
[589]124 * This debug syscall displays on the kernel terminal TXT0
[444]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
[610]134 * the state of the  VMM for the process <pid> in cluster <cxy>.
[444]135 * It can be called by any thread running in any cluster.
136 ***************************************************************************************
[625]137 * @ cxy      : [in] target cluster identifier.
[444]138 * @ pid      : [in] process identifier.
139 * @ return 0 if success / return -1 if illegal argument.
140 **************************************************************************************/
[597]141int display_vmm(unsigned int cxy, unsigned int pid );
[444]142
143/***************************************************************************************
[589]144 * This debug syscall displays on the kernel terminal TXT0
[444]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/***************************************************************************************
[589]156 * This debug syscall displays on the kernel terminal TXT0
[444]157 * the list of process registered in a given cluster identified by the <cxy> argument.
[589]158 * Only the owned processes are displayed when the <owned> argument is non zero.
[444]159 * It can be called by any thread running in any cluster.
160 ***************************************************************************************
161 * @ cxy      : [in] target cluster identifier.
[589]162 * @ owned    : [in] only owned processes if non zero.
[444]163 * @ return 0 if success / return -1 if illegal argument.
164 **************************************************************************************/
[589]165int display_cluster_processes( unsigned int  cxy,
166                               unsigned int  owned );
[444]167
168/***************************************************************************************
[589]169 * This debug syscall displays on the kernel terminal TXT0
[445]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/***************************************************************************************
[589]179 * This debug syscall displays on the kernel terminal TXT0
[597]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
[444]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 **************************************************************************************/
[478]197int display_chdev( void );
[444]198
199/***************************************************************************************
[589]200 * This debug syscall displays on the kernel terminal TXT0
[444]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 **************************************************************************************/
[478]206int display_vfs( void );
[444]207
208/***************************************************************************************
[589]209 * This debug syscall displays on the kernel terminal TXT0 the current DQDT state.
[444]210 * It can be called by any thread running in any cluster.
211 ***************************************************************************************
212 * @ return always 0.
213 **************************************************************************************/
[478]214int display_dqdt( void );
[444]215
[611]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
[623]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
[444]240/*****************************************************************************************
[589]241* This debug syscall is used to activate / desactivate the context switches trace
[444]242* for a core identified by the <cxy> and <lid> arguments.
243* It can be called by any thread running in any cluster.
244*****************************************************************************************
245* @ active     : activate trace if non zero / desactivate if zero.
246* @ cxy        : cluster identifier.
247* @ lid        : core local index.
248* @ returns O if success / returns -1 if illegal arguments.
249****************************************************************************************/
250int trace( unsigned int active,
[450]251           unsigned int cxy, 
252           unsigned int lid );
[444]253
[445]254/****************************************************************************************
[589]255 * This syscall implements an user-level interactive debugger that can be
[445]256 * introduced in any user application to display various kernel distributed structures.
257 * The supported commands are:
258 * - p (cxy)     : display all processes descriptors in a given cluster.
259 * - s (cxy,lid) : display all threads attached to a given core in a given cluster.
260 * - v (cxy)     : display the calling process VMM in a given cluster.
261 * - t (tid)     : display all owner process descriptors attached to a TXT terminal.
262 * - x           : force the calling process to exit.
263 * - c           : continue calling process execution.
264 * - h           : list the supported commands
265 ***************************************************************************************/
[478]266void idbg( void );
[444]267
268
[445]269/****************** Non standard (ALMOS-MKH specific) malloc operations  ***************/
[444]270
[445]271/////////////////////////////////////////////////////////////////////////////////////////
[444]272// General principles:
273// - In user space the HEAP zone spread between the ELF zone and the STACK zone,
274//   as defined in the kernel_config.h file.
275// - The malloc library uses the mmap() syscall to create - on demand -
276//   one vseg in a given cluster. The size of this vseg is defined below
277//   by the MALLOC_LOCAL_STORE_SIZE parameter.
278// - For a standard malloc(), the target cluster is the cluster containing
279//   the core running the client thread.
280// - For a remote_malloc(), the target cluster is explicitely defined
281//   by the argument.
282// - In each cluster, the available storage in virtual space is handled by a
283//   local allocator using the buddy algorithm.
284//
285// TODO : In this first implementation one single - fixed size - vseg
286//        is allocated on demand in each cluster.
287//        We should introduce the possibility to dynamically allocate
288//        several vsegs in each cluster, using several mmap when required.
[445]289/////////////////////////////////////////////////////////////////////////////////////////
[444]290// Free blocks organisation in each cluster :
291// - All free blocks have a size that is a power of 2, larger or equal
292//   to MALLOC_MIN_BLOCK_SIZE (typically 64 bytes).
293// - All free blocks are aligned.
294// - They are pre-classed in an array of linked lists, where all blocks in a
295//   given list have the same size.
296// - The NEXT pointer implementing those linked lists is written
297//   in the first bytes of the block itself, using the unsigned int type.
298// - The pointers on the first free block for each size are stored in an
299//   array of pointers free[32] in the storage(x,y) descriptor.
[445]300/////////////////////////////////////////////////////////////////////////////////////////
[444]301// Allocation policy:
302// - The block size required by the user can be any value, but the allocated
303//   block size can be larger than the requested size:
304// - The allocator computes actual_size, that is the smallest power of 2
305//   value larger or equal to the requested size AND larger or equal to
306//   MALLOC_MIN_BLOCK_SIZE.
307// - It pop the linked list of free blocks corresponding to actual_size,
308//   and returns the block B if the list[actual_size] is not empty.
309// - If the list[actual_size] is empty, it pop the list[actual_size * 2].
310//   If a block B' is found, it breaks this block in 2 B/2 blocks, returns
311//   the first B/2 block and push the other B/2 block into list[actual_size].
312// - If the list[actual_size * 2] is empty, it pop the list[actual_size * 4].
313//   If a block B is found, it break this block in 3 blocks B/4, B/4 and B/2,
314//   returns the first B/4 block, push the other blocks B/4 and B/2 into
315//   the proper lists. etc...
316// - If no block satisfying the request is available it returns a failure
317//   (NULL pointer).
318// - This allocation policy has the nice following property:
319//   If the vseg is aligned (the vseg base is a multiple of the
320//   vseg size), all allocated blocks are aligned on the actual_size.
[445]321/////////////////////////////////////////////////////////////////////////////////////////
[444]322// Free policy:
323// - Each allocated block is registered in an alloc[] array of unsigned char.
324// - This registration is required by the free() operation, because the size
325//   of the allocated block must be obtained from the base address of the block. 
326// - The number of entries in this array is equal to the max number
327//   of allocated block : MALLOC_LOCAL_STORE_SIZE / MALLOC_MIN_BLOCK_SIZE.
328// - For each allocated block, the value registered in the alloc[] array
329//   is log2( size_of_allocated_block ).
330// - The index in this array is computed from the allocated block base address:
331//      index = (block_base - vseg_base) / MALLOC_MIN_BLOCK_SIZE
332// - The alloc[] array is stored at the end of heap segment. This consume
333//   (1 / MALLOC_MIN_BLOCK_SIZE) of the total storage capacity.
[445]334/////////////////////////////////////////////////////////////////////////////////////////
[444]335
336
337#define MALLOC_INITIALIZED         0xBABEF00D   // magic number when initialised
338#define MALLOC_MIN_BLOCK_SIZE      0x40         // 64 bytes
339#define MALLOC_LOCAL_STORE_SIZE    0x800000     // 8 Mbytes     
340#define MALLOC_MAX_CLUSTERS        0x100        // 256 clusters
341
[445]342/////////////////////////////////////////////////////////////////////////////////////////
343//               store(x,y) descriptor (one per cluster)
344/////////////////////////////////////////////////////////////////////////////////////////
[444]345
346typedef struct malloc_store_s
347{
[445]348    pthread_mutex_t mutex;           // lock protecting exclusive access to local heap
[444]349    unsigned int    initialized;     // initialised when value == MALLOC_INITIALIZED
350    unsigned int    cxy;             // cluster identifier 
351    unsigned int    store_base;      // store base address
352    unsigned int    store_size;      // store size (bytes)
353    unsigned int    alloc_base;      // alloc[] array base address
354    unsigned int    alloc_size;      // alloc[] array size (bytes)
355    unsigned int    free[32];        // array of addresses of first free block
356} 
357malloc_store_t;
358
359/*****************************************************************************************
360 * This function allocates <size> bytes of memory in user space, and returns a pointer
361 * to the allocated buffer. The pysical memory is allocated from store located in
362 * cluster identified by the <cxy> argument.
363 *****************************************************************************************
364 * @ size    : number of requested bytes.
365 * @ cxy     : target cluster identifier.
366 * @ returns a pointer on the allocated buffer if success / returns NULL if failure
367 ****************************************************************************************/
368void * remote_malloc( unsigned int size, 
369                      unsigned int cxy );
370
371/*****************************************************************************************
372 * This function releases the memory buffer identified by the <ptr> argument,
373 * to the store identified by the <cxy> argument.
374 * It displays an error message, but does nothing if the ptr is illegal.
375 *****************************************************************************************
376 * @ ptr   : pointer on the released buffer.
377 * @ cxy   : target cluster identifier.
378 ****************************************************************************************/
379void remote_free( void        * ptr,
380                  unsigned int  cxy );
381
382/*****************************************************************************************
383 * This function releases the memory buffer identified by the <ptr> argument,
384 * to the store located in cluster identified by the <cxy> argument, and allocates
385 * a new buffer containing <size> bytes from this store.
386 * The content of the old buffer is copied to the new buffer, up to <size> bytes.
387 * It displays an error message, but does nothing if the ptr is illegal.
388 *****************************************************************************************
389 * @ ptr     : pointer on the released buffer.
390 * @ size    : new buffer requested size (bytes).
391 * @ cxy     : target cluster identifier.
392 * @ return a pointer on allocated buffer if success / return NULL if failure
393 ****************************************************************************************/
394void * remote_realloc( void        * ptr,
395                       unsigned int  size,
396                       unsigned int  cxy );
[445]397
[444]398/*****************************************************************************************
399 * This function allocates enough space for <count> objects that are <size> bytes
400 * of memory each from the store located in cluster identied by the <cxy> argument.
401 * The allocated memory is filled with bytes of value zero.
402 *****************************************************************************************
403 * @ count   : number of requested objects.
404 * @ size    : number of bytes per object.
405 * @ cxy     : target cluster identifier.
406 * @ returns a pointer on allocated buffer if success / returns NULL if failure
407 ****************************************************************************************/
408void * remote_calloc( unsigned int count,
409                      unsigned int size,
410                      unsigned int cxy );
411
412#endif /* _LIBALMOSMKH_H_ */
413
Note: See TracBrowser for help on using the repository browser.