/* * Class: sharedmemory_SharedMemory * Method: open_sem * Signature: (Ljava/lang/String;)Ljava/nio/ByteBuffer; */ JNIEXPORT jobject JNICALL Java_sharedmemory_SharedMemory_open_1sem (JNIEnv *env, jobject obj, jstring descriptor) { jobject ret = NULL; const char* desc = (*env)->GetStringUTFChars( env, descriptor , NULL ) ; sem_t* sem = open_sem(desc); ret = (*env)->NewDirectByteBuffer(env, (void*) sem, sizeof(sem_t*)); (*env)->ReleaseStringUTFChars(env, descriptor ,desc); return ret; }
int main(int argc, char ** argv){ key_t key; int *shm_seg, shm_id, sem_id, pid, fd_fifo; int i, tmp, count_r; int r_arr[2]; unsigned int nn, n, size; struct sigaction sa; memset(&sa, 0, sizeof(sa)); sa.sa_handler = sigchldhandler; if (sigaction(SIGCHLD, &sa, 0) < 0){ perror("sigaction"); exit(0); } printf("n: "); scanf("%u", &n); if (n < 2){ printf("n must be bigger than 1\n"); exit(0); } nn = 2; while (nn < n){ nn <<= 1; } /*-initialize*/ if (mknod(FIFO, S_IFIFO | 0660, 0) < 0){ perror("mknod: "); exit(2); } if ((key = ftok(argv[0], 'q')) < 0) { perror("ftok"); exit(2); }/*========================================================================*/ size = nn*sizeof(int); if ((shm_id = open_seg(key,size)) < 0){ printf("open_seg error\n"); exit(2); } if (*(shm_seg = shmat(shm_id, 0, 0)) < 0) { printf("error attaching %d\n",shm_id); exit(2); } if ((sem_id = open_sem(key,4)) < 0){ printf("open_sem error\n"); exit(2); } srand(key); for(i = 0; i < n; i++){ shm_seg[i] = rand() % 100; printf("%d ", shm_seg[i]); } for(; i < nn; i++){ shm_seg[i] = 100; printf("%d ", 100); } printf("\n"); /*=initialize*/ op_sem(sem_id, &r_unlock[0]); op_sem(sem_id, &w_unlock[0]); for(i = 0; i < nn/2; i++){ if ((pid = fork()) < 0){ printf("fork %d", i); exit(0); } if (pid == 0){ if ((fd_fifo = open(FIFO, O_RDONLY | O_NONBLOCK)) < 0){ if (errno == EINTR){ _exit(0); } perror("open2: "); _exit(2); } while (get_sem_val(sem_id, 3) > 0){ r_arr[0] = 0; r_arr[1] = 0; /* trouble: В конце работы read читает из пустой фифо. Надо найти макс задержку read'а. Или семафоры...:( */ op_sem(sem_id, &r_lock[0]); if ((count_r = read(fd_fifo, &r_arr, sizeof(int)*2)) < 0){ if (errno == EAGAIN){ continue; } perror("read: "); _exit(2); }; if (count_r < 2){ continue; } op_sem(sem_id, &iter_unlock[0]); op_sem(sem_id, &r_unlock[0]); if (shm_seg[r_arr[0]] > shm_seg[r_arr[1]]){ tmp = shm_seg[r_arr[0]]; op_sem(sem_id, &w_lock[0]); shm_seg[r_arr[0]] = shm_seg[r_arr[1]]; shm_seg[r_arr[1]] = tmp; op_sem(sem_id, &w_unlock[0]); } } printf("die.\n"); if (close(fd_fifo) < 0){ perror("close2"); } _exit(0); } } while (1){ if ((fd_fifo = open(FIFO, O_WRONLY | O_NONBLOCK)) < 0){ if (errno == EINTR || errno == ENXIO){ continue; } perror("open3: "); exit(0); }else{ break; } } op_sem(sem_id, &work_start[0]); make_mn(nn, nn, 1, fd_fifo, sem_id); op_sem(sem_id, &work_stop[0]); if (close(fd_fifo) < 0){ perror("close2"); }; for(i = 0; i < n; i++){ printf("%d ", shm_seg[i]); } printf("\n"); while(die < nn/2); detach_seg((char *)shm_seg); close_seg(shm_id); close_sem(sem_id); return 0; }
// argv[1] = port name int main(int argc, char** argv) { Semaphore sem_gen_v; Semaphore mutex_boat; Semaphore mutex_sync; Shm shm_boat; Boat boat; mqd_t mqd_trucks; mqd_t mqd_cars_vans; char buffer[MQ_MSGSIZE]; char* port_name = argv[1]; char* msg = malloc(sizeof(msg)); int i = 0; int nb_trucks = 0, nb_cars = 0, nb_vans = 0; int nb_boats = atoi(getProp(PROP_FILE, "nb_boats")); srand(getpid()); // SEM_GEN_V sem_gen_v.oflag = (O_CREAT | O_RDWR); sem_gen_v.mode = 0644; sem_gen_v.value = 0; sprintf(sem_gen_v.semname,"%s%s", SEM_GEN_V, port_name); sem_unlink(sem_gen_v.semname); open_sem(&sem_gen_v); // Preparing mutex for shm_boat access mutex_boat.oflag = O_RDWR; mutex_boat.mode = 0644; mutex_boat.value = 1; strcpy(mutex_boat.semname, MUTEX_BOAT); open_sem(&mutex_boat); // Preparing shm_boat access shm_boat.sizeofShm = sizeof(Boat) * 6; shm_boat.mode = O_RDWR; strcpy(shm_boat.shmName, SHM_BOAT); open_shm(&shm_boat); mapping_shm(&shm_boat, sizeof(Boat) * 6); while(1) { // Waiting signal_sem on sem_gen_v from Docks processes. wait_sem(sem_gen_v); // Waiting for access on shm_boat wait_sem(mutex_boat); boat = get_actual_boat(DOCK, port_name, nb_boats, shm_boat); signal_sem(mutex_boat); sprintf(msg, "Débloqué"); print_boat(port_name, boat.index, msg); // MUTEX_SYNC mutex_sync.oflag = 0; sprintf(mutex_sync.semname,"%s%d", MUTEX_SYNC, boat.index); open_sem(&mutex_sync); // Ouverture MQs mqd_trucks = mq_open(boat.mq1.name, O_WRONLY); mqd_cars_vans = mq_open(boat.mq2.name, O_WRONLY); nb_cars = rand() % MAX_N_CARS + 1; nb_vans = rand() % MAX_N_VANS + 1; nb_trucks = rand()% MAX_N_TRUCKS + 1; memset(buffer, 0, MQ_MSGSIZE); sprintf(msg, "Debut embarquement"); print_boat(port_name, boat.index, msg); sprintf(msg, "Embarquement de %d voitures", nb_cars); print_boat(port_name, boat.index, msg); for(i = 0; i < nb_cars; i++) { sprintf(buffer, "Car %d", i + 1); if(mq_send(mqd_cars_vans, buffer, strlen(buffer), CAR_PRIORITY) == -1) { mq_close(mqd_cars_vans); mq_unlink(boat.mq1.name); perror("Error occured when mq_send (cars & vans)\n"); exit(EXIT_FAILURE); } // Sleep 1/4s -- TODO Paramétrable. nanosleep((struct timespec[]){{0, 250000000}}, NULL); } sprintf(msg, "Embarquement de %d vans", nb_vans); print_boat(port_name, boat.index, msg); for(i = 0; i < nb_vans; i++) { sprintf(buffer, "Van %d", i); if(mq_send(mqd_cars_vans, buffer, strlen(buffer), VAN_PRIORITY) == -1) { mq_close(mqd_cars_vans); mq_unlink(boat.mq1.name); perror("Error occured when mq_send (cars & vans)\n"); exit(EXIT_FAILURE); } // Sleep 1/4s nanosleep((struct timespec[]){{0, 250000000}}, NULL); }