diff -r 000000000000 -r 6474c204b198 security/nss/cmd/libpkix/perf/libpkix_buildthreads.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/security/nss/cmd/libpkix/perf/libpkix_buildthreads.c Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,349 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +/* + * libpkixBuildThreads.c + * + * libpkix Builder Performance Evaluation application (multi-threaded) + * + */ + +#include +#include + +#include "secutil.h" + +#include "nspr.h" +#include "prtypes.h" +#include "prtime.h" +#include "prlong.h" + +#include "pk11func.h" +#include "secasn1.h" +#include "cert.h" +#include "cryptohi.h" +#include "secoid.h" +#include "certdb.h" +#include "nss.h" + +#include "pkix.h" +#include "pkix_tools.h" +#include "pkix_pl_cert.h" + +#include "testutil.h" +#include "testutil_nss.h" + +static void *plContext = NULL; + +#undef pkixTempResult +#define PERF_DECREF(obj) \ + { \ + PKIX_Error *pkixTempResult = NULL; \ + if (obj){ \ + pkixTempResult = PKIX_PL_Object_DecRef \ + ((PKIX_PL_Object *)(obj), plContext); \ + obj = NULL; \ + } \ + } + +static void finish(char* message, int code); + +typedef struct ThreadDataStr tData; + +struct ThreadDataStr { + CERTCertificate* anchor; + char* eecertName; + PRIntervalTime duration; + CERTCertDBHandle *handle; + PRUint32 iterations; +}; + +#define PKIX_LOGGER_ON 1 + +#ifdef PKIX_LOGGER_ON + +char *logLevels[] = { + "None", + "Fatal Error", + "Error", + "Warning", + "Debug", + "Trace" +}; + +static PKIX_Error *loggerCallback( + PKIX_Logger *logger, + PKIX_PL_String *message, + PKIX_UInt32 logLevel, + PKIX_ERRORCLASS logComponent, + void *plContext) +{ + char *msg = NULL; + static int callCount = 0; + + msg = PKIX_String2ASCII(message, plContext); + printf("Logging %s (%s): %s\n", + logLevels[logLevel], + PKIX_ERRORCLASSNAMES[logComponent], + msg); + PR_Free((void *)msg); + + return(NULL); +} + +#endif /* PKIX_LOGGER_ON */ + +static void ThreadEntry(void* data) +{ + tData* tdata = (tData*) data; + PRIntervalTime duration = tdata->duration; + PRIntervalTime start = PR_IntervalNow(); + + PKIX_List *anchors = NULL; + PKIX_ProcessingParams *procParams = NULL; + PKIX_BuildResult *buildResult = NULL; + CERTCertificate* nsseecert; + PKIX_PL_Cert *eeCert = NULL; + PKIX_CertStore *certStore = NULL; + PKIX_List *certStores = NULL; + PKIX_ComCertSelParams *certSelParams = NULL; + PKIX_CertSelector *certSelector = NULL; + PKIX_PL_Date *nowDate = NULL; + void *state = NULL; /* only relevant with non-blocking I/O */ + void *nbioContext = NULL; /* only relevant with non-blocking I/O */ + + PR_ASSERT(duration); + if (!duration){ + return; + } + + do { + + /* libpkix code */ + + /* keep more update time, testing cache */ + PKIX_PL_Date_Create_UTCTime(NULL, &nowDate, plContext); + + /* CertUsage is 0x10 and no NSS arena */ + /* We haven't determined how we obtain the value of wincx */ + + nsseecert = CERT_FindCertByNicknameOrEmailAddr(tdata->handle, + tdata->eecertName); + if (!nsseecert) finish("Unable to find eecert.\n", 1); + + pkix_pl_Cert_CreateWithNSSCert + (nsseecert, &eeCert, plContext); + + PKIX_List_Create(&anchors, plContext); + + /* + * This code is retired. + * pkix_pl_Cert_CreateWithNSSCert + * (tdata->anchor, &anchorCert, NULL); + * PKIX_TrustAnchor_CreateWithCert(anchorCert, &anchor, NULL); + * PKIX_List_AppendItem(anchors, (PKIX_PL_Object *)anchor, NULL); + */ + + PKIX_ProcessingParams_Create(anchors, &procParams, plContext); + + PKIX_ProcessingParams_SetRevocationEnabled + (procParams, PKIX_TRUE, plContext); + + PKIX_ProcessingParams_SetDate + (procParams, nowDate, plContext); + + /* create CertSelector with target certificate in params */ + + PKIX_ComCertSelParams_Create(&certSelParams, plContext); + + PKIX_ComCertSelParams_SetCertificate + (certSelParams, eeCert, plContext); + + PKIX_CertSelector_Create + (NULL, NULL, &certSelector, plContext); + + PKIX_CertSelector_SetCommonCertSelectorParams + (certSelector, certSelParams, plContext); + + PKIX_ProcessingParams_SetTargetCertConstraints + (procParams, certSelector, plContext); + + PKIX_PL_Pk11CertStore_Create(&certStore, plContext); + + PKIX_List_Create(&certStores, plContext); + PKIX_List_AppendItem + (certStores, (PKIX_PL_Object *)certStore, plContext); + PKIX_ProcessingParams_SetCertStores + (procParams, certStores, plContext); + + PKIX_BuildChain + (procParams, + &nbioContext, + &state, + &buildResult, + NULL, + plContext); + + /* + * As long as we use only CertStores with blocking I/O, we + * know we must be done at this point. + */ + + if (!buildResult){ + (void) fprintf(stderr, "libpkix BuildChain failed.\n"); + PORT_Assert(0); + return; + } + + tdata->iterations ++; + + PERF_DECREF(nowDate); + PERF_DECREF(anchors); + PERF_DECREF(procParams); + PERF_DECREF(buildResult); + PERF_DECREF(certStore); + PERF_DECREF(certStores); + PERF_DECREF(certSelParams); + PERF_DECREF(certSelector); + PERF_DECREF(eeCert); + + } while ((PR_IntervalNow() - start) < duration); + + +} + +static void +Test( + CERTCertificate* anchor, + char* eecertName, + PRIntervalTime duration, + CERTCertDBHandle *handle, + PRUint32 threads) +{ + tData data; + tData** alldata; + PRIntervalTime starttime, endtime, elapsed; + PRUint32 msecs; + float total = 0; + PRThread** pthreads = NULL; + PRUint32 i = 0; + + data.duration = duration; + data.anchor = anchor; + data.eecertName = eecertName; + data.handle = handle; + + data.iterations = 0; + + starttime = PR_IntervalNow(); + pthreads = (PRThread**)PR_Malloc(threads*sizeof (PRThread*)); + alldata = (tData**)PR_Malloc(threads*sizeof (tData*)); + for (i = 0; i < threads; i++){ + alldata[i] = (tData*)PR_Malloc(sizeof (tData)); + *alldata[i] = data; + pthreads[i] = + PR_CreateThread(PR_USER_THREAD, + ThreadEntry, + (void*) alldata[i], + PR_PRIORITY_NORMAL, + PR_GLOBAL_THREAD, + PR_JOINABLE_THREAD, + 0); + } + + for (i = 0; i < threads; i++) { + tData* args = alldata[i]; + PR_JoinThread(pthreads[i]); + total += args->iterations; + PR_Free((void*)args); + } + + PR_Free((void*) pthreads); + PR_Free((void*) alldata); + endtime = PR_IntervalNow(); + + endtime = PR_IntervalNow(); + elapsed = endtime - starttime; + msecs = PR_IntervalToMilliseconds(elapsed); + total /= msecs; + total *= 1000; + (void) fprintf(stdout, "%f operations per second.\n", total); +} + + +static void finish(char* message, int code) +{ + (void) printf(message); + exit(code); +} + +static void usage(char* progname) +{ + (void) printf("Usage : %s <-d certStoreDirectory> " + " \n\n", progname); + finish("", 0); +} + +int +libpkix_buildthreads(int argc, char** argv) +{ + CERTCertDBHandle *handle = NULL; + CERTCertificate* eecert = NULL; + PRIntervalTime duration = PR_SecondsToInterval(1); + PRUint32 threads = 1; + PKIX_UInt32 actualMinorVersion; + PKIX_UInt32 j = 0; + PKIX_Logger *logger = NULL; + void *wincx = NULL; + + /* if (argc != 5) -- when TrustAnchor used to be on command line */ + if (argc != 4) + { + usage(argv[0]); + } + if (atoi(argv[1]) > 0) + { + duration = PR_SecondsToInterval(atoi(argv[1])); + } + if (atoi(argv[2]) > 0) + { + threads = atoi(argv[2]); + } + + PKIX_PL_NssContext_Create(certificateUsageEmailSigner, PKIX_FALSE, + NULL, &plContext); + + handle = CERT_GetDefaultCertDB(); + PR_ASSERT(handle); + +#ifdef PKIX_LOGGER_ON + + /* set logger to log trace and up */ + PKIX_SetLoggers(NULL, plContext); + PKIX_Logger_Create(loggerCallback, NULL, &logger, plContext); + PKIX_Logger_SetMaxLoggingLevel + (logger, PKIX_LOGGER_LEVEL_WARNING, plContext); + PKIX_AddLogger(logger, plContext); + +#endif /* PKIX_LOGGER_ON */ + + /* + * This code is retired + * anchor = CERT_FindCertByNicknameOrEmailAddr(handle, argv[3]); + * if (!anchor) finish("Unable to find anchor.\n", 1); + * + * eecert = CERT_FindCertByNicknameOrEmailAddr(handle, argv[4]); + + * if (!eecert) finish("Unable to find eecert.\n", 1); + * + * Test(anchor, eecert, duration, threads); + */ + + Test(NULL, argv[3], duration, handle, threads); + + PERF_DECREF(logger); + + PKIX_Shutdown(plContext); + + return (0); +}