// Allocate a new socket static int sock_open() { int i; mutex_lock(fd_mutex); for (i=0; i<SOCKFD_CNT; i++) if (!fds[i].inuse) break; if (i >= SOCKFD_CNT) i = -1; else { // Clean it out and set it as in-use memset(fds+i, 0, sizeof(sockfd_t)); fds[i].inuse = 1; } mutex_unlock(fd_mutex); // Setup some basic stuff fds[i].mutex = mutex_create(); fds[i].connect = cond_create(); fds[i].recv_avail = cond_create(); fds[i].send_avail = cond_create(); fds[i].connmax = 0; fds[i].conncnt = -1; fds[i].recv = -1; fds[i].send = -1; return i; }
/* * Initialization. * This function may be called multiple times when we are in * SML's commandline. */ void smlgtk_runtime_init() { static int init = FALSE; LOG("RUNTIME: smlgtk_runtime_init"); if (*init) { /* call this only once or glib will choke */ g_thread_init(NULL); init = TRUE; } else { /* Clean up previous versions of these data package */ cond_destroy(&event_pending); cond_destroy(&threadOk); cond_destroy(&response); g_mutex_free(signal_pending); } signal_queue_clear(); cond_create(&event_pending); cond_create(&response); cond_create(&threadOk); signal_pending = g_mutex_new(); signal_handler_added = FALSE; memset(&smlgtk_event,sizeof(struct smlgtk_event),0); if (thread_is_running) CHECK(hostthread_cancel(runtime_thread)); thread_is_running = FALSE; }
FixedSizeQueue *queue_init(int max_size) { FixedSizeQueue *queue; queue = malloc(sizeof(*queue) - sizeof(queue->data) + (max_size * sizeof(void *))); queue->start = 0; queue->size = 0; queue->max_size = max_size; queue->mutex = mutex_create(); queue->not_full = cond_create(); queue->not_empty = cond_create(); return queue; }
handler_t * handler_alloc (int queue_size) { int sz = sizeof (handler_t) + (queue_size-1) * sizeof (message_t); handler_t *h = malloc (sz); memset (h, 0, sz); h->mutex = mutex_create (); h->cond = cond_create (); return h; }
main (int argc, char *argv[]) { int number, i, j, offset; uint32 handle; sem_t spage; sem_t ipc_sem; char num_str[10], spage_str[10], handle_str[10], ipc_str[10]; DB * db; switch(argc) { case 2: handle = shmget(); db = (DB *)shmat(handle); if(db == NULL) { Printf("Could not map the shared page to virtual address, exiting..\n"); exit(); } db->end = 0; // Initially the end flag is 0 spage = sem_create(0); ipc_sem = cond_create(0); ditoa(handle, handle_str); ditoa(spage, spage_str); number = dstrtol(argv[1], NULL, 10); Printf("Setting number = %d\n", number); for(i = 0; i < number; i++) { //Printf("Current process : %d\n", i); ditoa(i, num_str); process_create("userprog4.dlx.obj", 1 + i, 0, num_str, spage_str, handle_str, NULL); // different p_nice for child process } sem_wait(spage); // wait for the children to reach 200 db->end = 1; // terminate children processes break; case 4: offset = dstrtol(argv[1], NULL, 10); spage = dstrtol(argv[2], NULL, 10); //ipc_sem = dstrtol(argv[3], NULL, 10); handle = dstrtol(argv[3], NULL, 10); db = (DB *)shmat(handle); if(db == NULL) { Printf("Could not map the virtual address to the memory, exiting...\n"); exit(); } sleep(100); for(i = 0; !db->end; i ++) { for(j = 0; j < 50000; j++) { //#ifdef sleep if(offset == 1 && j % 1000 == 0 && j <= 30000) sleep(1); //# endif #ifdef dynamic if(offset == 0 && j % 500 == 0 && j <= 3000) cond_wait(ipc_sem); if(offset == 1 && j % 600 == 0) cond_signal(ipc_sem); # endif } //waste some time Printf("%c%d\n",'A'+offset, i); if(i > 200) sem_signal(spage); //signal end } Printf("***** Process %d reached %d *****\n", getpid(), i); /* The expected output for the following run dlxsim -x os.dlx.obj -a -u userprog4.dlx.obj 2 is that the first process reaches an "i" which is roughly half of the "i" reached by the second process. This implies the second process gets scheduled for twice the time of the first process. Our output is ***** Process 29 reached 203 ***** ***** Process 30 reached 101 ***** Your output may differ a little bit due to randomness. */ break; default: Printf("Usage: "); Printf(argv[0]); Printf(" number\n"); Printf("argc = %d\n", argc); exit(); } }
void main (int argc, char *argv[]) { int numprocs = 5; // Used to store number of processes to create int i; // Loop index variable phil *p; // Used to get address of shared memory page uint32 h_mem; // Used to hold handle to shared memory page sem_t s_procs_completed; // Semaphore used to wait until all spawned processes have completed char h_mem_str[10]; // Used as command-line argument to pass mem_handle to new processes char s_procs_completed_str[10]; // Used as command-line argument to pass page_mapped handle to new processes char i_str[2]; if (argc != 1) { Printf("Usage: "); Printf(argv[0]); Printf("\n"); Exit(); } Printf("Creating %d processes\n", numprocs); // Allocate space for a shared memory page, which is exactly 64KB // Note that it doesn't matter how much memory we actually need: we // always get 64KB if ((h_mem = shmget()) == 0) { Printf("ERROR: could not allocate shared memory page in "); Printf(argv[0]); Printf(", exiting...\n"); Exit(); } // Map shared memory page into this process's memory space if ((p = (phil *)shmat(h_mem)) == NULL) { Printf("Could not map the shared page to virtual address in "); Printf(argv[0]); Printf(", exiting..\n"); Exit(); } // Put some values in the shared memory, to be read by other processes for (i = 0; i < 5; i++){ p->state[i] = THINKING; p->wait_locks[i] = lock_create(); p->self[i] = cond_create(p->wait_locks[i]); p->eaten[i] = 0; } // Create semaphore to not exit this process until all other processes // have signalled that they are complete. To do this, we will initialize // the semaphore to (-1) * (number of signals), where "number of signals" // should be equal to the number of processes we're spawning - 1. Once // each of the processes has signaled, the semaphore should be back to // zero and the final sem_wait below will return. if ((s_procs_completed = sem_create(-(numprocs-1))) == SYNC_FAIL) { Printf("Bad sem_create in "); Printf(argv[0]); Printf("\n"); Exit(); } // Setup the command-line arguments for the new process. We're going to // pass the handles to the shared memory page and the semaphore as strings // on the command line, so we must first convert them from ints to strings. ditoa(h_mem, h_mem_str); ditoa(s_procs_completed, s_procs_completed_str); // Now we can create the processes. Note that you MUST end your call to // process_create with a NULL argument so that the operating system // knows how many arguments you are sending. for(i=0; i<numprocs; i++) { ditoa(i, i_str); process_create(FILENAME_TO_RUN, h_mem_str, s_procs_completed_str, i_str , NULL); Printf("Process %d created\n", i); } // And finally, wait until all spawned processes have finished. if (sem_wait(s_procs_completed) != SYNC_SUCCESS) { Printf("Bad semaphore s_procs_completed (%d) in ", s_procs_completed); Printf(argv[0]); Printf("\n"); Exit(); } for (i = 0; i < numprocs; i++){ if (p->eaten[i] == 1){ Printf("Philosopher %d has eaten\n", i); }else{ Printf("Philosopher %d DID NOT eat\n", i); } } Printf("All other processes completed, exiting main process.\n"); }
void main (int argc, char *argv[]) { int numprocs = 0; // Used to store number of processes to create int i; // Loop index variable circular_buffer *cb; // Used to get address of shared memory page uint32 h_mem; // Used to hold handle to shared memory page sem_t h_procs_sem; // Semaphore used to wait until all spawned processes have completed lock_t h_cb_lock; // LOCK handles cond_t h_nFull_cv, h_nEmpty_cv; // Condition variables char h_mem_str[10]; // Used as command-line argument to pass mem_handle to new processes char h_procs_sem_str[10]; // Used as command-line argument to pass page_mapped handle to new processes char h_cb_lock_str[10]; char h_nFull_cv_str[10]; // Used as command-line arg char h_nEmpty_cv_str[10]; // Used as command-line arg if (argc != 2) { Printf("Usage: "); Printf(argv[0]); Printf(" <number of processes to create>\n"); Exit(); } // Convert string from ascii command line argument to integer number numprocs = dstrtol(argv[1], NULL, 10); // the "10" means base 10 Printf("Creating %d processes\n", 2*numprocs); // Allocate space for a shared memory page, which is exactly 64KB // Note that it doesn't matter how much memory we actually need: we // always get 64KB if ((h_mem = shmget()) == 0) { Printf("ERROR: could not allocate shared memory page in "); Printf(argv[0]); Printf(", exiting...\n"); Exit(); } // Map shared memory page into this process's memory space if ((cb = (circular_buffer *)shmat(h_mem)) == NULL) { Printf("Could not map the shared page to virtual address in "); Printf(argv[0]); Printf(", exiting..\n"); Exit(); } // Put some values in the shared memory, to be read by other processes cb->head = 0; cb->tail = 0; // Create semaphore to not exit this process until all other processes // have signalled that they are complete. To do this, we will initialize // the semaphore to (-1) * (number of signals), where "number of signals" // should be equal to the number of processes we're spawning - 1. Once // each of the processes has signaled, the semaphore should be back to // zero and the final sem_wait below will return. if ((h_procs_sem = sem_create(-(numprocs*2-1))) == SYNC_FAIL) { Printf("Bad sem_create in "); Printf(argv[0]); Printf("\n"); Exit(); } if((h_cb_lock = lock_create()) == SYNC_FAIL) { Printf("Bad lock_create in "); Exit(); } if((h_nFull_cv = cond_create(h_cb_lock)) == SYNC_FAIL) { Printf("Bad cond_create in "); Exit(); } if((h_nEmpty_cv = cond_create(h_cb_lock)) == SYNC_FAIL) { Printf("Bad cond_create in "); Exit(); } // Setup the command-line arguments for the new process. We're going to // pass the handles to the shared memory page and the semaphore as strings // on the command line, so we must first convert them from ints to strings. ditoa(h_mem, h_mem_str); ditoa(h_procs_sem, h_procs_sem_str); ditoa(h_cb_lock, h_cb_lock_str); ditoa(h_nFull_cv, h_nFull_cv_str); ditoa(h_nEmpty_cv, h_nEmpty_cv_str); // Now we can create the processes. Note that you MUST end your call to // process_create with a NULL argument so that the operating system // knows how many arguments you are sending. for(i=0; i < numprocs; i++) { process_create(CONSUMER_TO_RUN, h_mem_str, h_procs_sem_str, h_cb_lock_str, h_nFull_cv_str, h_nEmpty_cv_str, NULL); process_create(PRODUCER_TO_RUN, h_mem_str, h_procs_sem_str, h_cb_lock_str, h_nFull_cv_str, h_nEmpty_cv_str, NULL); Printf("Process %d created\n", i); } // And finally, wait until all spawned processes have finished. if (sem_wait(h_procs_sem) != SYNC_SUCCESS) { Printf("Bad semaphore s_procs_completed (%d) in ", h_procs_sem); Printf(argv[0]); Printf("\n"); Exit(); } Printf("All other processes completed, exiting main process.\n"); }