int main(void) { pthread_t pthread1, pthread2, pthread3; semaphore_t* sem = g_sem; kern_return_t kr; setbuf(stdout, NULL); kr = semaphore_create(mach_task_self(), &sem[0], SYNC_POLICY_FIFO, 0); OUT_ON_MACH_ERROR("semaphore_create", kr); kr = semaphore_create(mach_task_self(), &sem[1], SYNC_POLICY_FIFO, 0); OUT_ON_MACH_ERROR("semaphore_create", kr); (void)pthread_create(&pthread1, (const pthread_attr_t *)0, start_routine, (void *) 0); printf("created thread1=%lx\n", 0); (void)pthread_create(&pthread2, (const pthread_attr_t *)0, start_routine, (void *) 1); printf("created thread2=%lx\n", 1); (void)pthread_create(&pthread3, (const pthread_attr_t *)0, start_routine, (void *) 2); printf("created thread3=%lx\n", 2); // wait until all three threads are ready SEMAPHORE_WAIT(sem[1], 3); // printf("main: about to signal thread3\n"); // semaphore_signal_thread(sem[0], pthread_mach_thread_np(pthread3)); // wait for thread3 to sem_signal() // semaphore_wait(sem[1]); sleep(1); printf("main: about to signal all threads\n"); semaphore_signal_all(sem[0]); // wait for thread1 and thread2 to sem_signal() SEMAPHORE_WAIT(sem[1], 3); out: if (sem[0]) semaphore_destroy(mach_task_self(), sem[0]); if (sem[1]) semaphore_destroy(mach_task_self(), sem[1]); exit(kr); }
int main(void) { kern_return_t kr; int status; mach_port_t mytask = mach_task_self(); mach_vm_size_t size = (mach_vm_size_t)vm_page_size; kr = mach_vm_allocate(mytask, &page_shared, size, VM_FLAGS_ANYWHERE); OUT_ON_MACH_ERROR("vm_allocate", kr); kr = mach_vm_allocate(mytask, &page_cow, size, VM_FLAGS_ANYWHERE); OUT_ON_MACH_ERROR("vm_allocate", kr); kr = mach_vm_inherit(mytask, page_shared, size, VM_INHERIT_SHARE); OUT_ON_MACH_ERROR("vm_inherit(VM_INHERIT_SHARE)", kr); kr = mach_vm_inherit(mytask, page_cow, size, VM_INHERIT_COPY); OUT_ON_MACH_ERROR("vm_inherit(VM_INHERIT_COPY)", kr); FIRST_UINT32(page_shared) = (unsigned int)0xAAAAAAAA; FIRST_UINT32(page_cow) = (unsigned int)0xBBBBBBBB; printf("%-12s%-8s%-10s%-12s%-10s%s\n", "Process", "Page", "Contents", "VM Object", "Refcount", "Event"); peek_at_some_memory("parent", "before forking"); if (fork() == 0) child_process(); // this will also exit the child wait(&status); peek_at_some_memory("parent", "after child is done"); out: mach_vm_deallocate(mytask, page_shared, size); mach_vm_deallocate(mytask, page_cow, size); exit(0); }
int main() { kern_return_t kr; clock_serv_t clk_system; mach_timespec_t alarm_time; clock_reply_t alarm_port; struct timeval t1, t2; msg_format_recv_t message; mach_port_t mytask; // The C library optimized this call by returning the task port's value // that it caches in the mach_task_self_ variable mytask = mach_task_self(); kr = host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, (clock_serv_t *)&clk_system); OUT_ON_MACH_ERROR("host_get_clock_service", kr); // Let us set the alarm to ring after 2.5 seconds alarm_time.tv_sec = 2; alarm_time.tv_nsec = 50000000; // Allocate a port (specifically, get receive right for the new port) // We will use this port to receive the alarm message from the clock kr = mach_port_allocate( mytask, // the task acquiring the port right MACH_PORT_RIGHT_RECEIVE, // type of right &alarm_port); // task's name for the port right OUT_ON_MACH_ERROR("mach_port_allocate", kr); gettimeofday(&t1, NULL); // Set the alarm kr = clock_alarm(clk_system, // the clock to use TIME_RELATIVE, // how to interpret alarm time alarm_time, // the alarm time alarm_port); // this port will receive the alarm message OUT_ON_MACH_ERROR("clock_alarm", kr); printf("Current time %ld s + %d us\n" "Setting alarm to ring after %d s + %d ns\n", t1.tv_sec, t1.tv_usec, alarm_time.tv_sec, alarm_time.tv_nsec); // Wait to receive the alarm message (we will block here) kr = mach_msg(&(message.header), // the message buffer MACH_RCV_MSG, // message option bits 0, // send size (we are receiving, so 0) message.header.msgh_size,// receive limit alarm_port, // receive right MACH_MSG_TIMEOUT_NONE, // no timeout MACH_PORT_NULL); // no timeout notification port // We should have received an alarm message at this point gettimeofday(&t2, NULL); OUT_ON_MACH_ERROR("mach_msg", kr); if (t2.tv_usec < t1.tv_usec) { t1.tv_sec += 1; t1.tv_usec -= 1000000; } printf("\nCurrent time %ld s + %d us\n", t2.tv_sec, t2.tv_usec); printf("Alarm rang after %ld s + %d us\n", (t2.tv_sec - t1.tv_sec), (t2.tv_usec - t1.tv_usec)); out: mach_port_deallocate(mytask, clk_system); // Release user reference for the receive right we created mach_port_deallocate(mytask, alarm_port); exit(0); }