blob: d12872eaf53edde39be9649d6182a96acdecb088 [file] [log] [blame]
Brian Silverman6ae77dd2013-03-29 22:28:08 -07001#include "vision/PacketNotifier.h"
Brian Silverman5b3e51e2013-03-29 22:53:44 -07002
Brian Silverman6ae77dd2013-03-29 22:28:08 -07003#include <stdio.h>
4#include <unistd.h>
5#include <stdlib.h>
6#include <sys/mman.h>
7#include <errno.h>
8#include <string.h>
9
10namespace frc971 {
11namespace vision {
12
13void PacketNotifier::RegisterSender(){
14 close(fd[1]);
15}
16void PacketNotifier::RegisterReciever(){
17 close(fd[0]);
18}
19PacketNotifier *PacketNotifier::MMap(size_t data_size){
20 PacketNotifier *data;
21 data = (PacketNotifier *)mmap(NULL, ((data_size * 3 + 4095 + sizeof(PacketNotifier)) / 4096) * 4096,
22 PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
23 data->data_size = data_size;
24 socketpair(PF_LOCAL, SOCK_STREAM, 0, data->fd);
25 for(int i = 0;i < 3;i++){
26 data->buffs[i] = (uint8_t *)data + (sizeof(PacketNotifier) + i * data_size);
27 }
28 void *place = &(data->mutex);
29 *((int *)place) = 0; // The Mutex class needs a placement new operator. (you know, keep the masses happy);
30 data->in_flight = false;
31 data->to_send = -1;
32 data->sending = -1;
33 return data;
34}
35void *PacketNotifier::GetBuffer(){
36 mutex.Lock();
37 for(int i = 0; i < 3 ; i++){ //search for open spot.
38 if(i != sending && i != to_send){ //open
39 filling = i;
40 mutex.Unlock();
Austin Schuh86bec782013-04-04 05:50:52 +000041 //printf("leasing out to fill buff # %d\n",i);
Brian Silverman6ae77dd2013-03-29 22:28:08 -070042 return buffs[i];
43 }
44 }
45 mutex.Unlock();
Austin Schuh86bec782013-04-04 05:50:52 +000046 //printf("Error in the fabric of the universe\n");
Brian Silverman6ae77dd2013-03-29 22:28:08 -070047 exit(-42);
48}
49void PacketNotifier::Notify(){
50 mutex.Lock();
51 to_send = filling;
52 filling = -1;
53 mutex.Unlock();
54 // wall error
55 if(write(fd[0],"\n",1)) {}
56}
57
58void PacketNotifier::DataSent(const void * /*data*/, size_t /*datalen*/){
Austin Schuh86bec782013-04-04 05:50:52 +000059 //printf("packet_sent: %d; fill: %d; to_send: %d \n",sending,filling,to_send);
Brian Silverman6ae77dd2013-03-29 22:28:08 -070060 mutex.Lock();
61 sending = -1;
62 mutex.Unlock();
63 in_flight = false;
64}
65bool PacketNotifier::GetData(char **place_to_put,size_t *length){
66 if(in_flight) return false;
67 mutex.Lock();
68 *length = data_size;
69 *place_to_put = (char *)buffs[to_send];
70 sending = to_send;
71 to_send = -1;
72 mutex.Unlock();
73 in_flight = true;
74 return true;
75}
76
77} // namespace vision
78} // namespace frc971
79