VirtualBox

source: vbox/trunk/src/VBox/Additions/common/crOpenGL/pack/packspu_net.c@ 32499

Last change on this file since 32499 was 32499, checked in by vboxsync, 15 years ago

crOpenGL: fix race crashes with new tracking code

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 6.2 KB
Line 
1/* Copyright (c) 2001, Stanford University
2 * All rights reserved
3 *
4 * See the file LICENSE.txt for information on redistributing this software.
5 */
6
7#include "cr_pack.h"
8#include "cr_mem.h"
9#include "cr_net.h"
10#include "cr_pixeldata.h"
11#include "cr_protocol.h"
12#include "cr_error.h"
13#include "packspu.h"
14#include "packspu_proto.h"
15
16static void
17packspuWriteback( const CRMessageWriteback *wb )
18{
19 int *writeback;
20 crMemcpy( &writeback, &(wb->writeback_ptr), sizeof( writeback ) );
21 *writeback = 0;
22}
23
24/**
25 * XXX Note that this routine is identical to crNetRecvReadback except
26 * we set *writeback=0 instead of decrementing it. Hmmm.
27 */
28static void
29packspuReadback( const CRMessageReadback *rb, unsigned int len )
30{
31 /* minus the header, the destination pointer,
32 * *and* the implicit writeback pointer at the head. */
33
34 int payload_len = len - sizeof( *rb );
35 int *writeback;
36 void *dest_ptr;
37 crMemcpy( &writeback, &(rb->writeback_ptr), sizeof( writeback ) );
38 crMemcpy( &dest_ptr, &(rb->readback_ptr), sizeof( dest_ptr ) );
39
40 *writeback = 0;
41 crMemcpy( dest_ptr, ((char *)rb) + sizeof(*rb), payload_len );
42}
43
44static void
45packspuReadPixels( const CRMessageReadPixels *rp, unsigned int len )
46{
47 crNetRecvReadPixels( rp, len );
48 --pack_spu.ReadPixels;
49}
50
51static int
52packspuReceiveData( CRConnection *conn, CRMessage *msg, unsigned int len )
53{
54 if (msg->header.type == CR_MESSAGE_REDIR_PTR)
55 msg = (CRMessage*) msg->redirptr.pMessage;
56
57 switch( msg->header.type )
58 {
59 case CR_MESSAGE_READ_PIXELS:
60 packspuReadPixels( &(msg->readPixels), len );
61 break;
62 case CR_MESSAGE_WRITEBACK:
63 packspuWriteback( &(msg->writeback) );
64 break;
65 case CR_MESSAGE_READBACK:
66 packspuReadback( &(msg->readback), len );
67 break;
68 default:
69 /*crWarning( "Why is the pack SPU getting a message of type 0x%x?", msg->type ); */
70 return 0; /* NOT HANDLED */
71 }
72 return 1; /* HANDLED */
73}
74
75static CRMessageOpcodes *
76__prependHeader( CRPackBuffer *buf, unsigned int *len, unsigned int senderID )
77{
78 int num_opcodes;
79 CRMessageOpcodes *hdr;
80
81 CRASSERT( buf );
82 CRASSERT( buf->opcode_current < buf->opcode_start );
83 CRASSERT( buf->opcode_current >= buf->opcode_end );
84 CRASSERT( buf->data_current > buf->data_start );
85 CRASSERT( buf->data_current <= buf->data_end );
86
87 num_opcodes = buf->opcode_start - buf->opcode_current;
88 hdr = (CRMessageOpcodes *)
89 ( buf->data_start - ( ( num_opcodes + 3 ) & ~0x3 ) - sizeof(*hdr) );
90
91 CRASSERT( (void *) hdr >= buf->pack );
92
93 if (pack_spu.swap)
94 {
95 hdr->header.type = (CRMessageType) SWAP32(CR_MESSAGE_OPCODES);
96 hdr->numOpcodes = SWAP32(num_opcodes);
97 }
98 else
99 {
100 hdr->header.type = CR_MESSAGE_OPCODES;
101 hdr->numOpcodes = num_opcodes;
102 }
103
104 *len = buf->data_current - (unsigned char *) hdr;
105
106 return hdr;
107}
108
109
110/*
111 * This is called from either the Pack SPU and the packer library whenever
112 * we need to send a data buffer to the server.
113 */
114void packspuFlush(void *arg )
115{
116 ThreadInfo *thread = (ThreadInfo *) arg;
117 ContextInfo *ctx;
118 unsigned int len;
119 CRMessageOpcodes *hdr;
120 CRPackBuffer *buf;
121
122 crLockMutex(&_PackMutex);
123
124 /* we should _always_ pass a valid <arg> value */
125 CRASSERT(thread);
126 ctx = thread->currentContext;
127 buf = &(thread->buffer);
128 CRASSERT(buf);
129
130 /* We're done packing into the current buffer, unbind it */
131 crPackReleaseBuffer( thread->packer );
132
133 /*
134 printf("%s thread=%p thread->id = %d thread->pc=%p t2->id=%d t2->pc=%p packbuf=%p packbuf=%p\n",
135 __FUNCTION__, (void*) thread, (int) thread->id, thread->packer,
136 (int) t2->id, t2->packer,
137 buf->pack, thread->packer->buffer.pack);
138 */
139
140 if ( buf->opcode_current == buf->opcode_start ) {
141 /*
142 printf("%s early return\n", __FUNCTION__);
143 */
144 /* XXX these calls seem to help, but might be appropriate */
145 crPackSetBuffer( thread->packer, buf );
146 crPackResetPointers(thread->packer);
147 crUnlockMutex(&_PackMutex);
148 return;
149 }
150
151 hdr = __prependHeader( buf, &len, 0 );
152
153 CRASSERT( thread->netServer.conn );
154
155 if ( buf->holds_BeginEnd )
156 {
157 /*crDebug("crNetBarf %d, (%d)", len, buf->size);*/
158 crNetBarf( thread->netServer.conn, &(buf->pack), hdr, len );
159 }
160 else
161 {
162 /*crDebug("crNetSend %d, (%d)", len, buf->size);*/
163 crNetSend( thread->netServer.conn, &(buf->pack), hdr, len );
164 }
165
166 buf->pack = crNetAlloc( thread->netServer.conn );
167
168 /* The network may have found a new mtu */
169 buf->mtu = thread->netServer.conn->mtu;
170
171 crPackSetBuffer( thread->packer, buf );
172
173 crPackResetPointers(thread->packer);
174
175 crUnlockMutex(&_PackMutex);
176}
177
178
179/**
180 * XXX NOTE: there's a lot of duplicate code here common to the
181 * pack, tilesort and replicate SPUs. Try to simplify someday!
182 */
183void packspuHuge( CROpcode opcode, void *buf )
184{
185 GET_THREAD(thread);
186 unsigned int len;
187 unsigned char *src;
188 CRMessageOpcodes *msg;
189
190 CRASSERT(thread);
191
192 /* packet length is indicated by the variable length field, and
193 includes an additional word for the opcode (with alignment) and
194 a header */
195 len = ((unsigned int *) buf)[-1];
196 if (pack_spu.swap)
197 {
198 /* It's already been swapped, swap it back. */
199 len = SWAP32(len);
200 }
201 len += 4 + sizeof(CRMessageOpcodes);
202
203 /* write the opcode in just before the length */
204 ((unsigned char *) buf)[-5] = (unsigned char) opcode;
205
206 /* fix up the pointer to the packet to include the length & opcode
207 & header */
208 src = (unsigned char *) buf - 8 - sizeof(CRMessageOpcodes);
209
210 msg = (CRMessageOpcodes *) src;
211
212 if (pack_spu.swap)
213 {
214 msg->header.type = (CRMessageType) SWAP32(CR_MESSAGE_OPCODES);
215 msg->numOpcodes = SWAP32(1);
216 }
217 else
218 {
219 msg->header.type = CR_MESSAGE_OPCODES;
220 msg->numOpcodes = 1;
221 }
222
223 CRASSERT( thread->netServer.conn );
224 crNetSend( thread->netServer.conn, NULL, src, len );
225}
226
227void packspuConnectToServer( CRNetServer *server )
228{
229 crNetInit( packspuReceiveData, NULL );
230 crNetServerConnect( server );
231}
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette