Actual source code: petscfptimpl.h

      1: #pragma once
      2: #include <petscviewertypes.h>
      3: #include <petscsys.h>
      4: /*
      5:     Function pointer table that maps from function pointers to their string representation

      7:     Does not use the PetscFunctionBegin/Return() or PetscCall() because these routines are called within those macros
      8: */
      9: #define PetscCallQ(A) \
     10:   do { \
     11:     PetscErrorCode ierr = A; \
     12:     if (ierr) return ierr; \
     13:   } while (0);

     15: typedef struct _n_PetscFPT *PetscFPT;
     16: struct _n_PetscFPT {
     17:   void        **functionpointer;
     18:   char        **functionname;
     19:   PetscInt      count;
     20:   unsigned long tablesize;
     21: };
     22: PETSC_INTERN PetscFPT PetscFPTData;

     24: static inline PetscErrorCode PetscFPTView(PetscViewer viewer)
     25: {
     26:   if (PetscFPTData) {
     27:     for (unsigned long i = 0; i < PetscFPTData->tablesize; ++i) {
     28:       if (PetscFPTData->functionpointer[i]) printf("%s()\n", PetscFPTData->functionname[i]);
     29:     }
     30:   }
     31:   return PETSC_SUCCESS;
     32: }

     34: static inline PetscErrorCode PetscFPTDestroy(void)
     35: {
     36:   PetscFPT data = PetscFPTData;

     38:   PetscFPTData = NULL;
     39:   if (!data) return PETSC_SUCCESS;
     40:   PetscCallQ(PetscFree(data->functionpointer));
     41:   PetscCallQ(PetscFree(data->functionname));
     42:   PetscCallQ(PetscFree(data));
     43:   return PETSC_SUCCESS;
     44: }

     46: /*
     47:    PetscFPTCreate  Creates a PETSc look up table from function pointers to strings

     49:    Input Parameter:
     50: .     n - expected number of keys

     52: */
     53: static inline PetscErrorCode PetscFPTCreate(PetscInt n)
     54: {
     55:   PetscFPT _PetscFPTData;

     57:   PetscCheck(n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "n < 0");
     58:   /* Cannot use PetscNew() here because it is not yet defined in the include file chain */
     59:   PetscCallQ(PetscMalloc(sizeof(struct _n_PetscFPT), &_PetscFPTData));
     60:   _PetscFPTData->tablesize = (3 * n) / 2 + 17;
     61:   if (_PetscFPTData->tablesize < (unsigned long)n) _PetscFPTData->tablesize = PETSC_INT_MAX / 4; /* overflow */
     62:   PetscCallQ(PetscCalloc(sizeof(void *) * _PetscFPTData->tablesize, &_PetscFPTData->functionpointer));
     63:   PetscCallQ(PetscMalloc(sizeof(char **) * _PetscFPTData->tablesize, &_PetscFPTData->functionname));
     64:   _PetscFPTData->count = 0;
     65:   PetscFPTData         = _PetscFPTData;
     66:   return PETSC_SUCCESS;
     67: }

     69: static inline unsigned long PetscFPTHashPointer(void *ptr)
     70: {
     71: #define PETSC_FPT_HASH_FACT 79943
     72:   return (PETSC_FPT_HASH_FACT * ((size_t)ptr)) % PetscFPTData->tablesize;
     73: }

     75: static inline PetscErrorCode PetscFPTAdd(void *key, const char *data)
     76: {
     77:   PetscCheck(data, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Null function name");
     78:   if (!PetscFPTData) return PETSC_SUCCESS;
     79:   for (unsigned long i = 0, hash = PetscFPTHashPointer(key); i < PetscFPTData->tablesize; ++i) {
     80:     if (PetscFPTData->functionpointer[hash] == key) {
     81:       PetscFPTData->functionname[hash] = (char *)data;
     82:       return PETSC_SUCCESS;
     83:     } else if (!PetscFPTData->functionpointer[hash]) {
     84:       PetscFPTData->count++;
     85:       PetscFPTData->functionpointer[hash] = key;
     86:       PetscFPTData->functionname[hash]    = (char *)data;
     87:       return PETSC_SUCCESS;
     88:     }
     89:     hash = (hash == (PetscFPTData->tablesize - 1)) ? 0 : hash + 1;
     90:   }
     91:   SETERRQ(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Function pointer table is full");
     92: }

     94: /*
     95:     PetscFPTFind - checks if a function pointer is in the table

     97:     If data==0, then no entry exists

     99: */
    100: static inline PetscErrorCode PetscFPTFind(void *key, char const **data)
    101: {
    102:   unsigned long hash, ii = 0;

    104:   *data = NULL;
    105:   if (!PetscFPTData) return PETSC_SUCCESS;
    106:   hash = PetscFPTHashPointer(key);
    107:   while (ii++ < PetscFPTData->tablesize) {
    108:     if (!PetscFPTData->functionpointer[hash]) break;
    109:     else if (PetscFPTData->functionpointer[hash] == key) {
    110:       *data = PetscFPTData->functionname[hash];
    111:       break;
    112:     }
    113:     hash = (hash == (PetscFPTData->tablesize - 1)) ? 0 : hash + 1;
    114:   }
    115:   return PETSC_SUCCESS;
    116: }