Changeset 581 for trunk/libs


Ignore:
Timestamp:
Oct 10, 2018, 3:11:53 PM (6 years ago)
Author:
alain
Message:

1) Improve the busylock debug infrastructure.
2) introduce a non-distributed, but portable implementation for the pthread_barrier.

Location:
trunk/libs/libpthread
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/libs/libpthread/pthread.c

    r573 r581  
    3131#include <syscalls_numbers.h>
    3232
    33 #define PTHREAD_BARRIER_DEBUG   0
    3433
    3534////////////////////////////////////////////////////////////////////////////////////////////
     
    7372}
    7473
    75 ///////////////////
     74/////////////////////////
    7675int pthread_yield( void )
    7776{
     
    8079
    8180////////////////////////////////////////////////////////////////////////////////////////////
     81//                               Mutexes
     82////////////////////////////////////////////////////////////////////////////////////////////
     83
     84//////////////////////////////////////////////////////////
     85int pthread_mutex_init( pthread_mutex_t           * mutex,
     86                        const pthread_mutexattr_t * attr )
     87{
     88    if( attr != NULL )
     89    {
     90        printf("\n[ERROR] in %s : <attr> argument not supported\n", __FUNCTION__);
     91        return -1;
     92    }
     93
     94    return hal_user_syscall( SYS_MUTEX,
     95                             (reg_t)mutex,
     96                             MUTEX_INIT,
     97                             0, 0 );
     98}
     99
     100////////////////////////////////////////////////////
     101int pthread_mutex_destroy( pthread_mutex_t * mutex )
     102{
     103    return hal_user_syscall( SYS_MUTEX,
     104                             (reg_t)mutex,
     105                             MUTEX_DESTROY,
     106                             0, 0 );
     107}
     108
     109/////////////////////////////////////////////////
     110int pthread_mutex_lock( pthread_mutex_t * mutex )
     111{
     112    return hal_user_syscall( SYS_MUTEX,
     113                             (reg_t)mutex,
     114                             MUTEX_LOCK,
     115                             0, 0 );
     116}
     117
     118////////////////////////////////////////////////////
     119int pthread_mutex_trylock( pthread_mutex_t * mutex )
     120{
     121    return hal_user_syscall( SYS_MUTEX,
     122                             (reg_t)mutex,
     123                             MUTEX_TRYLOCK,
     124                             0, 0 );
     125}
     126   
     127///////////////////////////////////////////////////
     128int pthread_mutex_unlock( pthread_mutex_t * mutex )
     129{
     130    return hal_user_syscall( SYS_MUTEX,
     131                             (reg_t)mutex,
     132                             MUTEX_UNLOCK,
     133                             0, 0 );
     134}
     135
     136////////////////////////////////////////////////////////////////////////////////////////////
     137//                               Condvars
     138////////////////////////////////////////////////////////////////////////////////////////////
     139
     140///////////////////////////////////////////////
     141int pthread_cond_init( pthread_cond_t     * cond,
     142                       pthread_condattr_t * attr )
     143{
     144    if( attr )
     145    {
     146        printf("[ERROR] in %s ; <attr> argument must be NULL\n", __FUNCTION__ );
     147        return -1;
     148    }
     149
     150   return hal_user_syscall( SYS_CONDVAR,
     151                             (reg_t)cond,
     152                             CONDVAR_INIT,
     153                             0, 0 );
     154}
     155
     156/////////////////////////////////////////////////
     157int pthread_cond_destroy( pthread_cond_t * cond )
     158{
     159    return hal_user_syscall( SYS_CONDVAR,
     160                             (reg_t)cond,
     161                             CONDVAR_DESTROY,
     162                             0, 0 );
     163}
     164
     165//////////////////////////////////////////////
     166int pthread_cond_wait( pthread_cond_t  * cond,
     167                       pthread_mutex_t * mutex )
     168{
     169    return hal_user_syscall( SYS_CONDVAR,
     170                             (reg_t)cond,
     171                             CONDVAR_WAIT,
     172                             (reg_t)mutex,
     173                             0 );
     174}
     175
     176////////////////////////////////////////////////
     177int pthread_cond_signal( pthread_cond_t * cond )
     178{
     179    return hal_user_syscall( SYS_CONDVAR,
     180                             (reg_t)cond,
     181                             CONDVAR_SIGNAL,
     182                             0, 0 );
     183}
     184
     185///////////////////////////////////////////////////
     186int pthread_cond_broadcast( pthread_cond_t * cond )
     187{
     188    return hal_user_syscall( SYS_CONDVAR,
     189                             (reg_t)cond,
     190                             CONDVAR_BROADCAST,
     191                             0, 0 );
     192}
     193
     194
     195////////////////////////////////////////////////////////////////////////////////////////////
    82196//                            Barriers
    83197////////////////////////////////////////////////////////////////////////////////////////////
     198
     199////////////////////////////////////////////////////////////////
     200int pthread_barrier_init( pthread_barrier_t           * barrier,
     201                          const pthread_barrierattr_t * attr,
     202                          unsigned int                  count )
     203{
     204    return hal_user_syscall( SYS_BARRIER,
     205                             (reg_t)barrier,
     206                             BARRIER_INIT,
     207                             (reg_t)count,
     208                             0 );
     209}
     210
     211//////////////////////////////////////////////////////////
     212int pthread_barrier_destroy( pthread_barrier_t * barrier )
     213{
     214    return hal_user_syscall( SYS_BARRIER,
     215                             (reg_t)barrier,
     216                             BARRIER_DESTROY,
     217                             0, 0 );
     218}
     219   
     220///////////////////////////////////////////////////////
     221int pthread_barrier_wait( pthread_barrier_t * barrier )
     222{
     223    return hal_user_syscall( SYS_BARRIER,
     224                             (reg_t)barrier,
     225                             BARRIER_WAIT,
     226                             0, 0 );
     227}
     228
     229/*
     230
     231////////////////////////////////////////////////////////////////////////////////////////////
     232// The following functions define another implementation for the POSX barrier
     233// based on a distributed quadtree implemented in user space, and relying
     234// on a busy waiting policy.
     235////////////////////////////////////////////////////////////////////////////////////////////
     236
    84237
    85238////////////////////////////////////////////////////////////////////////////////////////////
     
    359512}  // end pthread_barrier_wait()
    360513
    361 ////////////////////////////////////////////////////////////////////////////////////////////
    362 //                               Mutexes
    363 ////////////////////////////////////////////////////////////////////////////////////////////
    364 
    365 //////////////////////////////////////////////////////////
    366 int pthread_mutex_init( pthread_mutex_t           * mutex,
    367                         const pthread_mutexattr_t * attr )
    368 {
    369     if( attr != NULL )
    370     {
    371         printf("\n[ERROR] in %s : <attr> argument not supported\n", __FUNCTION__);
    372         return -1;
    373     }
    374 
    375     return hal_user_syscall( SYS_MUTEX,
    376                              (reg_t)mutex,
    377                              MUTEX_INIT,
    378                              0, 0 );
    379 }
    380 
    381 ////////////////////////////////////////////////////
    382 int pthread_mutex_destroy( pthread_mutex_t * mutex )
    383 {
    384     return hal_user_syscall( SYS_MUTEX,
    385                              (reg_t)mutex,
    386                              MUTEX_DESTROY,
    387                              0, 0 );
    388 }
    389 
    390 /////////////////////////////////////////////////
    391 int pthread_mutex_lock( pthread_mutex_t * mutex )
    392 {
    393     return hal_user_syscall( SYS_MUTEX,
    394                              (reg_t)mutex,
    395                              MUTEX_LOCK,
    396                              0, 0 );
    397 }
    398 
    399 ////////////////////////////////////////////////////
    400 int pthread_mutex_trylock( pthread_mutex_t * mutex )
    401 {
    402     return hal_user_syscall( SYS_MUTEX,
    403                              (reg_t)mutex,
    404                              MUTEX_TRYLOCK,
    405                              0, 0 );
    406 }
    407    
    408 ///////////////////////////////////////////////////
    409 int pthread_mutex_unlock( pthread_mutex_t * mutex )
    410 {
    411     return hal_user_syscall( SYS_MUTEX,
    412                              (reg_t)mutex,
    413                              MUTEX_UNLOCK,
    414                              0, 0 );
    415 }
    416 
    417 ////////////////////////////////////////////////////////////////////////////////////////////
    418 //                               Condition variable
    419 ////////////////////////////////////////////////////////////////////////////////////////////
    420 
    421 ///////////////////////////////////////////////
    422 int pthread_cond_init( pthread_cond_t     * cond,
    423                        pthread_condattr_t * attr )
    424 {
    425     if( attr )
    426     {
    427         printf("[ERROR] in %s ; <attr> argument must be NULL\n", __FUNCTION__ );
    428         return -1;
    429     }
    430 
    431    return hal_user_syscall( SYS_CONDVAR,
    432                              (reg_t)cond,
    433                              CONDVAR_INIT,
    434                              0, 0 );
    435 }
    436 
    437 /////////////////////////////////////////////////
    438 int pthread_cond_destroy( pthread_cond_t * cond )
    439 {
    440     return hal_user_syscall( SYS_CONDVAR,
    441                              (reg_t)cond,
    442                              CONDVAR_DESTROY,
    443                              0, 0 );
    444 }
    445 
    446 //////////////////////////////////////////////
    447 int pthread_cond_wait( pthread_cond_t  * cond,
    448                        pthread_mutex_t * mutex )
    449 {
    450     return hal_user_syscall( SYS_CONDVAR,
    451                              (reg_t)cond,
    452                              CONDVAR_WAIT,
    453                              (reg_t)mutex,
    454                              0 );
    455 }
    456 
    457 ////////////////////////////////////////////////
    458 int pthread_cond_signal( pthread_cond_t * cond )
    459 {
    460     return hal_user_syscall( SYS_CONDVAR,
    461                              (reg_t)cond,
    462                              CONDVAR_SIGNAL,
    463                              0, 0 );
    464 }
    465 
    466 ///////////////////////////////////////////////////
    467 int pthread_cond_broadcast( pthread_cond_t * cond )
    468 {
    469     return hal_user_syscall( SYS_CONDVAR,
    470                              (reg_t)cond,
    471                              CONDVAR_BROADCAST,
    472                              0, 0 );
    473 }
    474 
    475 
    476 
     514*/
    477515
    478516
  • trunk/libs/libpthread/pthread.h

    r573 r581  
    2525#define _PTHREAD_H_
    2626
     27#include <shared_pthread.h>
     28
    2729//////////////////////////////////////////////////////////////////////////////////////////////
    2830//             POSIX thread related functions
    29 //
    30 //  This include the thread creation/destruction, as well as the synchronisations:
    31 //  barriers, mutexes, and condition variables.
    32 //////////////////////////////////////////////////////////////////////////////////////////////
    33 
    34 #include <shared_pthread.h>
     31//////////////////////////////////////////////////////////////////////////////////////////////
    3532
    3633/*********************************************************************************************
     
    9087
    9188//////////////////////////////////////////////////////////////////////////////////////////////
    92 //                 POSIX barrier related functions
    93 //
    94 // These functions are implemented in user space. Only the pthread_barrier_init() function
    95 // uses system calls to build the distributed quad-tree infrastructure.
    96 //////////////////////////////////////////////////////////////////////////////////////////////
    97 
    98 /*********************************************************************************************
    99  * These structures defines a hierarchical, POSIX compliant, barrier.
    100  * - If the barrier attribute in the pthread_barrier_init() is NULL, it is implemented
    101  *   as a simple, sense reversing barrier, localised in the calling thread cluster.
    102  * - If the barrier attribute is defined, it is implemented as a hierarchical, physically
    103  *   distributed quad-tree, covering all clusters specified, with the following constraints:
    104  *   . The involved clusters form a mesh [x_size * y_size]
    105  *   . The lower left involved cluster is cluster(0,0) 
    106  *   . The number of threads per cluster is the same in all clusters.
    107  *
    108  * Implementation note:
    109  * - The quad three is implemented as a three dimensions array of node[x][y][l]
    110  *   . [x][y] are the cluster coordinates / max values are (QDT_XMAX-1), (QDT_YMAX-1)
    111  *   . [l] is the node level / 0 for terminal nodes / (QDT_LMAX-1) for the root node
    112  ********************************************************************************************/
    113 
    114 #define  QDT_XMAX    16                /*! max number of clusters in a row                  */
    115 #define  QDT_YMAX    16                /*! max number of clusters in a column               */
    116 #define  QDT_LMAX    5                 /*! max depth of the quad tree                       */
    117 #define  QDT_YWIDTH  4                 /*! Y field in cxy, for cxy <=> (x,y) translation    */
    118 #define  QDT_YMASK   0xF               /*! Y field in cxy, for cxy <=> (x,y) translation    */
    119 
    120 typedef struct sqt_node_s
    121 {
    122     volatile unsigned int sense;       /*! barrier state (toggle)                           */
    123     volatile unsigned int count;       /*! number of not arrived tasks                      */
    124     unsigned int          arity;       /*! number of locally expected tasks                 */
    125     unsigned int          level;       /*! hierarchical level (0 is bottom)                 */
    126     struct sqt_node_s   * parent;      /*! pointer on parent node (NULL for root)           */
    127     struct sqt_node_s   * child[4];    /*! pointer on children node (NULL for bottom)       */
    128 }
    129 sqt_node_t;
    130 
    131 typedef struct pthread_barrier_s
    132 {
    133     sqt_node_t          * node[QDT_XMAX][QDT_YMAX][QDT_LMAX];
    134 }
    135 pthread_barrier_t;
    136 
    137 typedef struct pthread_barrierattr_s
    138 {
    139     unsigned int          x_size;      /*! number of clusters in a row (0 to x_size-1)      */
    140     unsigned int          y_size;      /*! number of clusters in a column (0 to y_size-1)   */
    141     unsigned int          nthreads;    /*! number of expected threads in a cluster          */
    142 }
    143 pthread_barrierattr_t;
     89//                      POSIX mutex related functions
     90//////////////////////////////////////////////////////////////////////////////////////////////
     91
     92/*********************************************************************************************
     93 * This function initialise the mutex identified by the <mutex> argument.
     94 * The <attr> argument is not supported yet, and must be NULL.
     95 *********************************************************************************************
     96 * @ mutex     : pointer on mutex in user space.
     97 * @ attr      : pointer on attributes structure / must be NULL.
     98 * @ return 0 if success / return -1 if failure.
     99 ********************************************************************************************/
     100int pthread_mutex_init( pthread_mutex_t           * mutex,
     101                        const pthread_mutexattr_t * attr );
     102
     103/*********************************************************************************************
     104 * This function destroy the mutex identified by the <mutex> argument.
     105 *********************************************************************************************
     106 * @ mutex     : pointer on mutex in user space.
     107 * @ return 0 if success / return -1 if failure.
     108 ********************************************************************************************/
     109int pthread_mutex_destroy( pthread_mutex_t * mutex );
     110
     111/*********************************************************************************************
     112 * This bloking function locks the mutex identified by the <mutex> argument,
     113 * and blocks until it becomes available.
     114 *********************************************************************************************
     115 * @ mutex     : pointer on mutex in user space.
     116 * @ return 0 if success / return -1 if failure.
     117 ********************************************************************************************/
     118int pthread_mutex_lock( pthread_mutex_t * mutex );
     119
     120/*********************************************************************************************
     121 * This function unlocks the mutex identified by the <mutex> argument.
     122 *********************************************************************************************
     123 * @ mutex     : pointer on mutex in user space.
     124 * @ return 0 if success / return -1 if failure.
     125 ********************************************************************************************/
     126int pthread_mutex_unlock( pthread_mutex_t * mutex );
     127
     128/*********************************************************************************************
     129 * This function tries to lock the mutex identified by the <mutex> argument,
     130 * but don't block if the mutex is locked by another thread, including the current thread.
     131 *********************************************************************************************
     132 * @ mutex     : pointer on mutex in user space.
     133 * @ return 0 if success / return -1 if mutex already taken.
     134 ********************************************************************************************/
     135int pthread_mutex_trylock( pthread_mutex_t * mutex );
     136
     137
     138//////////////////////////////////////////////////////////////////////////////////////////////
     139//                      POSIX condvar related functions
     140//////////////////////////////////////////////////////////////////////////////////////////////
     141
     142/*********************************************************************************************
     143 * This function initializes a condition variable identified by the <cond> argument.
     144 * WARNING: the <attr> argument is not supported and must be NULL.
     145 *********************************************************************************************
     146 * @ cond   : [in] pointer on condition in user space.
     147 * @ attr   : [in] pointer on condition attribute (must be NULL).
     148 * @ return 0 if success / return -1 if failure.
     149 ********************************************************************************************/
     150int pthread_cond_init( pthread_cond_t     * cond,
     151                       pthread_condattr_t * attr );
     152
     153/*********************************************************************************************
     154 * This function atomically unlocks the <mutex> and blocks the calling thread on the
     155 * condition specified by the <cond> argument.  The thread unblocks only after another
     156 * thread calls the pthread_cond_signal() or pthread_cond_broadcast() functions with the
     157 * same condition variable.  The mutex must be locked before calling this function,
     158 * otherwise the behavior is undefined. Before the pthread_cond_wait() function returns
     159 * to the calling function, it re-acquires the <mutex>.
     160 *********************************************************************************************
     161 * @ cond      : pointer on condition in user space.
     162 * @ mutex     : pointer on mutex in user space.
     163 * @ return 0 if success / return -1 if failure.
     164 ********************************************************************************************/
     165int pthread_cond_wait( pthread_cond_t  * cond,
     166                       pthread_mutex_t * mutex );
     167
     168/*********************************************************************************************
     169 * This function unblocks one thread blocked on condition specified by the <cond> argument.
     170 *********************************************************************************************
     171 * @ cond      : pointer on condition in user space.
     172 * @ return 0 if success / return -1 if failure.
     173 ********************************************************************************************/
     174int pthread_cond_signal( pthread_cond_t * cond );
     175
     176/*********************************************************************************************
     177 * This function unblocks all threads blocked on condition specified by the <cond> argument.
     178 *********************************************************************************************
     179 * @ cond      : pointer on condition in user space.
     180 * @ return 0 if success / return -1 if failure.
     181 ********************************************************************************************/
     182int pthread_cond_broadcast( pthread_cond_t * cond );
     183
     184/*********************************************************************************************
     185 * This function delete the condition variable specified by the <cond> argument.
     186 *********************************************************************************************
     187 * @ cond      : pointer on condition in user space.
     188 * @ return 0 if success / return -1 if failure.
     189 ********************************************************************************************/
     190int pthread_cond_destroy( pthread_cond_t * cond );
     191
     192
     193//////////////////////////////////////////////////////////////////////////////////////////////
     194//                    POSIX barrier related functions
     195//////////////////////////////////////////////////////////////////////////////////////////////
    144196
    145197/*********************************************************************************************
     
    186238   
    187239
    188 //////////////////////////////////////////////////////////////////////////////////////////////
    189 //                      POSIX mutex related functions
    190 //////////////////////////////////////////////////////////////////////////////////////////////
    191 
    192 /*********************************************************************************************
    193  * This function initialise the mutex identified by the <mutex> argument.
    194  * The <attr> argument is not supported yet, and must be NULL.
    195  *********************************************************************************************
    196  * @ mutex     : pointer on mutex in user space.
    197  * @ attr      : pointer on attributes structure / must be NULL.
    198  * @ return 0 if success / return -1 if failure.
    199  ********************************************************************************************/
    200 int pthread_mutex_init( pthread_mutex_t           * mutex,
    201                         const pthread_mutexattr_t * attr );
    202 
    203 /*********************************************************************************************
    204  * This function destroy the mutex identified by the <mutex> argument.
    205  *********************************************************************************************
    206  * @ mutex     : pointer on mutex in user space.
    207  * @ return 0 if success / return -1 if failure.
    208  ********************************************************************************************/
    209 int pthread_mutex_destroy( pthread_mutex_t * mutex );
    210 
    211 /*********************************************************************************************
    212  * This bloking function locks the mutex identified by the <mutex> argument,
    213  * and blocks until it becomes available.
    214  *********************************************************************************************
    215  * @ mutex     : pointer on mutex in user space.
    216  * @ return 0 if success / return -1 if failure.
    217  ********************************************************************************************/
    218 int pthread_mutex_lock( pthread_mutex_t * mutex );
    219 
    220 /*********************************************************************************************
    221  * This function unlocks the mutex identified by the <mutex> argument.
    222  *********************************************************************************************
    223  * @ mutex     : pointer on mutex in user space.
    224  * @ return 0 if success / return -1 if failure.
    225  ********************************************************************************************/
    226 int pthread_mutex_unlock( pthread_mutex_t * mutex );
    227 
    228 /*********************************************************************************************
    229  * This function tries to lock the mutex identified by the <mutex> argument,
    230  * but don't block if the mutex is locked by another thread, including the current thread.
    231  *********************************************************************************************
    232  * @ mutex     : pointer on mutex in user space.
    233  * @ return 0 if success / return -1 if mutex already taken.
    234  ********************************************************************************************/
    235 int pthread_mutex_trylock( pthread_mutex_t * mutex );
    236 
    237 
    238 //////////////////////////////////////////////////////////////////////////////////////////////
    239 //                      POSIX condvar related functions
    240 //////////////////////////////////////////////////////////////////////////////////////////////
    241 
    242 /*********************************************************************************************
    243  * This function initializes a condition variable identified by the <cond> argument.
    244  * WARNING: the <attr> argument is not supported and must be NULL.
    245  *********************************************************************************************
    246  * @ cond   : [in] pointer on condition in user space.
    247  * @ attr   : [in] pointer on condition attribute (must be NULL).
    248  * @ return 0 if success / return -1 if failure.
    249  ********************************************************************************************/
    250 int pthread_cond_init( pthread_cond_t     * cond,
    251                        pthread_condattr_t * attr );
    252 
    253 /*********************************************************************************************
    254  * This function atomically unlocks the <mutex> and blocks the calling thread on the
    255  * condition specified by the <cond> argument.  The thread unblocks only after another
    256  * thread calls the pthread_cond_signal() or pthread_cond_broadcast() functions with the
    257  * same condition variable.  The mutex must be locked before calling this function,
    258  * otherwise the behavior is undefined. Before the pthread_cond_wait() function returns
    259  * to the calling function, it re-acquires the <mutex>.
    260  *********************************************************************************************
    261  * @ cond      : pointer on condition in user space.
    262  * @ mutex     : pointer on mutex in user space.
    263  * @ return 0 if success / return -1 if failure.
    264  ********************************************************************************************/
    265 int pthread_cond_wait( pthread_cond_t  * cond,
    266                        pthread_mutex_t * mutex );
    267 
    268 /*********************************************************************************************
    269  * This function unblocks one thread blocked on condition specified by the <cond> argument.
    270  *********************************************************************************************
    271  * @ cond      : pointer on condition in user space.
    272  * @ return 0 if success / return -1 if failure.
    273  ********************************************************************************************/
    274 int pthread_cond_signal( pthread_cond_t * cond );
    275 
    276 /*********************************************************************************************
    277  * This function unblocks all threads blocked on condition specified by the <cond> argument.
    278  *********************************************************************************************
    279  * @ cond      : pointer on condition in user space.
    280  * @ return 0 if success / return -1 if failure.
    281  ********************************************************************************************/
    282 int pthread_cond_broadcast( pthread_cond_t * cond );
    283 
    284 /*********************************************************************************************
    285  * This function delete the condition variable specified by the <cond> argument.
    286  *********************************************************************************************
    287  * @ cond      : pointer on condition in user space.
    288  * @ return 0 if success / return -1 if failure.
    289  ********************************************************************************************/
    290 int pthread_cond_destroy( pthread_cond_t * cond );
    291 
    292 
    293240
    294241#endif  // _PTHREAD_H_
Note: See TracChangeset for help on using the changeset viewer.