Back to home page

Enduro/X

 
 

    


0001 /**
0002  * @brief System tests, Check locking performance. This is informative
0003  *  does not do any real testing.
0004  *
0005  * @file atmiclt0_locks.c
0006  */
0007 /* -----------------------------------------------------------------------------
0008  * Enduro/X Middleware Platform for Distributed Transaction Processing
0009  * Copyright (C) 2009-2016, ATR Baltic, Ltd. All Rights Reserved.
0010  * Copyright (C) 2017-2023, Mavimax, Ltd. All Rights Reserved.
0011  * This software is released under one of the following licenses:
0012  * AGPL (with Java and Go exceptions) or Mavimax's license for commercial use.
0013  * See LICENSE file for full text.
0014  * -----------------------------------------------------------------------------
0015  * AGPL license:
0016  *
0017  * This program is free software; you can redistribute it and/or modify it under
0018  * the terms of the GNU Affero General Public License, version 3 as published
0019  * by the Free Software Foundation;
0020  *
0021  * This program is distributed in the hope that it will be useful, but WITHOUT ANY
0022  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
0023  * PARTICULAR PURPOSE. See the GNU Affero General Public License, version 3
0024  * for more details.
0025  *
0026  * You should have received a copy of the GNU Affero General Public License along 
0027  * with this program; if not, write to the Free Software Foundation, Inc.,
0028  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
0029  *
0030  * -----------------------------------------------------------------------------
0031  * A commercial use license is available from Mavimax, Ltd
0032  * contact@mavimax.com
0033  * -----------------------------------------------------------------------------
0034  */
0035 #include <string.h>
0036 #include <stdio.h>
0037 #include <stdlib.h>
0038 #include <memory.h>
0039 #include <pthread.h>
0040 #include <unistd.h>
0041 
0042 #include "test000.h"
0043 #include "nstopwatch.h"
0044 
0045 /*---------------------------Externs------------------------------------*/
0046 /*---------------------------Macros-------------------------------------*/
0047 
0048 #define MAX_LOOP    10000000 /* some good number */
0049 /*---------------------------Enums--------------------------------------*/
0050 /*---------------------------Typedefs-----------------------------------*/
0051 /*---------------------------Globals------------------------------------*/
0052 
0053 pthread_rwlock_t M_rwlock = PTHREAD_RWLOCK_INITIALIZER;
0054 long M_rw_spent[2];
0055 long M_mutex_spent[2];
0056 MUTEX_LOCKDECL(M_mutex);
0057 volatile long some_glob=0;
0058 
0059 /*---------------------------Statics------------------------------------*/
0060 /*---------------------------Prototypes---------------------------------*/
0061 
0062 
0063 /**
0064  * This perform read lock on shared mutex
0065  * @param arg
0066  * @return 
0067  */
0068 void* t1_lockedrw(void *arg)
0069 {    
0070     long i;
0071     int ret;
0072     ndrx_stopwatch_t t;
0073     long idx = (long)arg;
0074     
0075     ndrx_stopwatch_reset(&t);
0076     
0077     for (i=0; i<MAX_LOOP; i++)
0078     {
0079         if ((ret=pthread_rwlock_rdlock(&M_rwlock)) != 0) 
0080         {
0081             fprintf(stderr,"can't acquire read lock (%ld): %d\n", (long)arg, ret);
0082             exit(-1);
0083         }
0084         
0085         some_glob++;
0086         
0087         if ((ret=pthread_rwlock_unlock(&M_rwlock)) != 0) 
0088         {
0089             fprintf(stderr,"can't acquire read lock (%ld): %d\n", (long)arg, ret);
0090             exit(-1);
0091         }
0092     }
0093     
0094     M_rw_spent[idx] = ndrx_stopwatch_get_delta(&t);
0095     
0096     return NULL;
0097 }
0098 
0099 /**
0100  * This perform read lock on shared mutex
0101  * @param arg
0102  * @return 
0103  */
0104 void* t1_mutex(void *arg)
0105 {    
0106     long i;
0107     ndrx_stopwatch_t t;
0108     long idx = (long)arg;
0109     ndrx_stopwatch_reset(&t);
0110     
0111     for (i=0; i<MAX_LOOP; i++)
0112     {
0113         MUTEX_LOCK_V(M_mutex);
0114         some_glob++;
0115         MUTEX_UNLOCK_V(M_mutex);
0116     }
0117     
0118     M_mutex_spent[idx] = ndrx_stopwatch_get_delta(&t);
0119     return NULL;
0120 }
0121 
0122 int main( int argc , char **argv )
0123 {
0124     pthread_t pth1={0}, pth2={0};
0125     pthread_t pth3={0}, pth4={0};
0126     void *mb1=(void *)0, *mb2 =(void *)1;
0127     pthread_attr_t pthrat={0};
0128     pthread_attr_init(&pthrat);
0129     pthread_attr_setstacksize(&pthrat, 1<<20);
0130     unsigned int n_pth=0;
0131     long totrw;
0132     long totmut;
0133     int ret;
0134     
0135     fprintf(stderr, "Test RW lock speed...\n");
0136     
0137     if (0!=(ret=pthread_create( &pth1, &pthrat, t1_lockedrw, mb1)))
0138     {
0139         fprintf(stderr, "RW 1 fail create: %d\n", ret);
0140         return -1;
0141     }
0142     
0143     if (0!=(ret=pthread_create( &pth2, &pthrat, t1_lockedrw, mb2)))
0144     {
0145         fprintf(stderr, "RW 2 fail create: %d\n", ret);
0146         return -1;
0147     }
0148     
0149     pthread_join( pth1, NULL );
0150     pthread_join( pth2, NULL );
0151     
0152     
0153     fprintf(stderr, "Test Mutex lock speed...\n");
0154     n_pth=0;
0155     
0156     if (0!=(ret=pthread_create( &pth3, &pthrat, t1_mutex, mb1)))
0157     {
0158         fprintf(stderr, "Mut 1 fail create: %d\n", ret);
0159         return -1;
0160     }
0161     
0162     if (0!=(ret=pthread_create( &pth4, &pthrat, t1_mutex, mb2)))
0163     {
0164         fprintf(stderr, "Mut 2 fail create: %d\n", ret);
0165         return -1;
0166     }
0167     
0168     pthread_join( pth3, NULL );
0169     pthread_join( pth4, NULL );
0170     
0171     pthread_attr_destroy(&pthrat);
0172 
0173     totrw = M_rw_spent[0] + M_rw_spent[1];
0174     totmut = M_mutex_spent[0] + M_mutex_spent[1];
0175     
0176     fprintf(stderr,"Results %ld: rw1: %ld ms rw2: %ld ms, mut1: %ld ms, mut2: %ld ms\n", 
0177             some_glob, M_rw_spent[0], M_rw_spent[1], M_mutex_spent[0], M_mutex_spent[1]);
0178     
0179     fprintf(stderr,"Totals: rw: %ld vs mut %ld\n", 
0180             totrw, totmut);
0181     
0182     return 0;
0183 }
0184 
0185 /* vim: set ts=4 sw=4 et smartindent: */