/* this function is run by the second thread */ void consumer() { int i, time; while (1){ if (i >= 32 ) { i = 0; } time = 0; if (!check_mutex()){ //printf("Mutex Aquired by Consumer\n"); if (!check_empty(i)) { printf("Consumer Printing from Index %d: %d\n", i, product[i].print); printf("Consumer Waiting at Index %d: %d\n", i, product[i].wait_time); time = product[i].wait_time; product[i].print = -1; product[i].wait_time = -1; } pthread_mutex_unlock(&lock); //printf("Mutex released by Consumer\n"); sleep(time); } //else { // printf("Consumer did not obtain Mutex.\n"); //} i++; } }
int main() { int i; int producer_wait; for (i = 0; i < 32; ++i){ product[i].print=-1; product[i].wait_time=-1; } //Prints all the data in the array. //for (i = 0; i < 32; ++i){ // printf("Print: %d\n", product[i].print); // printf("Wait: %d\n", product[i].wait_time); //} /* this variable is our reference to the second thread */ pthread_t consumer_thread; /* create a second thread which executes inc_x(&x) */ if(pthread_create(&consumer_thread, NULL, (void *)consumer, (void *)NULL)) { fprintf(stderr, "Error creating thread\n"); return 1; } while (1){ if (i >= 32 ) { i = 0; } producer_wait = 0; if (!check_mutex()){ //printf("Mutex Aquired by Producer\n"); if (check_empty(i)) { product[i].print = rdrand_func(3); product[i].wait_time = rdrand_func(1); printf("Producer Inserting Value %d and Wait Time %d at Index: %d\n", product[i].print, product[i].wait_time, i); producer_wait = rdrand_func(2); printf("Producer is now sleeping for %d seconds\n", producer_wait); } pthread_mutex_unlock(&lock); //printf("Mutex released by Producer\n"); sleep(producer_wait); } //else { // printf("Producer did not obtain Mutex.\n"); //} i++; } /* wait for the second thread to finish */ if(pthread_join(consumer_thread, NULL)) { fprintf(stderr, "Error joining thread\n"); return 2; } return 0; }
plc_tag ab_tag_create(attr attribs) { ab_tag_p tag = AB_TAG_NULL; const char *path; int rc; int debug = attr_get_int(attribs,"debug",0); pdebug(debug,"Starting."); /* * allocate memory for the new tag. Do this first so that * we have a vehicle for returning status. */ tag = (ab_tag_p)mem_alloc(sizeof(struct ab_tag_t)); if(!tag) { pdebug(debug,"Unable to allocate memory for AB EIP tag!"); return PLC_TAG_NULL; } /* store the debug status */ tag->debug = debug; /* * check the CPU type. * * This determines the protocol type. */ if(check_cpu(tag, attribs) != PLCTAG_STATUS_OK) { tag->status = PLCTAG_ERR_BAD_DEVICE; return (plc_tag)tag; } /* AB PLCs are little endian. */ tag->endian = PLCTAG_DATA_LITTLE_ENDIAN; /* allocate memory for the data */ tag->elem_count = attr_get_int(attribs,"elem_count",1); tag->elem_size = attr_get_int(attribs,"elem_size",0); tag->size = (tag->elem_count) * (tag->elem_size); if(tag->size == 0) { /* failure! Need data_size! */ tag->status = PLCTAG_ERR_BAD_PARAM; return (plc_tag)tag; } tag->data = (uint8_t*)mem_alloc(tag->size); if(tag->data == NULL) { tag->status = PLCTAG_ERR_NO_MEM; return (plc_tag)tag; } /* get the connection path, punt if there is not one and we have a Logix-class PLC. */ path = attr_get_str(attribs,"path",NULL); if(path == NULL && tag->protocol_type == AB_PROTOCOL_LGX) { tag->status = PLCTAG_ERR_BAD_PARAM; return (plc_tag)tag; } /* make sure the global mutex is set up */ rc = check_mutex(tag->debug); if(rc != PLCTAG_STATUS_OK) { tag->status = rc; return (plc_tag)tag; } tag->first_read = 1; /* * now we start the part that might conflict with other threads. * * The rest of this is inside a locked block. */ pdebug(debug,"Locking mutex"); critical_block(io_thread_mutex) { /* * set up tag vtable. This is protocol specific */ tag->vtable = set_tag_vtable(tag); if(!tag->vtable) { pdebug(debug,"Unable to set tag vtable!"); tag->status = PLCTAG_ERR_BAD_PARAM; break; } /* * Check the request IO handler thread. */ if(!io_handler_thread) { rc = thread_create((thread_p*)&io_handler_thread,request_handler_func, 32*1024, NULL); if(rc != PLCTAG_STATUS_OK) { pdebug(debug,"Unable to create request handler thread!"); tag->status = rc; break; } } /* * Find or create a session. */ if(find_or_create_session(tag, attribs) != PLCTAG_STATUS_OK) { pdebug(debug,"Unable to create session!"); tag->status = PLCTAG_ERR_BAD_GATEWAY; break; } /* * parse the link path into the tag. Note that it must * pad the byte string to a multiple of 16-bit words. The function * also adds the protocol/PLC specific routing information to the * links specified. This fills in fields in the connection about * any DH+ special data. * * Skip this if we don't have a path. */ if(path && cip_encode_path(tag,path) != PLCTAG_STATUS_OK) { pdebug(debug,"Unable to convert links strings to binary path!"); tag->status = PLCTAG_ERR_BAD_PARAM; break; } /* * check the tag name, this is protocol specific. */ if(check_tag_name(tag, attr_get_str(attribs,"name","NONE")) != PLCTAG_STATUS_OK) { pdebug(debug,"Bad tag name!"); tag->status = PLCTAG_ERR_BAD_PARAM; break; } /* * add the tag to the session's list. */ if(session_add_tag_unsafe(tag, tag->session) != PLCTAG_STATUS_OK) { pdebug(debug,"unable to add new tag to connection!"); tag->status = PLCTAG_ERR_CREATE; break; } } pdebug(debug,"Done."); return (plc_tag)tag; }