Explorar el Código

- tm converted to the new locking scheme (locking.h)

Andrei Pelinescu-Onciul hace 22 años
padre
commit
b717e512ac
Se han modificado 2 ficheros con 98 adiciones y 173 borrados
  1. 79 142
      modules/tm/lock.c
  2. 19 31
      modules/tm/lock.h

+ 79 - 142
modules/tm/lock.c

@@ -24,6 +24,11 @@
  * along with this program; if not, write to the Free Software 
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
+/*
+ * History:
+ * --------
+ *  2003-03-17  converted to locking.h (andrei)
+ */
 
 
 #include "defs.h"
@@ -35,26 +40,18 @@
 #include "timer.h"
 #include "../../dprint.h"
 
-#ifdef FAST_LOCK
-#include "../../mem/shm_mem.h"
-#endif
 
 
-#ifndef FAST_LOCK
+#ifndef GEN_LOCK_T_PREFERED 
 /* semaphore probing limits */
 #define SEM_MIN		16
 #define SEM_MAX		4096
 
-/* we implement mutex here using System V semaphores; as number of
-   sempahores is limited and number of synchronized elements
-   high, we partition the sync'ed SER elements and share semaphores
-   in each of the partitions; we try to use as many semaphores as OS
-   gives us for finest granularity; perhaps later we will
-   add some arch-dependent mutex code that will not have
-   ipc's dimensioning limitations and will provide us with
-   fast unlimited (=no sharing) mutexing
-
-  UPDATE: we do have now arch-dependent locking (-DFAST_LOCK)
+/* we implement mutex here using lock sets; as the number of
+   sempahores may be limited (e.g. sysv) and number of synchronized 
+   elements high, we partition the sync'ed SER elements and share 
+   semaphores in each of the partitions; we try to use as many 
+   semaphores as OS gives us for finest granularity. 
 
    we allocate the locks according to the following plans:
 
@@ -71,82 +68,17 @@
 
 */
 
-/* keep the semaphore here */
-static int
-	entry_semaphore=0, 
-	timer_semaphore=0, 
-	reply_semaphore=0;
 /* and the maximum number of semaphores in the entry_semaphore set */
 static int sem_nr;
-/* timer group locks */
-
-
-
-/* return -1 if semget failed, -2 if semctl failed */
-static int init_semaphore_set( int size )
-{
-	int new_semaphore, i;
-
-	new_semaphore=semget ( IPC_PRIVATE, size, IPC_CREAT | IPC_PERMISSIONS );
-	if (new_semaphore==-1) {
-		DBG("DEBUG: init_semaphore_set(%d):  failure to allocate a"
-					" semaphore: %s\n", size, strerror(errno));
-		return -1;
-	}
-	for (i=0; i<size; i++) {
-
- 		union semun {
-			int val;
-			struct semid_ds *buf;
-			ushort *array;
-		} argument;
-
-		/* binary lock */
-		argument.val = +1;
-   		if (semctl( new_semaphore, i , SETVAL , argument )==-1) {
-			DBG("DEBUG: init_semaphore_set:  failure to "
-				"initialize a semaphore: %s\n", strerror(errno));
-			/* bug cought -- courtesy of Bogdan; -Jiri */
-			/* if (semctl( entry_semaphore, 0 , IPC_RMID , 0 )==-1) */
-			if (semctl( new_semaphore, 0 , IPC_RMID , 0 )==-1) 
-				DBG("DEBUG: init_semaphore_set:  failure to release"
-					" a semaphore\n");
-			return -2;
-		}
-	} /* for cycle */
-	return new_semaphore;
-}
-
-
+lock_set_t* timer_semaphore=0;
+lock_set_t* entry_semaphore=0;
+lock_set_t* reply_semaphore=0;
+#endif
 
-int change_semaphore( ser_lock_t* s  , int val )
-{
-	struct sembuf pbuf;
-	int r;
-
-	pbuf.sem_num = s->semaphore_index ;
-	pbuf.sem_op =val;
-	pbuf.sem_flg = 0;
-
-tryagain:
-	r=semop( s->semaphore_set, &pbuf ,  1 /* just 1 op */ );
-
-	if (r==-1) {
-		if (errno==EINTR) {
-			DBG("signal received in a semaphore\n");
-			goto tryagain;
-		} else {
-			LOG(L_CRIT, "ERROR: change_semaphore(%x, %p, 1) : %s\n",
-					s->semaphore_set, &pbuf,
-					strerror(errno));
-		}
-	}
-	return r;
-}
-#endif  /* !FAST_LOCK*/
+/* timer group locks */
 
 
-static ser_lock_t* timer_group_lock; /* pointer to a TG_NR lock array,
+static ser_lock_t* timer_group_lock=0; /* pointer to a TG_NR lock array,
 								    it's safer if we alloc this in shared mem 
 									( required for fast lock ) */
 
@@ -155,7 +87,7 @@ static ser_lock_t* timer_group_lock; /* pointer to a TG_NR lock array,
 int lock_initialize()
 {
 	int i;
-#ifndef FAST_LOCK
+#ifndef GEN_LOCK_T_PREFERED
 	int probe_run;
 #endif
 
@@ -167,11 +99,13 @@ int lock_initialize()
 		LOG(L_CRIT, "ERROR: lock_initialize: out of shm mem\n");
 		goto error;
 	}
-#ifdef FAST_LOCK
-	for(i=0;i<TG_NR;i++) init_lock(timer_group_lock[i]);
+#ifdef GEN_LOCK_T_PREFERED
+	for(i=0;i<TG_NR;i++) lock_init(&timer_group_lock[i]);
 #else
 	/* transaction timers */
-	if ((timer_semaphore= init_semaphore_set( TG_NR ) ) < 0) {
+	if (((timer_semaphore= lock_set_alloc( TG_NR ) ) == 0)||
+			(lock_set_init(timer_semaphore)==0)){
+		if (timer_semaphore) lock_set_destroy(timer_semaphore);
 		LOG(L_CRIT, "ERROR: lock_initialize:  "
 			"transaction timer semaphore initialization failure: %s\n",
 				strerror(errno));
@@ -180,7 +114,7 @@ int lock_initialize()
 
 	for (i=0; i<TG_NR; i++) {
 		timer_group_lock[i].semaphore_set = timer_semaphore;
-		timer_group_lock[i].semaphore_index = timer_group[ i ];	
+		timer_group_lock[i].semaphore_index = timer_group[ i ];
 	}
 
 
@@ -189,44 +123,47 @@ int lock_initialize()
 	probe_run=0;
 again:
 	do {
-		if (entry_semaphore>0) /* clean-up previous attempt */
-			semctl( entry_semaphore, 0 , IPC_RMID , 0 );
-		if (reply_semaphore>0)
-			semctl(reply_semaphore, 0 , IPC_RMID , 0 );
-
-
+		if (entry_semaphore!=0){ /* clean-up previous attempt */
+			lock_set_destroy(entry_semaphore);
+			lock_set_dealloc(entry_semaphore);
+		}
+		if (reply_semaphore!=0){
+			lock_set_destroy(reply_semaphore);
+			lock_set_dealloc(reply_semaphore);
+		}
+		
 		if (i==0){
 			LOG(L_CRIT, "lock_initialize: could not allocate semaphore"
 					" sets\n");
 			goto error;
 		}
-
-		entry_semaphore=init_semaphore_set( i );
-		if (entry_semaphore==-1) {
+		
+		if (((entry_semaphore=lock_set_alloc(i))==0)||
+			(lock_set_init(entry_semaphore)==0)) {
 			DBG("DEBUG: lock_initialize: entry semaphore "
 					"initialization failure:  %s\n", strerror( errno ) );
-			/* Solaris: EINVAL, Linux: ENOSPC */
-                        if (errno==EINVAL || errno==ENOSPC ) {
-                                /* first time: step back and try again */
-                                if (probe_run==0) {
+			if (entry_semaphore){
+				lock_set_dealloc(entry_semaphore);
+				entry_semaphore=0;
+			}
+			/* first time: step back and try again */
+			if (probe_run==0) {
 					DBG("DEBUG: lock_initialize: first time "
 								"semaphore allocation failure\n");
-                                        i--;
-                                        probe_run=1;
-                                        continue;
+					i--;
+					probe_run=1;
+					continue;
 				/* failure after we stepped back; give up */
-                                } else {
-				 	DBG("DEBUG: lock_initialize:   second time sempahore allocation failure\n");
+			} else {
+					DBG("DEBUG: lock_initialize:   second time sempahore"
+							" allocation failure\n");
 					goto error;
-				}
-                        }
-			/* some other error occured: give up */
-                        goto error;
-                }
+			}
+		}
 		/* allocation succeeded */
 		if (probe_run==1) { /* if ok after we stepped back, we're done */
 			break;
-		} else { /* if ok otherwiese, try again with larger set */
+		} else { /* if ok otherwise, try again with larger set */
 			if (i==SEM_MAX) break;
 			else {
 				i++;
@@ -234,25 +171,24 @@ again:
 			}
 		}
 	} while(1);
-	sem_nr=i;	
+	sem_nr=i;
 
-	if ((reply_semaphore=init_semaphore_set( sem_nr ))<0){
-		if (errno==EINVAL || errno==ENOSPC ) {
+	if (((reply_semaphore=lock_set_alloc(i))==0)||
+		(lock_set_init(reply_semaphore)==0)){
+			if (reply_semaphore){
+				lock_set_dealloc(reply_semaphore);
+				reply_semaphore=0;
+			}
 			DBG("DEBUG:lock_initialize: reply semaphore initialization"
 				" failure: %s\n", strerror(errno));
 			probe_run=1;
 			i--;
 			goto again;
-		}else{
-			LOG(L_CRIT, "ERROR:lock_initialize: reply semaphore initialization"
-				" failure: %s\n", strerror(errno));
-			goto error;
-		}
 	}
 
 	/* return success */
 	LOG(L_INFO, "INFO: semaphore arrays of size %d allocated\n", sem_nr );
-#endif /* FAST_LOCK*/
+#endif /* GEN_LOCK_T_PREFERED*/
 	return 0;
 error:
 	lock_cleanup();
@@ -260,7 +196,7 @@ error:
 }
 
 
-#ifdef FAST_LOCK
+#ifdef GEN_LOCK_T_PREFERED
 void lock_cleanup()
 {
 	/* must check if someone uses them, for now just leave them allocated*/
@@ -279,22 +215,23 @@ void lock_cleanup()
 
 	/* sibling double-check missing here; install a signal handler */
 
-	if (entry_semaphore > 0 && 
-	    semctl( entry_semaphore, 0 , IPC_RMID , 0 )==-1)
-		LOG(L_ERR, "ERROR: lock_cleanup, entry_semaphore cleanup failed\n");
-	if (timer_semaphore > 0 && 
-	    semctl( timer_semaphore, 0 , IPC_RMID , 0 )==-1)
-		LOG(L_ERR, "ERROR: lock_cleanup, timer_semaphore cleanup failed\n");
-	if (reply_semaphore > 0 &&
-	    semctl( reply_semaphore, 0 , IPC_RMID , 0 )==-1)
-		LOG(L_ERR, "ERROR: lock_cleanup, reply_semaphore cleanup failed\n");
-
+	if (entry_semaphore !=0){
+		lock_set_destroy(entry_semaphore);
+		lock_set_dealloc(entry_semaphore);
+	};
+	if (timer_semaphore !=0){
+		lock_set_destroy(timer_semaphore);
+		lock_set_dealloc(timer_semaphore);
+	};
+	if (reply_semaphore !=0) {
+		lock_set_destroy(reply_semaphore);
+		lock_set_dealloc(reply_semaphore);
+	};
 	entry_semaphore = timer_semaphore = reply_semaphore = 0;
-
 	if (timer_group_lock) shm_free(timer_group_lock);
 
 }
-#endif /*FAST_LOCK*/
+#endif /*GEN_LOCK_T_PREFERED*/
 
 
 
@@ -302,20 +239,20 @@ void lock_cleanup()
 
 int init_cell_lock( struct cell *cell )
 {
-#ifdef FAST_LOCK
-	init_lock(cell->reply_mutex);
+#ifdef GEN_LOCK_T_PREFERED
+	lock_init(&cell->reply_mutex);
 	return 0;
 #else
 	cell->reply_mutex.semaphore_set=reply_semaphore;
 	cell->reply_mutex.semaphore_index = cell->hash_index % sem_nr;
-#endif /* FAST_LOCK */
+#endif /* GEN_LOCK_T_PREFERED */
 	return 0;
 }
 
 int init_entry_lock( struct s_table* ht, struct entry *entry )
 {
-#ifdef FAST_LOCK
-	init_lock(entry->mutex);
+#ifdef GEN_LOCK_T_PREFERED
+	lock_init(&entry->mutex);
 #else
 	/* just advice which of the available semaphores to use;
 	   specifically, all entries are partitioned into as
@@ -332,7 +269,7 @@ int init_entry_lock( struct s_table* ht, struct entry *entry )
 
 int release_cell_lock( struct cell *cell )
 {
-#ifndef FAST_LOCK
+#ifndef GEN_LOCK_T_PREFERED
 	/* don't do anything here -- the init_*_lock procedures
 	   just advised on usage of shared semaphores but did not
 	   generate them

+ 19 - 31
modules/tm/lock.h

@@ -24,6 +24,11 @@
  * along with this program; if not, write to the Free Software 
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
+/*
+ * History:
+ * --------
+ *  2003-03-17  converted to locking.h (andrei)
+ */
 
 #include "defs.h"
 
@@ -31,24 +36,18 @@
 #ifndef __lock_h
 #define __lock_h
 
-#include <sys/types.h>
-#include <sys/ipc.h>
-#include <sys/sem.h>
 #include "../../dprint.h"
+#include "../../locking.h"
 
 
 
-#ifdef  FAST_LOCK
-#include "../../fastlock.h"
-#endif
-
-#ifdef FAST_LOCK
-#define ser_lock_t fl_lock_t
+#ifdef GEN_LOCK_T_PREFERED
+#define ser_lock_t gen_lock_t
 #else
 /* typedef to structure we use for mutexing;
    currently, index to a semaphore set identifier now */
 typedef struct {
-	int semaphore_set;
+	lock_set_t* semaphore_set;
 	int semaphore_index;
 } ser_lock_t;
 #endif
@@ -75,11 +74,6 @@ enum timer_groups {
 
 int lock_initialize();
 void lock_cleanup();
-/*
-#ifndef FAST_LOCK
-static int init_semaphore_set( int size );
-#endif
-*/
 
 #ifdef DBG_LOCK
 #define lock(_s) _lock( (_s), __FILE__, __FUNCTION__, __LINE__ )
@@ -99,47 +93,41 @@ int release_entry_lock( struct entry *entry );
 int release_timerlist_lock( struct timer *timerlist );
 
 
-#ifndef FAST_LOCK
-int change_semaphore( ser_lock_t* s  , int val );
-#endif
-
 
 /* lock semaphore s */
 #ifdef DBG_LOCK
-static inline int _lock( ser_lock_t* s , char *file, char *function,
+static inline void _lock( ser_lock_t* s , char *file, char *function,
 							unsigned int line )
 #else
-static inline int _lock( ser_lock_t* s )
+static inline void _lock( ser_lock_t* s )
 #endif
 {
 #ifdef DBG_LOCK
 	DBG("DEBUG: lock : entered from %s , %s(%d)\n", function, file, line );
 #endif
-#ifdef FAST_LOCK
-	get_lock(s);
-	return 0;
+#ifdef GEN_LOCK_T_PREFERED 
+	lock_get(s);
 #else
-	return change_semaphore( s, -1 );
+	lock_set_get(s->semaphore_set, s->semaphore_index);
 #endif
 }
 
 
 
 #ifdef DBG_LOCK
-static inline int _unlock( ser_lock_t* s, char *file, char *function,
+static inline void _unlock( ser_lock_t* s, char *file, char *function,
 		unsigned int line )
 #else
-static inline int _unlock( ser_lock_t* s )
+static inline void _unlock( ser_lock_t* s )
 #endif
 {
 #ifdef DBG_LOCK
 	DBG("DEBUG: unlock : entered from %s, %s:%d\n", file, function, line );
 #endif
-#ifdef FAST_LOCK
-	release_lock(s);
-	return 0;
+#ifdef GEN_LOCK_T_PREFERED
+	lock_release(s);
 #else
-	return change_semaphore( s, +1 );
+	lock_set_release( s->semaphore_set, s->semaphore_index );
 #endif
 }