New threadpool
- removed some whitespace noise. - cleaned up CMakeLists.txt - reintegrated task_manager.c into thread-pool.c - cleaned up some unnecessary code Co-authored-by: Cedric Roux <cedric.roux@eurecom.fr> Co-authored-by: Mikel Irazabal <mikel.irazabal@openairinterface.com>
This commit is contained in:
co-authored by
Cedric Roux
Mikel Irazabal
parent
c942fe43a9
commit
21dafbcde7
@@ -0,0 +1,223 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#ifndef NOTIFIED_FIFO_H
|
||||
#define NOTIFIED_FIFO_H
|
||||
#include "pthread_utils.h"
|
||||
#include <stdint.h>
|
||||
#include <pthread.h>
|
||||
#include "time_meas.h"
|
||||
#include <memory.h>
|
||||
#include <stdalign.h>
|
||||
#include "assertions.h"
|
||||
|
||||
/// @brief Element on the notifiedFifo_t
|
||||
/// next: internal FIFO chain, do not set it
|
||||
/// key: a long int that the client can use to identify a job or a group of messages
|
||||
/// ResponseFifo: if the client defines a response FIFO, the job will be posted back after processing
|
||||
/// processingFunc: any function (of type void processingFunc(void *)) that a worker will process
|
||||
/// msgData: the data passed to `processingFunc`. It can be added automatically, or you can set it to a buffer you are managing
|
||||
/// malloced: a boolean that enables internal free in the case of no return FIFO or abort feature
|
||||
typedef struct notifiedFIFO_elt_s {
|
||||
struct notifiedFIFO_elt_s *next;
|
||||
uint64_t key; // To filter out elements
|
||||
struct notifiedFIFO_s *reponseFifo;
|
||||
void (*processingFunc)(void *);
|
||||
bool malloced;
|
||||
oai_cputime_t creationTime;
|
||||
oai_cputime_t startProcessingTime;
|
||||
oai_cputime_t endProcessingTime;
|
||||
oai_cputime_t returnTime;
|
||||
// use alignas(32) to align msgData to 32b
|
||||
// user data behind it will be aligned to 32b as well
|
||||
// important! this needs to be the last member in the struct
|
||||
alignas(32) void *msgData;
|
||||
} notifiedFIFO_elt_t;
|
||||
|
||||
typedef struct notifiedFIFO_s {
|
||||
notifiedFIFO_elt_t *outF;
|
||||
notifiedFIFO_elt_t *inF;
|
||||
pthread_mutex_t lockF;
|
||||
pthread_cond_t notifF;
|
||||
bool abortFIFO; // if set, the FIFO always returns NULL -> abort condition
|
||||
} notifiedFIFO_t;
|
||||
|
||||
/// @brief Creates a new job.
|
||||
/// @param size The data part of the job will have this size
|
||||
/// @param key the job can be identified
|
||||
/// @param reponseFifo response fifo
|
||||
/// @param processingFunc function to call
|
||||
/// @return new notifiedFIFO_elt_t element with extra memory allocated at the end equal to size.
|
||||
static inline notifiedFIFO_elt_t *newNotifiedFIFO_elt(int size,
|
||||
uint64_t key,
|
||||
notifiedFIFO_t *reponseFifo,
|
||||
void (*processingFunc)(void *))
|
||||
{
|
||||
notifiedFIFO_elt_t *ret = (notifiedFIFO_elt_t *)memalign(32, sizeof(notifiedFIFO_elt_t) + size);
|
||||
AssertFatal(NULL != ret, "out of memory\n");
|
||||
ret->next = NULL;
|
||||
ret->key = key;
|
||||
ret->reponseFifo = reponseFifo;
|
||||
ret->processingFunc = processingFunc;
|
||||
// We set user data piece aligend 32 bytes to be able to process it with SIMD
|
||||
// msgData is aligned to 32bytes, so everything after will be as well
|
||||
ret->msgData = ((uint8_t *)ret) + sizeof(notifiedFIFO_elt_t);
|
||||
ret->malloced = true;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// @brief Get pointer to the data carried by notifiedFIFO_elt_t
|
||||
/// @param elt
|
||||
/// @return void pointer to the data allocated with the message
|
||||
static inline void *NotifiedFifoData(notifiedFIFO_elt_t *elt)
|
||||
{
|
||||
return elt->msgData;
|
||||
}
|
||||
|
||||
/// @brief Delete a notifiedFIFO_elt_t if its allocated
|
||||
/// @param elt
|
||||
static inline void delNotifiedFIFO_elt(notifiedFIFO_elt_t *elt)
|
||||
{
|
||||
if (elt->malloced) {
|
||||
elt->malloced = false;
|
||||
free(elt);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void initNotifiedFIFO_nothreadSafe(notifiedFIFO_t *nf)
|
||||
{
|
||||
nf->inF = NULL;
|
||||
nf->outF = NULL;
|
||||
nf->abortFIFO = false;
|
||||
}
|
||||
static inline void initNotifiedFIFO(notifiedFIFO_t *nf)
|
||||
{
|
||||
mutexinit(nf->lockF);
|
||||
condinit(nf->notifF);
|
||||
initNotifiedFIFO_nothreadSafe(nf);
|
||||
// No delete function: the creator has only to free the memory
|
||||
}
|
||||
|
||||
static inline void pushNotifiedFIFO_nothreadSafe(notifiedFIFO_t *nf, notifiedFIFO_elt_t *msg)
|
||||
{
|
||||
msg->next = NULL;
|
||||
|
||||
if (nf->outF == NULL)
|
||||
nf->outF = msg;
|
||||
|
||||
if (nf->inF != NULL)
|
||||
nf->inF->next = msg;
|
||||
|
||||
nf->inF = msg;
|
||||
}
|
||||
|
||||
static inline void pushNotifiedFIFO(notifiedFIFO_t *nf, notifiedFIFO_elt_t *msg)
|
||||
{
|
||||
mutexlock(nf->lockF);
|
||||
if (!nf->abortFIFO) {
|
||||
pushNotifiedFIFO_nothreadSafe(nf, msg);
|
||||
condsignal(nf->notifF);
|
||||
}
|
||||
mutexunlock(nf->lockF);
|
||||
}
|
||||
|
||||
static inline notifiedFIFO_elt_t *pullNotifiedFIFO_nothreadSafe(notifiedFIFO_t *nf)
|
||||
{
|
||||
if (nf->outF == NULL)
|
||||
return NULL;
|
||||
if (nf->abortFIFO)
|
||||
return NULL;
|
||||
|
||||
notifiedFIFO_elt_t *ret = nf->outF;
|
||||
|
||||
AssertFatal(nf->outF != nf->outF->next, "Circular list in thread pool: push several times the same buffer is forbidden\n");
|
||||
|
||||
nf->outF = nf->outF->next;
|
||||
|
||||
if (nf->outF == NULL)
|
||||
nf->inF = NULL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline notifiedFIFO_elt_t *pullNotifiedFIFO(notifiedFIFO_t *nf)
|
||||
{
|
||||
mutexlock(nf->lockF);
|
||||
notifiedFIFO_elt_t *ret = NULL;
|
||||
|
||||
while ((ret = pullNotifiedFIFO_nothreadSafe(nf)) == NULL && !nf->abortFIFO)
|
||||
condwait(nf->notifF, nf->lockF);
|
||||
|
||||
mutexunlock(nf->lockF);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline notifiedFIFO_elt_t *pollNotifiedFIFO(notifiedFIFO_t *nf)
|
||||
{
|
||||
int tmp = mutextrylock(nf->lockF);
|
||||
|
||||
if (tmp != 0)
|
||||
return NULL;
|
||||
|
||||
if (nf->abortFIFO) {
|
||||
mutexunlock(nf->lockF);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
notifiedFIFO_elt_t *ret = pullNotifiedFIFO_nothreadSafe(nf);
|
||||
mutexunlock(nf->lockF);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline time_stats_t exec_time_stats_NotifiedFIFO(const notifiedFIFO_elt_t *elt)
|
||||
{
|
||||
time_stats_t ts = {0};
|
||||
if (elt->startProcessingTime == 0 && elt->endProcessingTime == 0)
|
||||
return ts; /* no measurements done */
|
||||
ts.in = elt->startProcessingTime;
|
||||
ts.diff = elt->endProcessingTime - ts.in;
|
||||
ts.p_time = ts.diff;
|
||||
ts.diff_square = ts.diff * ts.diff;
|
||||
ts.max = ts.diff;
|
||||
ts.trials = 1;
|
||||
return ts;
|
||||
}
|
||||
|
||||
// This functions aborts all messages in the queue, and marks the queue as
|
||||
// "aborted", such that every call to it will return NULL
|
||||
static inline void abortNotifiedFIFO(notifiedFIFO_t *nf)
|
||||
{
|
||||
mutexlock(nf->lockF);
|
||||
nf->abortFIFO = true;
|
||||
notifiedFIFO_elt_t **elt = &nf->outF;
|
||||
while (*elt != NULL) {
|
||||
notifiedFIFO_elt_t *p = *elt;
|
||||
*elt = (*elt)->next;
|
||||
delNotifiedFIFO_elt(p);
|
||||
}
|
||||
|
||||
if (nf->outF == NULL)
|
||||
nf->inF = NULL;
|
||||
condbroadcast(nf->notifF);
|
||||
mutexunlock(nf->lockF);
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user