void * calloc(size_t n, size_t lb) { if ((lb | n) > GC_SQRT_SIZE_MAX /* fast initial test */ && lb && n > GC_SIZE_MAX / lb) return NULL; # if defined(GC_LINUX_THREADS) /* && !defined(USE_PROC_FOR_LIBRARIES) */ /* libpthread allocated some memory that is only pointed to by */ /* mmapped thread stacks. Make sure it's not collectable. */ { static GC_bool lib_bounds_set = FALSE; ptr_t caller = (ptr_t)__builtin_return_address(0); /* This test does not need to ensure memory visibility, since */ /* the bounds will be set when/if we create another thread. */ if (!lib_bounds_set) { GC_init_lib_bounds(); lib_bounds_set = TRUE; } if ((caller >= GC_libpthread_start && caller < GC_libpthread_end) || (caller >= GC_libld_start && caller < GC_libld_end)) return GC_malloc_uncollectable(n*lb); /* The two ranges are actually usually adjacent, so there may */ /* be a way to speed this up. */ } # endif return((void *)REDIRECT_MALLOC(n*lb)); }
/* This makes sure that the garbage collector sees all allocations, even those that we can't be bothered collecting, especially standard STL objects */ void* operator new(size_t n) { #ifdef DONT_COLLECT_STL return GC_malloc_uncollectable(n); // Don't collect, but mark #else return GC_malloc(n); // Collect everything #endif }
GC_API GC_ATTR_MALLOC void * GC_CALL GC_debug_malloc_uncollectable(size_t lb, GC_EXTRA_PARAMS) { void * result = GC_malloc_uncollectable( SIZET_SAT_ADD(lb, UNCOLLECTABLE_DEBUG_BYTES)); return store_debug_info(result, lb, "GC_debug_malloc_uncollectable", OPT_RA s, i); }
GC_API void * GC_CALL GC_debug_malloc_uncollectable(size_t lb, GC_EXTRA_PARAMS) { void * result = GC_malloc_uncollectable(lb + UNCOLLECTABLE_DEBUG_BYTES); if (result == 0) { GC_err_printf("GC_debug_malloc_uncollectable(%lu)" " returning NULL (%s:%d)\n", (unsigned long)lb, s, i); return(0); } if (!GC_debugging_started) { GC_start_debugging(); } ADD_CALL_CHAIN(result, ra); return (GC_store_debug_info(result, (word)lb, s, i)); }
/* Cygwin-pthreads calls CreateThread internally, but it's not * easily interceptible by us.. * so intercept pthread_create instead */ int GC_pthread_create(pthread_t *new_thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg) { int result; struct start_info * si; if (!parallel_initialized) GC_init_parallel(); /* make sure GC is initialized (i.e. main thread is attached) */ if (GC_win32_dll_threads) { return pthread_create(new_thread, attr, start_routine, arg); } /* This is otherwise saved only in an area mmapped by the thread */ /* library, which isn't visible to the collector. */ si = GC_malloc_uncollectable(sizeof(struct start_info)); if (0 == si) return(EAGAIN); si -> start_routine = start_routine; si -> arg = arg; if (attr != 0 && pthread_attr_getdetachstate(attr, &si->detached) == PTHREAD_CREATE_DETACHED) { si->detached = TRUE; } # if DEBUG_CYGWIN_THREADS GC_printf("About to create a thread from 0x%x(0x%x)\n", (int)pthread_self(), GetCurrentThreadId); # endif # if DEBUG_WIN32_PTHREADS GC_printf("About to create a thread from 0x%x(0x%x)\n", (int)(pthread_self()).p, GetCurrentThreadId()); # endif GC_need_to_lock = TRUE; result = pthread_create(new_thread, attr, GC_pthread_start, si); if (result) { /* failure */ GC_free(si); } return(result); }
GC_API HANDLE WINAPI GC_CreateThread( LPSECURITY_ATTRIBUTES lpThreadAttributes, DWORD dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId ) { HANDLE thread_h = NULL; thread_args *args; if (!parallel_initialized) GC_init_parallel(); /* make sure GC is initialized (i.e. main thread is attached, tls initialized) */ # if DEBUG_WIN32_THREADS GC_printf("About to create a thread from 0x%x\n", GetCurrentThreadId()); # endif if (GC_win32_dll_threads) { return CreateThread(lpThreadAttributes, dwStackSize, lpStartAddress, lpParameter, dwCreationFlags, lpThreadId); } else { args = GC_malloc_uncollectable(sizeof(thread_args)); /* Handed off to and deallocated by child thread. */ if (0 == args) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); return NULL; } /* set up thread arguments */ args -> start = lpStartAddress; args -> param = lpParameter; GC_need_to_lock = TRUE; thread_h = CreateThread(lpThreadAttributes, dwStackSize, GC_win32_start, args, dwCreationFlags, lpThreadId); if( thread_h == 0 ) GC_free( args ); return thread_h; } }
uintptr_t GC_beginthreadex( void *security, unsigned stack_size, unsigned ( __stdcall *start_address )( void * ), void *arglist, unsigned initflag, unsigned *thrdaddr) { uintptr_t thread_h; thread_args *args; if (!parallel_initialized) GC_init_parallel(); /* make sure GC is initialized (i.e. main thread is attached, tls initialized) */ # if DEBUG_WIN32_THREADS GC_printf("About to create a thread from 0x%x\n", GetCurrentThreadId()); # endif if (GC_win32_dll_threads) { return _beginthreadex(security, stack_size, start_address, arglist, initflag, thrdaddr); } else { args = GC_malloc_uncollectable(sizeof(thread_args)); /* Handed off to and deallocated by child thread. */ if (0 == args) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); return (uintptr_t)(-1L); } /* set up thread arguments */ args -> start = (LPTHREAD_START_ROUTINE)start_address; args -> param = arglist; GC_need_to_lock = TRUE; thread_h = _beginthreadex(security, stack_size, (unsigned (__stdcall *) (void *))GC_win32_start, args, initflag, thrdaddr); if( thread_h == 0 ) GC_free( args ); return thread_h; } }
int dassl_initial(DATA* data, threadData_t *threadData, SOLVER_INFO* solverInfo, DASSL_DATA *dasslData) { TRACE_PUSH /* work arrays for DASSL */ unsigned int i; SIMULATION_DATA tmpSimData = {0}; RHSFinalFlag = 0; dasslData->liw = 40 + data->modelData.nStates; dasslData->lrw = 60 + ((maxOrder + 4) * data->modelData.nStates) + (data->modelData.nStates * data->modelData.nStates) + (3*data->modelData.nZeroCrossings); dasslData->rwork = (double*) calloc(dasslData->lrw, sizeof(double)); assertStreamPrint(threadData, 0 != dasslData->rwork,"out of memory"); dasslData->iwork = (int*) calloc(dasslData->liw, sizeof(int)); assertStreamPrint(threadData, 0 != dasslData->iwork,"out of memory"); dasslData->ng = (int) data->modelData.nZeroCrossings; dasslData->jroot = (int*) calloc(data->modelData.nZeroCrossings, sizeof(int)); dasslData->rpar = (double**) malloc(3*sizeof(double*)); dasslData->ipar = (int*) malloc(sizeof(int)); dasslData->ipar[0] = ACTIVE_STREAM(LOG_JAC); assertStreamPrint(threadData, 0 != dasslData->ipar,"out of memory"); dasslData->atol = (double*) malloc(data->modelData.nStates*sizeof(double)); dasslData->rtol = (double*) malloc(data->modelData.nStates*sizeof(double)); dasslData->info = (int*) calloc(infoLength, sizeof(int)); assertStreamPrint(threadData, 0 != dasslData->info,"out of memory"); dasslData->dasslStatistics = (unsigned int*) calloc(numStatistics, sizeof(unsigned int)); assertStreamPrint(threadData, 0 != dasslData->dasslStatistics,"out of memory"); dasslData->dasslStatisticsTmp = (unsigned int*) calloc(numStatistics, sizeof(unsigned int)); assertStreamPrint(threadData, 0 != dasslData->dasslStatisticsTmp,"out of memory"); dasslData->idid = 0; dasslData->sqrteps = sqrt(DBL_EPSILON); dasslData->ysave = (double*) malloc(data->modelData.nStates*sizeof(double)); dasslData->delta_hh = (double*) malloc(data->modelData.nStates*sizeof(double)); dasslData->newdelta = (double*) malloc(data->modelData.nStates*sizeof(double)); dasslData->stateDer = (double*) malloc(data->modelData.nStates*sizeof(double)); dasslData->currentContext = CONTEXT_UNKNOWN; /* setup internal ring buffer for dassl */ /* RingBuffer */ dasslData->simulationData = 0; dasslData->simulationData = allocRingBuffer(SIZERINGBUFFER, sizeof(SIMULATION_DATA)); if(!data->simulationData) { throwStreamPrint(threadData, "Your memory is not strong enough for our Ringbuffer!"); } /* prepare RingBuffer */ for(i=0; i<SIZERINGBUFFER; i++) { /* set time value */ tmpSimData.timeValue = 0; /* buffer for all variable values */ tmpSimData.realVars = (modelica_real*)calloc(data->modelData.nVariablesReal, sizeof(modelica_real)); assertStreamPrint(threadData, 0 != tmpSimData.realVars, "out of memory"); tmpSimData.integerVars = (modelica_integer*)calloc(data->modelData.nVariablesInteger, sizeof(modelica_integer)); assertStreamPrint(threadData, 0 != tmpSimData.integerVars, "out of memory"); tmpSimData.booleanVars = (modelica_boolean*)calloc(data->modelData.nVariablesBoolean, sizeof(modelica_boolean)); assertStreamPrint(threadData, 0 != tmpSimData.booleanVars, "out of memory"); tmpSimData.stringVars = (modelica_string*) GC_malloc_uncollectable(data->modelData.nVariablesString * sizeof(modelica_string)); assertStreamPrint(threadData, 0 != tmpSimData.stringVars, "out of memory"); appendRingData(dasslData->simulationData, &tmpSimData); } dasslData->localData = (SIMULATION_DATA**) GC_malloc_uncollectable(SIZERINGBUFFER * sizeof(SIMULATION_DATA)); memset(dasslData->localData, 0, SIZERINGBUFFER * sizeof(SIMULATION_DATA)); rotateRingBuffer(dasslData->simulationData, 0, (void**) dasslData->localData); /* end setup internal ring buffer for dassl */ /* ### start configuration of dassl ### */ infoStreamPrint(LOG_SOLVER, 1, "Configuration of the dassl code:"); /* set nominal values of the states for absolute tolerances */ dasslData->info[1] = 1; infoStreamPrint(LOG_SOLVER, 1, "The relative tolerance is %g. Following absolute tolerances are used for the states: ", data->simulationInfo.tolerance); for(i=0; i<data->modelData.nStates; ++i) { dasslData->rtol[i] = data->simulationInfo.tolerance; dasslData->atol[i] = data->simulationInfo.tolerance * fmax(fabs(data->modelData.realVarsData[i].attribute.nominal), 1e-32); infoStreamPrint(LOG_SOLVER, 0, "%d. %s -> %g", i+1, data->modelData.realVarsData[i].info.name, dasslData->atol[i]); } messageClose(LOG_SOLVER); /* let dassl return at every internal step */ dasslData->info[2] = 1; /* define maximum step size, which is dassl is allowed to go */ if (omc_flag[FLAG_MAX_STEP_SIZE]) { double maxStepSize = atof(omc_flagValue[FLAG_MAX_STEP_SIZE]); assertStreamPrint(threadData, maxStepSize >= DASSL_STEP_EPS, "Selected maximum step size %e is too small.", maxStepSize); dasslData->rwork[1] = maxStepSize; dasslData->info[6] = 1; infoStreamPrint(LOG_SOLVER, 0, "maximum step size %g", dasslData->rwork[1]); } else { infoStreamPrint(LOG_SOLVER, 0, "maximum step size not set"); } /* define initial step size, which is dassl is used every time it restarts */ if (omc_flag[FLAG_INITIAL_STEP_SIZE]) { double initialStepSize = atof(omc_flagValue[FLAG_INITIAL_STEP_SIZE]); assertStreamPrint(threadData, initialStepSize >= DASSL_STEP_EPS, "Selected initial step size %e is too small.", initialStepSize); dasslData->rwork[2] = initialStepSize; dasslData->info[7] = 1; infoStreamPrint(LOG_SOLVER, 0, "initial step size %g", dasslData->rwork[2]); } else { infoStreamPrint(LOG_SOLVER, 0, "initial step size not set"); } /* define maximum integration order of dassl */ if (omc_flag[FLAG_MAX_ORDER]) { int maxOrder = atoi(omc_flagValue[FLAG_MAX_ORDER]); assertStreamPrint(threadData, maxOrder >= 1 && maxOrder <= 5, "Selected maximum order %d is out of range (1-5).", maxOrder); dasslData->iwork[2] = maxOrder; dasslData->info[8] = 1; } infoStreamPrint(LOG_SOLVER, 0, "maximum integration order %d", dasslData->info[8]?dasslData->iwork[2]:maxOrder); /* if FLAG_NOEQUIDISTANT_GRID is set, choose dassl step method */ if (omc_flag[FLAG_NOEQUIDISTANT_GRID]) { dasslData->dasslSteps = 1; /* TRUE */ solverInfo->solverNoEquidistantGrid = 1; } else { dasslData->dasslSteps = 0; /* FALSE */ } infoStreamPrint(LOG_SOLVER, 0, "use equidistant time grid %s", dasslData->dasslSteps?"NO":"YES"); /* check if Flags FLAG_NOEQUIDISTANT_OUT_FREQ or FLAG_NOEQUIDISTANT_OUT_TIME are set */ if (dasslData->dasslSteps){ if (omc_flag[FLAG_NOEQUIDISTANT_OUT_FREQ]) { dasslData->dasslStepsFreq = atoi(omc_flagValue[FLAG_NOEQUIDISTANT_OUT_FREQ]); } else if (omc_flag[FLAG_NOEQUIDISTANT_OUT_TIME]) { dasslData->dasslStepsTime = atof(omc_flagValue[FLAG_NOEQUIDISTANT_OUT_TIME]); dasslData->rwork[1] = dasslData->dasslStepsTime; dasslData->info[6] = 1; infoStreamPrint(LOG_SOLVER, 0, "maximum step size %g", dasslData->rwork[1]); } else { dasslData->dasslStepsFreq = 1; dasslData->dasslStepsTime = 0.0; } if (omc_flag[FLAG_NOEQUIDISTANT_OUT_FREQ] && omc_flag[FLAG_NOEQUIDISTANT_OUT_TIME]){ warningStreamPrint(LOG_STDOUT, 0, "The flags are \"noEquidistantOutputFrequency\" " "and \"noEquidistantOutputTime\" are in opposition " "to each other. The flag \"noEquidistantOutputFrequency\" superiors."); } infoStreamPrint(LOG_SOLVER, 0, "as the output frequency control is used: %d", dasslData->dasslStepsFreq); infoStreamPrint(LOG_SOLVER, 0, "as the output frequency time step control is used: %f", dasslData->dasslStepsTime); } /* if FLAG_DASSL_JACOBIAN is set, choose dassl jacobian calculation method */ if (omc_flag[FLAG_DASSL_JACOBIAN]) { for(i=1; i< DASSL_JAC_MAX;i++) { if(!strcmp((const char*)omc_flagValue[FLAG_DASSL_JACOBIAN], dasslJacobianMethodStr[i])){ dasslData->dasslJacobian = (int)i; break; } } if(dasslData->dasslJacobian == DASSL_JAC_UNKNOWN) { if (ACTIVE_WARNING_STREAM(LOG_SOLVER)) { warningStreamPrint(LOG_SOLVER, 1, "unrecognized jacobian calculation method %s, current options are:", (const char*)omc_flagValue[FLAG_DASSL_JACOBIAN]); for(i=1; i < DASSL_JAC_MAX; ++i) { warningStreamPrint(LOG_SOLVER, 0, "%-15s [%s]", dasslJacobianMethodStr[i], dasslJacobianMethodDescStr[i]); } messageClose(LOG_SOLVER); } throwStreamPrint(threadData,"unrecognized jacobian calculation method %s", (const char*)omc_flagValue[FLAG_DASSL_JACOBIAN]); } /* default case colored numerical jacobian */ } else { dasslData->dasslJacobian = DASSL_COLOREDNUMJAC; } /* selects the calculation method of the jacobian */ if(dasslData->dasslJacobian == DASSL_COLOREDNUMJAC || dasslData->dasslJacobian == DASSL_COLOREDSYMJAC || dasslData->dasslJacobian == DASSL_NUMJAC || dasslData->dasslJacobian == DASSL_SYMJAC) { if (data->callback->initialAnalyticJacobianA(data, threadData)) { infoStreamPrint(LOG_STDOUT, 0, "Jacobian or SparsePattern is not generated or failed to initialize! Switch back to normal."); dasslData->dasslJacobian = DASSL_INTERNALNUMJAC; } else { dasslData->info[4] = 1; /* use sub-routine JAC */ } } /* set up the appropriate function pointer */ switch (dasslData->dasslJacobian){ case DASSL_COLOREDNUMJAC: dasslData->jacobianFunction = JacobianOwnNumColored; break; case DASSL_COLOREDSYMJAC: dasslData->jacobianFunction = JacobianSymbolicColored; break; case DASSL_SYMJAC: dasslData->jacobianFunction = JacobianSymbolic; break; case DASSL_NUMJAC: dasslData->jacobianFunction = JacobianOwnNum; break; case DASSL_INTERNALNUMJAC: dasslData->jacobianFunction = dummy_Jacobian; break; default: throwStreamPrint(threadData,"unrecognized jacobian calculation method %s", (const char*)omc_flagValue[FLAG_DASSL_JACOBIAN]); break; } infoStreamPrint(LOG_SOLVER, 0, "jacobian is calculated by %s", dasslJacobianMethodDescStr[dasslData->dasslJacobian]); /* if FLAG_DASSL_NO_ROOTFINDING is set, choose dassl with out internal root finding */ if(omc_flag[FLAG_DASSL_NO_ROOTFINDING]) { dasslData->dasslRootFinding = 0; dasslData->zeroCrossingFunction = dummy_zeroCrossing; dasslData->ng = 0; } else { solverInfo->solverRootFinding = 1; dasslData->dasslRootFinding = 1; dasslData->zeroCrossingFunction = function_ZeroCrossingsDASSL; } infoStreamPrint(LOG_SOLVER, 0, "dassl uses internal root finding method %s", dasslData->dasslRootFinding?"YES":"NO"); /* if FLAG_DASSL_NO_RESTART is set, choose dassl step method */ if (omc_flag[FLAG_DASSL_NO_RESTART]) { dasslData->dasslAvoidEventRestart = 1; /* TRUE */ } else { dasslData->dasslAvoidEventRestart = 0; /* FALSE */ } infoStreamPrint(LOG_SOLVER, 0, "dassl performs an restart after an event occurs %s", dasslData->dasslAvoidEventRestart?"NO":"YES"); /* ### end configuration of dassl ### */ messageClose(LOG_SOLVER); TRACE_POP return 0; }
static int riva_load(module_t *Module, const char *FileName) { riva_t *Riva = unew(riva_t); // This really should be new... module_setup(Module, Riva, (module_importer)riva_import); gzFile File = gzopen(FileName, "rb"); char *LoadPath; for (int I = strlen(FileName) - 1; I >= 0; --I) { if (FileName[I] == PATHCHR) { strncpy(LoadPath = (char *)GC_malloc_atomic(I + 2), FileName, I + 1); break; }; }; module_set_path(Module, LoadPath); uint32_t Magic; gzread(File, &Magic, 4); if (Magic != 0x41564952) { log_errorf("Error: %s is not a valid riva module\n", FileName); return 0; }; uint32_t NoOfSections; gzread(File, &NoOfSections, 4); uint32_t NoOfExports; gzread(File, &NoOfExports, 4); uint32_t NoOfRequires; gzread(File, &NoOfRequires, 4); jmp_buf OnError[1]; if (setjmp(OnError)) return 0; section_t **Sections = (Riva->Sections = (section_t **)GC_malloc(NoOfSections * sizeof(section_t *))); for (int I = 0; I < NoOfSections; ++I) Sections[I] = new(section_t); for (int I = 0; I < NoOfSections; ++I) { section_t *Section = Sections[I]; uint8_t Type; gzread(File, &Type, 1); switch (Type) { case SECT_CODE: { Section->Fixup = fixup_code_section; gzread(File, &Section->Flags, 1); uint32_t Length; gzread(File, &Length, 4); uint32_t NoOfRelocs; gzread(File, &NoOfRelocs, 4); Section->NoOfRelocs = NoOfRelocs; reloc_t *Relocs = (Section->Relocs = (reloc_t *)GC_malloc_uncollectable(NoOfRelocs * sizeof(reloc_t))); if (Section->Flags & FLAG_GC) { Section->Data = GC_malloc_uncollectable(Length); } else { Section->Data = GC_malloc_atomic_uncollectable(Length); }; gzread(File, Section->Data, Length); for (int J = 0; J < NoOfRelocs; ++J) { reloc_t *Reloc = &Relocs[J]; gzread(File, &Reloc->Size, 1); gzread(File, &Reloc->Flags, 1); gzread(File, &Reloc->Position, 4); uint32_t Index; gzread(File, &Index, 4); Reloc->Section = Sections[Index]; }; break;}; case SECT_LIBRARY: { Section->Fixup = fixup_library_section; gzread(File, &Section->Flags, 1); uint32_t Length; gzread(File, &Length, 4); gzread(File, Section->Name = (char *)GC_malloc_atomic(Length + 1), Length); Section->Name[Length] = 0; if (Section->Flags == LIBRARY_ABS) { Section->Path = 0; } else if (Section->Flags == LIBRARY_REL) { Section->Path = LoadPath; }; for (char *P = Section->Name; *P; ++P) if (*P == '/') *P = PATHCHR; break;}; case SECT_IMPORT: { Section->Fixup = fixup_import_section; gzread(File, &Section->Flags, 1); uint32_t Index; gzread(File, &Index, 4); Section->Library = Sections[Index]; uint32_t Length; gzread(File, &Length, 4); gzread(File, Section->Name = (char *)GC_malloc_atomic(Length + 1), Length); Section->Name[Length] = 0; break;}; case SECT_BSS: { Section->Fixup = fixup_bss_section; gzread(File, &Section->Flags, 1); uint32_t Size; gzread(File, &Size, 4); Section->Data = (uint8_t *)GC_malloc(Size); break;}; case SECT_SYMBOL: { Section->Fixup = fixup_symbol_section; gzread(File, &Section->Flags, 1); uint32_t Length; gzread(File, &Length, 4); gzread(File, Section->Name = (char *)GC_malloc_atomic(Length + 1), Length); Section->Name[Length] = 0; break;}; }; }; for (int I = 0; I < NoOfExports; ++I) { export_t *Export = new(export_t); gzread(File, &Export->Flags, 1); uint32_t Index; gzread(File, &Index, 4); Export->Section = Sections[Index]; gzread(File, &Export->Offset, 4); uint32_t Length; gzread(File, &Length, 4); char *Name = (char *)GC_malloc_atomic(Length + 1); gzread(File, Name, Length); Name[Length] = 0; stringtable_put(Riva->Exports, Name, Export); }; for (int I = 0; I < NoOfRequires; ++I) { uint8_t Flags; gzread(File, &Flags, 1); uint32_t Length; gzread(File, &Length, 4); char *Name = (char *)GC_malloc_atomic(Length + 1); char *Path = 0; gzread(File, Name, Length); Name[Length] = 0; if (Flags == LIBRARY_REL) Path = LoadPath; for (char *P = Name; *P; ++P) if (*P == '/') *P = PATHCHR; module_load(Path, Name); }; gzclose(File); void (*__init)(module_t *) = check_import(Riva, "__init", OnError); if (__init) __init(Module); void *Methods = check_import(Riva, "__methods", OnError); if (Methods) add_methods(Methods); return 1; };