<commit_before>
/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004-2006
 *
 */

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include "trousers/tss.h"
#include "spi_internal_types.h"
#include "tcs_tsp.h"
#include "tcs_utils.h"
#include "tcs_int_literals.h"
#include "capabilities.h"
#include "tcslog.h"
#include "tcsd_wrap.h"
#include "tcsd.h"
#include "auth_mgr.h"
#include "req_mgr.h"


MUTEX_DECLARE_EXTERN(tcsp_lock);


/* Note: The after taking the auth_mgr_lock in any of the functions below, the
 * mem_cache_lock cannot be taken without risking a deadlock. So, the auth_mgr
 * functions must be "self-contained" wrt locking */

/* no locking done in init since its called by only a single thread */
TSS_RESULT
auth_mgr_init()
{
	memset(&auth_mgr, 0, sizeof(struct _auth_mgr));

	auth_mgr.max_auth_sessions = tpm_metrics.num_auths;

	auth_mgr.overflow = calloc(TSS_DEFAULT_OVERFLOW_AUTHS, sizeof(COND_VAR *));
	if (auth_mgr.overflow == NULL) {
		LogError("malloc of %zd bytes failed",
			 (TSS_DEFAULT_OVERFLOW_AUTHS * sizeof(COND_VAR *)));
		return TCSERR(TSS_E_OUTOFMEMORY);
	}

	auth_mgr.auth_mapper = calloc(TSS_DEFAULT_AUTH_TABLE_SIZE, sizeof(struct auth_map));
	if (auth_mgr.auth_mapper == NULL) {
		LogError("malloc of %zd bytes failed",
			 (TSS_DEFAULT_AUTH_TABLE_SIZE * sizeof(struct auth_map)));
		return TCSERR(TSS_E_OUTOFMEMORY);
	}
	auth_mgr.auth_mapper_size = TSS_DEFAULT_AUTH_TABLE_SIZE;

	return TSS_SUCCESS;
}

TSS_RESULT
auth_mgr_final()
{
	int i;

	/* wake up any sleeping threads, so they can be joined */
	for (i = 0; i < TSS_DEFAULT_OVERFLOW_AUTHS; i++) {
		if (auth_mgr.overflow[i] != NULL)
			COND_SIGNAL(auth_mgr.overflow[i]);
	}

	free(auth_mgr.overflow);
	free(auth_mgr.auth_mapper);

	return TSS_SUCCESS;
}

TSS_RESULT
auth_mgr_save_ctx(TCS_CONTEXT_HANDLE hContext)
{
	TSS_RESULT result;
	UINT32 i;

	for (i = 0; i < auth_mgr.auth_mapper_size; i++) {
		if (auth_mgr.auth_mapper[i].full == TRUE &&
		    auth_mgr.auth_mapper[i].swap == NULL &&
		    auth_mgr.auth_mapper[i].tcs_ctx != hContext) {

			LogDebug("Calling TPM_SaveAuthContext for TCS CTX %x. Swapping out: TCS %x "
				 "TPM %x", hContext, auth_mgr.auth_mapper[i].tcs_ctx,
				 auth_mgr.auth_mapper[i].tpm_handle);

			if ((result = TPM_SaveAuthContext(auth_mgr.auth_mapper[i].tpm_handle,
							  &auth_mgr.auth_mapper[i].swap_size,
							  &auth_mgr.auth_mapper[i].swap))) {
				LogDebug("TPM_SaveAuthContext failed: 0x%x", result);
				return result;
			}
		}
	}

	return TSS_SUCCESS;
}

/* if there's a TCS context waiting to get auth, wake it up or swap it in */
void
auth_mgr_swap_in()
{
	if (auth_mgr.overflow[auth_mgr.of_tail] != NULL) {
		LogDebug("waking up thread %zd, auth slot has opened", THREAD_ID);
		/* wake up the next sleeping thread in order and increment tail */
		COND_SIGNAL(auth_mgr.overflow[auth_mgr.of_tail]);
		auth_mgr.overflow[auth_mgr.of_tail] = NULL;
		auth_mgr.of_tail = (auth_mgr.of_tail + 1) % TSS_DEFAULT_OVERFLOW_AUTHS;
	} else
		/* else nobody needs to be swapped in, so continue */
		LogDebug("no threads need to be signaled.");
}

/* we need to swap out an auth context or add a waiting context to the overflow queue */
TSS_RESULT
auth_mgr_swap_out(TCS_CONTEXT_HANDLE hContext)
{
	COND_VAR *cond;

	/* If the TPM can do swapping and it succeeds, return, else cond wait below */
	if (tpm_metrics.authctx_swap && !auth_mgr_save_ctx(hContext))
		return TSS_SUCCESS;

	if ((cond = ctx_get_cond_var(hContext)) == NULL) {<commit_msg>enclose debug-only stmt in brackets<commit_after>
/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004-2006
 *
 */

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include "trousers/tss.h"
#include "spi_internal_types.h"
#include "tcs_tsp.h"
#include "tcs_utils.h"
#include "tcs_int_literals.h"
#include "capabilities.h"
#include "tcslog.h"
#include "tcsd_wrap.h"
#include "tcsd.h"
#include "auth_mgr.h"
#include "req_mgr.h"


MUTEX_DECLARE_EXTERN(tcsp_lock);


/* Note: The after taking the auth_mgr_lock in any of the functions below, the
 * mem_cache_lock cannot be taken without risking a deadlock. So, the auth_mgr
 * functions must be "self-contained" wrt locking */

/* no locking done in init since its called by only a single thread */
TSS_RESULT
auth_mgr_init()
{
	memset(&auth_mgr, 0, sizeof(struct _auth_mgr));

	auth_mgr.max_auth_sessions = tpm_metrics.num_auths;

	auth_mgr.overflow = calloc(TSS_DEFAULT_OVERFLOW_AUTHS, sizeof(COND_VAR *));
	if (auth_mgr.overflow == NULL) {
		LogError("malloc of %zd bytes failed",
			 (TSS_DEFAULT_OVERFLOW_AUTHS * sizeof(COND_VAR *)));
		return TCSERR(TSS_E_OUTOFMEMORY);
	}

	auth_mgr.auth_mapper = calloc(TSS_DEFAULT_AUTH_TABLE_SIZE, sizeof(struct auth_map));
	if (auth_mgr.auth_mapper == NULL) {
		LogError("malloc of %zd bytes failed",
			 (TSS_DEFAULT_AUTH_TABLE_SIZE * sizeof(struct auth_map)));
		return TCSERR(TSS_E_OUTOFMEMORY);
	}
	auth_mgr.auth_mapper_size = TSS_DEFAULT_AUTH_TABLE_SIZE;

	return TSS_SUCCESS;
}

TSS_RESULT
auth_mgr_final()
{
	int i;

	/* wake up any sleeping threads, so they can be joined */
	for (i = 0; i < TSS_DEFAULT_OVERFLOW_AUTHS; i++) {
		if (auth_mgr.overflow[i] != NULL)
			COND_SIGNAL(auth_mgr.overflow[i]);
	}

	free(auth_mgr.overflow);
	free(auth_mgr.auth_mapper);

	return TSS_SUCCESS;
}

TSS_RESULT
auth_mgr_save_ctx(TCS_CONTEXT_HANDLE hContext)
{
	TSS_RESULT result;
	UINT32 i;

	for (i = 0; i < auth_mgr.auth_mapper_size; i++) {
		if (auth_mgr.auth_mapper[i].full == TRUE &&
		    auth_mgr.auth_mapper[i].swap == NULL &&
		    auth_mgr.auth_mapper[i].tcs_ctx != hContext) {

			LogDebug("Calling TPM_SaveAuthContext for TCS CTX %x. Swapping out: TCS %x "
				 "TPM %x", hContext, auth_mgr.auth_mapper[i].tcs_ctx,
				 auth_mgr.auth_mapper[i].tpm_handle);

			if ((result = TPM_SaveAuthContext(auth_mgr.auth_mapper[i].tpm_handle,
							  &auth_mgr.auth_mapper[i].swap_size,
							  &auth_mgr.auth_mapper[i].swap))) {
				LogDebug("TPM_SaveAuthContext failed: 0x%x", result);
				return result;
			}
		}
	}

	return TSS_SUCCESS;
}

/* if there's a TCS context waiting to get auth, wake it up or swap it in */
void
auth_mgr_swap_in()
{
	if (auth_mgr.overflow[auth_mgr.of_tail] != NULL) {
		LogDebug("waking up thread %zd, auth slot has opened", THREAD_ID);
		/* wake up the next sleeping thread in order and increment tail */
		COND_SIGNAL(auth_mgr.overflow[auth_mgr.of_tail]);
		auth_mgr.overflow[auth_mgr.of_tail] = NULL;
		auth_mgr.of_tail = (auth_mgr.of_tail + 1) % TSS_DEFAULT_OVERFLOW_AUTHS;
	} else {
		/* else nobody needs to be swapped in, so continue */
		LogDebug("no threads need to be signaled.");
	}
}

/* we need to swap out an auth context or add a waiting context to the overflow queue */
TSS_RESULT
auth_mgr_swap_out(TCS_CONTEXT_HANDLE hContext)
{
	COND_VAR *cond;

	/* If the TPM can do swapping and it succeeds, return, else cond wait below */
	if (tpm_metrics.authctx_swap && !auth_mgr_save_ctx(hContext))
		return TSS_SUCCESS;

	if ((cond = ctx_get_cond_var(hContext)) == NULL) {
{'fraction_non_alphanumeric': 0.1168217808028893, 'fraction_numerical': 0.00416724545075705, 'mean_word_length': 4.594405594405594, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5272246', 'n_tokens_mistral': 2907, 'n_tokens_neox': 2784, 'n_words': 648}