Reuse old Object structures rather than build and free them every time.
authorrelyea%netscape.com
Tue, 13 Jun 2000 21:34:52 +0000
changeset 365 2fbf4b60594a6e5a0cc66354fdbe61c2e78f0f54
parent 361 dce975d898390b2b88eff5918fb70163a9be116d
child 366 1c72abbe045f2a11a809e629c98bd6996c8f7ee0
push idunknown
push userunknown
push dateunknown
Reuse old Object structures rather than build and free them every time.
security/nss/lib/softoken/pkcs11i.h
security/nss/lib/softoken/pkcs11u.c
--- a/security/nss/lib/softoken/pkcs11i.h
+++ b/security/nss/lib/softoken/pkcs11i.h
@@ -82,16 +82,17 @@ typedef void (*PK11Free)(void *);
  * these are data base storage hashes, not cryptographic hashes.. The define
  * the effective size of the various object hash tables
  */
 #define ATTRIBUTE_HASH_SIZE 32
 #define SESSION_OBJECT_HASH_SIZE 32
 #define TOKEN_OBJECT_HASH_SIZE 1024
 #define SESSION_HASH_SIZE 512
 #define MAX_KEY_LEN 256
+#define MAX_OBJECT_LIST_SIZE 800
 
 /* Value to tell if an attribute is modifiable or not.
  *    NEVER: attribute is only set on creation.
  *    ONCOPY: attribute is set on creation and can only be changed on copy.
  *    SENSITIVE: attribute can only be changed to TRUE.
  *    ALWAYS: attribute can always be changed.
  */
 typedef enum {
--- a/security/nss/lib/softoken/pkcs11u.c
+++ b/security/nss/lib/softoken/pkcs11u.c
@@ -586,25 +586,61 @@ pk11_AddAttributeType(PK11Object *object
     return CKR_OK;
 }
 
 /*
  * ******************** Object Utilities *******************************
  */
 
 /* allocation hooks that allow us to recycle old object structures */
-static PK11Object *
+#ifdef MAX_OBJECT_LIST_SIZE
+static PK11Object * objectFreeList = NULL;
+static PRLock *objectLock = NULL;
+static int object_count = 0;
+#endif
+PK11Object *
 pk11_GetObjectFromList(PRBool *hasLocks) {
-    PK11Object *object = (PK11Object*)PORT_ZAlloc(sizeof(PK11Object));
+    PK11Object *object;
+
+#if MAX_OBJECT_LIST_SIZE
+    if (objectLock == NULL) {
+	objectLock = PR_NewLock();
+    }
+
+    PK11_USE_THREADS(PR_Lock(objectLock));
+    object = objectFreeList;
+    if (object) {
+	objectFreeList = object->next;
+	object_count--;
+    }    	
+    PK11_USE_THREADS(PR_Unlock(objectLock));
+    if (object) {
+	object->next = object->prev = NULL;
+        *hasLocks = PR_TRUE;
+	return object;
+    }
+#endif
+
+    object  = (PK11Object*)PORT_ZAlloc(sizeof(PK11Object));
     *hasLocks = PR_FALSE;
     return object;
 }
 
 static void
 pk11_PutObjectToList(PK11Object *object) {
+#ifdef MAX_OBJECT_LIST_SIZE
+    if (object_count < MAX_OBJECT_LIST_SIZE) {
+	PK11_USE_THREADS(PR_Lock(objectLock));
+	object->next = objectFreeList;
+	objectFreeList = object;
+	object_count++;
+	PK11_USE_THREADS(PR_Unlock(objectLock));
+	return;
+     }
+#endif
     PK11_USE_THREADS(PR_DestroyLock(object->attributeLock);)
     PK11_USE_THREADS(PR_DestroyLock(object->refLock);)
     object->attributeLock = object->refLock = NULL;
     PORT_Free(object);
 }
 
 
 /*