OpenCores
URL https://opencores.org/ocsvn/funbase_ip_library/funbase_ip_library/trunk

Subversion Repositories funbase_ip_library

[/] [funbase_ip_library/] [trunk/] [TUT/] [ip.swp.api/] [openmcapi/] [1.0/] [libmcapi/] [shm/] [sysv.c] - Blame information for rev 145

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 145 lanttu
/*
2
 * Copyright (c) 2011, Mentor Graphics Corporation
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions are met:
7
 *
8
 * 1. Redistributions of source code must retain the above copyright notice,
9
 *    this list of conditions and the following disclaimer.
10
 * 2. Redistributions in binary form must reproduce the above copyright notice,
11
 *    this list of conditions and the following disclaimer in the documentation
12
 *    and/or other materials provided with the distribution.
13
 * 3. Neither the name of the <ORGANIZATION> nor the names of its contributors
14
 *    may be used to endorse or promote products derived from this software
15
 *    without specific prior written permission.
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
 * POSSIBILITY OF SUCH DAMAGE.
28
 */
29
 
30
/* This file allows the shared memory transport to mmap a file rather than
31
 * requiring dedicated physical memory. This is useful for development and
32
 * debugging, but obviously can only work for MCAPI processes within a single
33
 * OS (single filesystem). In addition to mmap(), it uses 0-length SysV message
34
 * queues as IPIs. */
35
 
36
#include <mcapi.h>
37
#include "shm.h"
38
#include "shm_os.h"
39
 
40
#include <stdio.h>
41
#include <fcntl.h>
42
#include <errno.h>
43
#include <unistd.h>
44
#include <sys/types.h>
45
#include <sys/stat.h>
46
#include <sys/mman.h>
47
#include <sys/ioctl.h>
48
 
49
#include <sys/ipc.h>
50
#include <sys/msg.h>
51
 
52
#define FILENAME "/tmp/mcapi-shm"
53
 
54
 
55
const unsigned int shm_bytes = 0x00100000; /* XXX */
56
 
57
static int msgqid;
58
static pthread_t shm_rx_thread;
59
 
60
struct shm_msgbuf {
61
    long mtype;
62
};
63
 
64
mcapi_status_t openmcapi_shm_notify(mcapi_uint32_t unit_id,
65
                                    mcapi_uint32_t node_id)
66
{
67
    struct shm_msgbuf msg = {node_id + 1};
68
    int rc;
69
    mcapi_status_t status = MCAPI_SUCCESS;
70
 
71
    rc = msgsnd(msgqid, &msg, 0, 0);
72
    if (rc == -1)
73
        status = MGC_MCAPI_ERR_NOT_CONNECTED;
74
 
75
    return status;
76
}
77
 
78
mcapi_uint32_t openmcapi_shm_schedunitid(void)
79
{
80
    return 0;
81
}
82
 
83
void *openmcapi_shm_map(void)
84
{
85
    void *shm;
86
    int key;
87
    int fd;
88
 
89
    /* Create the file. */
90
    fd = open(FILENAME, O_RDWR | O_CREAT | O_EXCL, 0660);
91
    if (fd != -1) {
92
        /* We created it first. Make it a sparse file of the correct size, then
93
         * initialize the associated semaphore. */
94
        lseek(fd, shm_bytes-1, SEEK_SET);
95
        write(fd, "\0", 1);
96
    } else {
97
        if (errno == EEXIST) {
98
            /* Another process created it, but we can use it. */
99
            fd = open(FILENAME, O_RDWR, 0660);
100
        }
101
    }
102
    if (fd == -1) {
103
        perror("open backing file");
104
        goto out1;
105
    }
106
 
107
    key = ftok(FILENAME, 'A');
108
    if (key == -1) {
109
        perror("ftok");
110
        goto out2;
111
    }
112
 
113
    msgqid = msgget(key, IPC_CREAT | 0660);
114
    if (msgqid == -1) {
115
        perror("msgget");
116
        goto out2;
117
    }
118
 
119
    /* mmap it. */
120
    shm = mmap(NULL, shm_bytes, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
121
    if (shm == MAP_FAILED) {
122
        perror("mmap shared memory");
123
        goto out2;
124
    }
125
 
126
    /* Don't need the original fd around any more. */
127
    close(fd);
128
 
129
    return shm;
130
 
131
out2:
132
    close(fd);
133
out1:
134
    return NULL;
135
}
136
 
137
static void *mcapi_receive_thread(void *data)
138
{
139
    int rc;
140
    static struct shm_msgbuf msg = {0};
141
 
142
    do {
143
        /* Block until data for this node is available. */
144
        rc = msgrcv(msgqid, &msg, 0, MCAPI_Node_ID + 1, 0);
145
        if (rc < 0) {
146
            /* This likely means the other side has already torn down the
147
             * message queue, so just exit. */
148
            break;
149
        }
150
 
151
        /* Obtain lock so we can safely manipulate the RX_Queue. */
152
        MCAPI_Lock_RX_Queue();
153
 
154
        /* Process the incoming data. */
155
        shm_poll();
156
 
157
        MCAPI_Unlock_RX_Queue(0);
158
 
159
    } while (1);
160
 
161
    return NULL;
162
}
163
 
164
/* Now that SM_Mgmt_Blk has been initialized, we can start the RX thread. */
165
mcapi_status_t openmcapi_shm_os_init(void)
166
{
167
    mcapi_status_t mcapi_status = MCAPI_SUCCESS;
168
    int rc;
169
 
170
    rc = pthread_create(&shm_rx_thread, NULL, mcapi_receive_thread, NULL);
171
    if (rc) {
172
        perror("couldn't create pthread");
173
        mcapi_status = MCAPI_ERR_GENERAL;
174
    }
175
 
176
    return mcapi_status;
177
}
178
 
179
/* Finalize the SM driver OS specific layer. */
180
mcapi_status_t openmcapi_shm_os_finalize(void)
181
{
182
    mcapi_status_t mcapi_status = MCAPI_SUCCESS;
183
    int rc;
184
 
185
    rc = pthread_cancel(shm_rx_thread);
186
    if (rc) {
187
        perror("couldn't cancel thread");
188
        mcapi_status = MCAPI_ERR_GENERAL;
189
    }
190
 
191
    return mcapi_status;
192
}
193
 
194
void openmcapi_shm_unmap(void *shm)
195
{
196
    /* File and message queue will be removed multiple times, once by each
197
     * process, but that's OK. */
198
    unlink(FILENAME);
199
    msgctl(msgqid, IPC_RMID, NULL);
200
 
201
    munmap(shm, shm_bytes);
202
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.