Exemple #1
0
int test1(void)
{
	void **ptrs;
	int i,j;
	int size;
	int ret = 0;

	srandom(0x19730929);

	ptrs = malloc(N_PTRS*sizeof(void *));

	for(i=0; i<N_PTRS; i++){
		if ((ptrs[i] = malloc(random_size())) == NULL) {
			printf("malloc random failed! %i\n", i);
			++ret;
		}
	}
	for(i=0; i<N_ALLOCS; i++){
		j = random_ptr();
		free(ptrs[j]);

		size = random_size();
		ptrs[j] = malloc(size);
		if (!ptrs[j]) {
			printf("malloc failed! %d\n", i);
			++ret;
		}
		memset(ptrs[j],0,size);
	}
	for(i=0; i<N_PTRS; i++){
		free(ptrs[i]);
	}

	return ret;
}
Exemple #2
0
static void ts_mem_check(void * arg) {

  t_mchecker mc = arg;
  x_thread thread = mc->thread;
  x_size size;
  x_size old_size;
  x_size blocks_in_use = 0;
  t_Block Initial;
  t_block initial = &Initial;
  t_block block;
  x_int command;
  x_size discards = 0;
  x_size frees = 0;
  x_size allocs = 0;
  x_size reallocs_g = 0;
  x_size reallocs_s = 0;

  /*
  ** Initialize our own list.
  */

  initial->size = 1024 * 1024 * 30;
  x_list_init(initial);

  /*
  ** ... and check dynamic allocation and deallocation forever ...
  */

  while (1) {
  
    /*
    ** Select the operation: 0 and 1 = allocation, 2 = reallocation, 3 = change owner and 4 = free or discard
    */
    
    command = x_random() % 5;
    block = NULL;

    if (force_next_is_release || global_force_release) {
      command = 4;
      force_next_is_release = 0;
    }
    else if (force_next_is_allocation) {
      command = 0;
    }

    /*
    ** If we have released all our blocks due to a global force release command and
    ** we have no blocks left, we sleep so that other threads can start dumping their
    ** blocks.
    */

    if (global_force_release && blocks_in_use == 0) {
      x_thread_sleep(2);
    }

    /*
    ** Only do allocations when we have not all blocks in use.
    */

    if ((command == 1 || command == 0) && (blocks_in_use < max_blocks_in_use)) { 
      size = random_size();

      block = allocate_block(mc, initial, size, x_random() & 0x00000001);
      allocs += 1;
      if (block == NULL) {
        force_next_is_release = 1;
        global_force_release = 1;
        oempa("No more memory for %d bytes. Global force releasing enabled, %d bytes in use.\n", size, global_in_use);
        continue;
      }
      
      blocks_in_use += 1;
      allocations += 1;

      if (force_next_is_allocation) {
        force_next_is_allocation = 0;
      }

    }
    else if (command == 2) {
      block = initial->next;
      if (block != initial) {
        size = random_size();
        old_size = block->size;
        block = reallocate_block(mc, initial, block, size);
        if (old_size < size) {
          reallocs_g += 1;
        }
        else {
          reallocs_s += 1;
        }
        allocs += 1;
        if (block == NULL) {
          force_next_is_release = 1;
          global_force_release = 1;
          continue;
        }
      
        reallocations += 1;

      }
    }
    else if (command == 3) {
      block = initial->next;
    }
    else {
      block = initial->next;
      if (block != initial) {
        if (x_random() % 5 == 0) {
          release_block(mc, block, true, 1);
          discards += 1;
        }
        else {
          release_block(mc, block, true, 0);
          frees += 1;
        }
        blocks_in_use -= 1;
        releases += 1;
      }
    }

    if (allocs > 0 && allocs % 4000 == 0) {
      oempa("Thread %p: A %d Rg %d Rs %d D %d F %d\n", thread, allocs, reallocs_g, reallocs_s, discards, frees);
      force_next_is_allocation = 1;
    }

    if (allocs > 0 && allocs % 2000 == 0) {
      x_thread_sleep((x_random() % 10) + 10);
    }

  }
  
}
void Simulator_run(size_t initial_memory,
                   int use_custom_allocator,
                   size_t process_limit)
{
    // seed pseudo-random number generator
    seed_rand();

    // setup non-reentrant variables for Standard Deviation,
    // which allows Simulator_run to be fully reentrant
    InitSD();

    for (size_t i = 0; i < PROCESS_COUNT; ++i) {
        // randomize pid, cycles, and memory size for each process
        processes[i].pid = unique_pid();
        processes[i].cycles = random_cycles();
        processes[i].size = random_size();

        // set process state to ready, and reset time variables.
        // this allows Simulator_run to be fully reentrant
        processes[i].state = PROCESS_READY;
        processes[i].malloc_time = 0;
        processes[i].free_time = 0;
    }

    memory = initial_memory;
    total_memory = initial_memory;

    active_process_count = 0;
    active_process_limit = process_limit;

    unsigned int timer = 0;
    unsigned int frame_count = 0;

    // disable cursor (improves flickering substantially)
    printf("\033[?25l");


    printf("INITIAL MEMORY:     %zu\n"
           "USING CUSTOM ALLOC: %s\n"
           "PROCESS LIMIT:      %zu\n\n",
           initial_memory,
           (use_custom_allocator) ? "true" : "false",
           process_limit);


    Timer_start(&start_time);

    // allocate memory pool
    MemoryPool *memory_pool = NULL;
    if (use_custom_allocator) {
        memory_pool = MemoryPool_create(total_memory);
    }
    while (1) {
        // count the total number of running and complete processes
        running_count = 0;
        complete_count = 0;
        for (size_t i = 0; i < PROCESS_COUNT; ++i) {
            if (processes[i].state == PROCESS_COMPLETE) {
                ++complete_count;
            }
            else if (processes[i].state == PROCESS_RUNNING) {
                ++running_count;
            }
        }

        // if we've all processes have completed, exit the program
        if (complete_count == PROCESS_COUNT) {
            draw_process_table();
            break;
        }

        // every 50 cycles, attempt to start ready processes
        if (timer == 49) {
            timer = 0;

            // set all ready processes that will fit in memory to running state
            for (size_t i = 0; i < PROCESS_COUNT; ++i) {
                if ((active_process_limit == 0 || active_process_count < active_process_limit)
                    && processes[i].state == PROCESS_READY
                    && processes[i].size < memory
                ) {
                    ++active_process_count;
                    processes[i].state = PROCESS_RUNNING;
                    memory -= processes[i].size;
                    processes[i].cycles_remaining = processes[i].cycles;

                    // attempt to allocate process' memory
                    Timer_start(&malloc_start_time);
                    if (use_custom_allocator) {
                        processes[i].data = my_malloc(memory_pool, processes[i].size);
                    }
                    else {
                        processes[i].data = malloc(processes[i].size);
                    }
                    processes[i].malloc_time = Timer_stop(malloc_start_time,
                                                          &malloc_end_time);

                    if (processes[i].data == NULL) {
                        printf("Error: Failed to allocate "
                               "memory for process %u\n",
                               processes[i].pid);
                        break;
                    }

                    draw_process_table();
                }
            }
        }

        // update running processes
        for (size_t i = 0; i < PROCESS_COUNT; ++i) {
            if (processes[i].state == PROCESS_RUNNING) {
                // if the current process is complete, update the system
                if (processes[i].cycles_remaining == 0) {
                    --active_process_count;
                    processes[i].state = PROCESS_COMPLETE;
                    memory += processes[i].size;

                    // attempt to free process' memory
                    if (processes[i].data != NULL) {
                        Timer_start(&malloc_start_time);
                        if (use_custom_allocator) {
                            my_free(memory_pool,
                                    processes[i].data,
                                    processes[i].size);
                            processes[i].data = NULL;
                        }
                        else {
                            free(processes[i].data);
                            processes[i].data = NULL;
                        }
                        processes[i].free_time = Timer_stop(malloc_start_time,
                                                            &malloc_end_time);
                    }
                }
                else {
                    --processes[i].cycles_remaining;
                }
            }
        }

        // print process table every 25 frames
        if (frame_count == 24) {
            frame_count = 0;
            draw_process_table();
        }

        // update counters and sleep 10 milliseconds
        ++timer;
        ++frame_count;
        sleep_ms(10);
    }

    // deallocate memory pool
    if (use_custom_allocator) {
        MemoryPool_destroy(memory_pool);
    }

    // measure total execution time of simulation
    double total_time = Timer_stop(start_time, &end_time);

    for (size_t i = 0; i < PROCESS_COUNT; ++i) {
        printf("%u, %zu, %zu, %0.3lf, %0.3lf\n",
               processes[i].pid,
               processes[i].cycles,
               processes[i].size,
               processes[i].malloc_time,
               processes[i].free_time);
    }
    printf("\nTotal Execution Time: %0.3lf ms\n\n", total_time);

    // re-enable cursor
    printf("\033[?25h");
}