Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 27 additions & 16 deletions commonb.c
Original file line number Diff line number Diff line change
Expand Up @@ -1495,20 +1495,13 @@ unsigned long max_mem (
return (MAX_MEM);
}

/* Return memory (in MB) now available for a variable usage thread. */
/* This routine takes into account the memory used by other workers. */
/* Can we get "lots of memory", whatever that means? (Rules, slot counts) */

int avail_mem (
int thread_num,
unsigned long minimum_memory, /* If this much memory (in MB) can be returned without restarting other workers, then do so */
unsigned long desired_memory, /* If this much memory (in MB) can be returned without restarting other workers, then do so */
unsigned int *memory) /* Returned available memory, in MB */
int avail_mem_qualitative (
int thread_num) /* Returned available memory, in MB */
{
int i, fixed_threads[MAX_NUM_WORKERS];
unsigned long fixed_usage, variable_usage, num_variable_threads, avail, diff;

int lots_occupied = 0;
/* Check if we are in a period of forced low memory usage */

if (is_LowMemWhileRunning_active (thread_num)) {
MEM_RESTART_FLAGS[thread_num] |= MEM_RESTART_LOWMEM_ENDS;
return (STOP_NOT_ENOUGH_MEM);
Expand All @@ -1522,19 +1515,37 @@ int avail_mem (
return (STOP_NOT_ENOUGH_MEM);
}

/* Obtain lock before accessing memory global variables */
/* Check if we must wait for more memory to become available. This happens when we reach the maximum allowable number of threads using a lot of memory. */

gwmutex_lock (&MEM_MUTEX);
lots_occupied = are_threads_using_lots_of_memory (thread_num);
gwmutex_unlock (&MEM_MUTEX);

/* Check if we must wait for more memory to become available. This happens when we reach the maximum allowable number of threads using a lot of memory. */

if (are_threads_using_lots_of_memory (thread_num)) {
if (lots_occupied) {
MEM_RESTART_FLAGS[thread_num] |= MEM_RESTART_TOO_MANY_HIGHMEM;
gwmutex_unlock (&MEM_MUTEX);
OutputStr (thread_num, "Exceeded limit on number of workers that can use lots of memory.\n");
return (STOP_NOT_ENOUGH_MEM);
}

return (0);
}

/* Return memory (in MB) now available for a variable usage thread. */
/* This routine takes into account the memory used by other workers. */

int avail_mem (
int thread_num,
unsigned long minimum_memory, /* If this much memory (in MB) can be returned without restarting other workers, then do so */
unsigned long desired_memory, /* If this much memory (in MB) can be returned without restarting other workers, then do so */
unsigned int *memory) /* Returned available memory, in MB */
{
int i, fixed_threads[MAX_NUM_WORKERS];
unsigned long fixed_usage, variable_usage, num_variable_threads, avail, diff;

/* Obtain lock before accessing memory global variables */

gwmutex_lock (&MEM_MUTEX);

/* Set flag saying this will be a variable usage thread. Remember the */
/* "good enough" value as it will be helpful in determining the best */
/* value this routine should return (for this thread and other threads) */
Expand Down
16 changes: 15 additions & 1 deletion ecm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7806,6 +7806,13 @@ replan: unsigned long best_fftlen;
best_fails = 0;
best_poly_efficiency = 0.0;
msgbuf[0] = 0;

stop_reason = avail_mem_qualitative(thread_num);
if (stop_reason) {
if (ecmdata.state == ECM_STATE_MIDSTAGE) ecm_save (&ecmdata);
goto exit;
}

for (bool found_best = FALSE; ; ) {

/* Initialize the polymult library (needed for calling polymult_mem_required). Let user override polymult tuning parameters. */
Expand Down Expand Up @@ -12333,6 +12340,13 @@ replan: unsigned long best_fftlen;
best_fails = 0;
best_poly_efficiency = 0.0;
msgbuf[0] = 0;

stop_reason = avail_mem_qualitative(thread_num);
if (stop_reason) {
if (pm1data.state == PM1_STATE_MIDSTAGE) pm1_save (&pm1data);
goto exit;
}

//GW: Can we get here (old save files) with V set and one of x or invx not set? If so, switching is an issue unless we convert V to binary.
for (bool found_best = FALSE; ; ) {

Expand Down Expand Up @@ -14918,7 +14932,7 @@ int pp1_stage2_impl (
min_memory = 1 + cvt_gwnums_to_mem (&pp1data->gwdata, 8);
if (pp1data->state < PP1_STATE_STAGE2) desired_memory = 3 + cvt_gwnums_to_mem (&pp1data->gwdata, 144);
else desired_memory = (unsigned int) (pp1data->pairmap_size >> 20) + cvt_gwnums_to_mem (&pp1data->gwdata, pp1data->stage2_numvals);
stop_reason = avail_mem (pp1data->thread_num, min_memory, desired_memory, &memory);
stop_reason = avail_mem_qualitative (pp1data->thread_num) || avail_mem (pp1data->thread_num, min_memory, desired_memory, &memory);
if (stop_reason) return (stop_reason);

/* Factor in the multiplier that we set to less than 1.0 when we get unexpected memory allocation errors. */
Expand Down