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:   PetscInt tablesize;
 21: };
 22: PETSC_INTERN PetscFPT PetscFPTData;

 24: static inline PetscErrorCode PetscFPTView(PetscViewer viewer)
 25: {
 26:   if (PetscFPTData) {
 27:     for (PetscInt 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 < 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 (PetscInt i = 0, hash = (PetscInt)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:   PetscInt 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: }