      {
          threads.push_back(*it);
      }
-@@ -533,7 +533,7 @@
+@@ -309,7 +317,7 @@
+     //try to get tcs from thread cache
+     se_thread_id_t thread_id = get_thread_id();
+     CTrustThread *trust_thread = get_bound_thread(thread_id);
+-    if(NULL != trust_thread  && m_utility_thread != trust_thread)
++    if(NULL != trust_thread && m_utility_thread != trust_thread && m_user_utility_thread != trust_thread)
+     {
+         return trust_thread;
+     }
+@@ -334,7 +342,7 @@
+     LockGuard lock(&m_thread_mutex);
+     CTrustThread *trust_thread = NULL;
+     bool is_special_ecall = (ecall_cmd == ECMD_INIT_ENCLAVE) || (ecall_cmd == ECMD_UNINIT_ENCLAVE) ;
+-    
++    bool is_user_utility = (ecall_cmd == ECMD_UTILITY);
+ 
+     if(is_special_ecall == true)
+     {
+@@ -357,6 +365,21 @@
+             trust_thread = _acquire_thread();
+         }
+     }
++    else if (is_user_utility)
++    {
++        if (m_user_utility_thread)
++        {
++            if (m_user_utility_thread_in_use.exchange(true))
++            {
++                return NULL;
++            }
++            trust_thread = m_user_utility_thread;
++            assert(trust_thread != NULL);
++        } else
++        {
++            trust_thread = _acquire_thread();
++        }
++    }
+     else
+     {
+         trust_thread = _acquire_thread();
+@@ -392,6 +415,10 @@
+ //Do nothing for bind mode, the tcs is always bound to a thread.
+ void CTrustThreadPool::release_thread(CTrustThread * const trust_thread)
+ {
++    if (trust_thread == m_user_utility_thread)
++    {
++        m_user_utility_thread_in_use = false;
++    }
+     LockGuard lock(&m_thread_mutex);
+     trust_thread->decrease_ref();
+     return;
+@@ -533,7 +560,7 @@
  
      //if free list is NULL, recycle tcs.
      //get thread id set of current process

 
 CTrustThread * CEnclave::get_tcs(int ecall_cmd)
 {
diff -Nur psw/urts/enclave.h psw/urts/enclave.h
--- psw/urts/enclave.h
+++ psw/urts/enclave.h
@@ -85,7 +85,10 @@
     void set_sealed_key(uint8_t *sealed_key);
     sgx_status_t init_uswitchless(const sgx_uswitchless_config_t* config);

 
 #ifdef __cplusplus
 }
diff -Nur common/inc/internal/rts_cmd.h common/inc/internal/rts_cmd.h
--- common/inc/internal/rts_cmd.h
+++ common/inc/internal/rts_cmd.h
@@ -36,6 +36,7 @@
 #define ECMD_EXCEPT         -3
 #define ECMD_MKTCS          -4
 #define ECMD_UNINIT_ENCLAVE -5
+#define ECMD_UTILITY        -6
 
 /* Built-in ECall command for Switchless SGX */
 #define ECMD_INIT_SWITCHLESS         (-6)
diff -Nur common/inc/internal/se_tcrypto_common.h common/inc/internal/se_tcrypto_common.h
--- common/inc/internal/se_tcrypto_common.h
+++ common/inc/internal/se_tcrypto_common.h
