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: }