Так, как делают некоторые системные функции. Чтобы внутри есть статический буфер, куда какая-нибудь функция складывает свой результат, но чтобы если ее вызвали из другого потока она не перекрыла результат первого.
В голову идет только динамический массив структур, каждая из которых содержит буфер и thread_id. И каждый раз при обращении проверять, если такой тред и если нет - расширять массив, и выдавать новый буфер. Минусы - не почистится буфер при выходе и анализаторы будут гудеть. Еще время поиска, когда много тредов оно в теории может быть менее выгодно чем malloc/free.
Как это реализуют нормальные люди? Количество тредов не определено, может быть 5, может быть 50, может быть 500.