splice() from pipe to TCP buffered? - tcp

xpost from linuxquestions.org, sorry...
I wrote a small test program to see if a simple proxy would benefit from using splice() but it always takes 200ms for the data that I spliced from a pipe to a TCP socket to be read from the other end of the socket.
Here is the Perl program to test it:
package test_pipes_2;
use strict;
use warnings;
use IO::Handle();
use POSIX qw(:errno_h);
use Time::HiRes qw(time);
use English qw(-no_match_vars);
use IO::Socket::INET;
use Socket qw(IPPROTO_TCP TCP_NODELAY);
__PACKAGE__->run if not caller;
sub run {
my( $class ) = #ARG;
pipe my $parent_reader, my $child_writer;
my $parent_reader_fd = fileno $parent_reader;
my $child_writer_fd = fileno $child_writer;
pipe my $child_reader, my $parent_writer;
my $child_reader_fd = fileno $child_reader;
my $parent_writer_fd = fileno $parent_writer;
my $server = IO::Socket::INET->new(
LocalAddr => '127.0.0.1:9000',
Type => SOCK_STREAM,
Listen => 5,
ReuseAddr => 1,
Blocking => 1,
) || die $OS_ERROR;
my $client_browser = IO::Socket::INET->new(
PeerAddr => '127.0.0.1:9000',
Type => SOCK_STREAM,
Blocking => 1,
) || die $OS_ERROR;
# setsockopt $client_browser, IPPROTO_TCP, TCP_NODELAY, 1;
my $client_browser_fd = fileno $client_browser;
my $server_browser = $server->accept() || die $OS_ERROR;
# setsockopt $server_browser, IPPROTO_TCP, TCP_NODELAY, 1;
my $server_browser_fd = fileno $server_browser;
for( 1 .. 3 ) { # 100_000
syswrite $client_browser, "HTTP/1.1 GET /foo/\r\nLocation: foo.com\r\n\r\n";
$server_browser->recv( my $request1, 4096, POSIX::MSG_PEEK );
syscall 313, $server_browser_fd, undef, $child_writer_fd, undef, 4096, 1;
sysread $parent_reader, my $request2, 4096;
my $response = "200 OK\n<head><title>html</title></head><body>body from $PID</body>";
syswrite $parent_writer, $response;
syscall 313, $child_reader_fd, undef, $server_browser_fd, undef, 4096, 1;
# syswrite $server_browser, "\n"; # eliminates delay, adds syscall...
sysread $client_browser, my $response1, 4096;
# chomp $response1;
if( $response1 ne $response ) {
warn 'Got wrong response: ', $response1 // 'undef';
no warnings 'once';
$DB::single = 1;
}
}
}
1;
And here is a sample of the strace output:
socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 8 <0.000010>
setsockopt(8, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 <0.000006>
bind(8, {sa_family=AF_INET, sin_port=htons(9000), sin_addr=inet_addr("127.0.0.1")}, 16) = 0 <0.000008>
listen(8, 5) = 0 <0.000008>
socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 9 <0.000006>
connect(9, {sa_family=AF_INET, sin_port=htons(9000), sin_addr=inet_addr("127.0.0.1")}, 16) = 0 <0.000037>
accept(8, {sa_family=AF_INET, sin_port=htons(49361), sin_addr=inet_addr("127.0.0.1")}, [16]) = 10 <0.000007>
write(9, "HTTP/1.1 GET /foo/\r\nLocation: foo.com\r\n\r\n"..., 41) = 41 <0.000014>
recvfrom(10, "HTTP/1.1 GET /foo/\r\nLocation: foo.com\r\n\r\n"..., 4096, MSG_PEEK, {sa_family=0x8b60 /* AF_??? */, sa_data="(\10\2\0\300\321\177\0\0\1\0\0\0\0"...}, [0]) = 41 <0.000007>
splice(0xa, 0, 0x5, 0, 0x1000, 0x1) = 41 <0.000007>
read(4, "HTTP/1.1 GET /foo/\r\nLocation: foo.com\r\n\r\n"..., 4096) = 41 <0.000005>
write(7, "200 OK\n<head><title>html</title></head><body>body from 14019</body>"..., 67) = 67 <0.000005>
splice(0x6, 0, 0xa, 0, 0x1000, 0x1) = 67 <0.000007>
read(9, "200 OK\n<head><title>html</title></head><body>body from 14019</body>"..., 4096) = 67 <0.200331>
write(9, "HTTP/1.1 GET /foo/\r\nLocation: foo.com\r\n\r\n"..., 41) = 41 <0.000016>
recvfrom(10, "HTTP/1.1 GET /foo/\r\nLocation: foo.com\r\n\r\n"..., 4096, MSG_PEEK, {sa_family=0x8b60 /* AF_??? */, sa_data="(\10\2\0\300\321\177\0\0\1\0\0\0\0"...}, [0]) = 41 <0.000008>
splice(0xa, 0, 0x5, 0, 0x1000, 0x1) = 41 <0.000006>
read(4, "HTTP/1.1 GET /foo/\r\nLocation: foo.com\r\n\r\n"..., 4096) = 41 <0.000005>
write(7, "200 OK\n<head><title>html</title></head><body>body from 14019</body>"..., 67) = 67 <0.000005>
splice(0x6, 0, 0xa, 0, 0x1000, 0x1) = 67 <0.000006>
read(9, "200 OK\n<head><title>html</title></head><body>body from 14019</body>"..., 4096) = 67 <0.200622>
write(9, "HTTP/1.1 GET /foo/\r\nLocation: foo.com\r\n\r\n"..., 41) = 41 <0.000018>
recvfrom(10, "HTTP/1.1 GET /foo/\r\nLocation: foo.com\r\n\r\n"..., 4096, MSG_PEEK, {sa_family=0x8b60 /* AF_??? */, sa_data="(\10\2\0\300\321\177\0\0\1\0\0\0\0"...}, [0]) = 41 <0.000007>
splice(0xa, 0, 0x5, 0, 0x1000, 0x1) = 41 <0.000006>
read(4, "HTTP/1.1 GET /foo/\r\nLocation: foo.com\r\n\r\n"..., 4096) = 41 <0.000005>
write(7, "200 OK\n<head><title>html</title></head><body>body from 14019</body>"..., 67) = 67 <0.000005>
splice(0x6, 0, 0xa, 0, 0x1000, 0x1) = 67 <0.000005>
read(9, "200 OK\n<head><title>html</title></head><body>body from 14019</body>"..., 4096) = 67 <0.200649
Note the ~200ms read(9,...) calls. If I uncomment the line to send a "\n" then there is no delay. What am I doing wrong? Thanks!

Related

process vm readv fails after certain number of iovec in MPI

I'm using process_vm_readv to get data from one process to the other in MPI.
I found the program will start getting trash after certain number of iovec (in this case 1024) given to process_vm_readv.
I wasn't sure what is going on, did the kernel running out of memory? Or something wrong with in my code.
Or did process_vm_readv has a upper limit for iovec?
I self-generated a vector pattern (8 bytes out of every 16 bytes) for iovec.
And the program will run until 1GB is filled with this pattern on both threads.
sbuf and rbuf have been allocated each for 1GB of memory.
And the program sits on a 24GB+ machine.
void do_test( int slen, int rlen, int scount, int rcount, void *sbuf, void *rbuf ){
int rank, err;
double timers[REP];
MPI_Win win;
pid_t pid;
MPI_Comm_rank( MPI_COMM_WORLD, &rank );
if( rank == 0 ){
MPI_Win_create( NULL, 0, 1, MPI_INFO_NULL, MPI_COMM_WORLD, &win );
int send_iovcnt;
struct iovec *send_iov;
struct iovec *iov = malloc( sizeof(struct iovec) * scount );
for( int p = 0; p < scount; p++ ){
iov[p].iov_base = (char*)rbuf + p * 16;
iov[p].iov_len = 8;
}
MPI_Recv( &pid, sizeof(pid_t), MPI_BYTE, 1, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE );
MPI_Recv( &send_iovcnt, 1, MPI_INT, 1, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE );
send_iov = malloc( sizeof(struct iovec) * send_iovcnt );
MPI_Recv( send_iov, sizeof(struct iovec) * send_iovcnt, MPI_BYTE, 1, 2, MPI_COMM_WORLD, MPI_STATUS_IGNORE );
for( int i = 0; i < REP; i++ ){
cache_flush();
timers[i] = MPI_Wtime();
MPI_Win_fence( 0, win );
process_vm_readv( pid, iov, send_iovcnt, send_iov, send_iovcnt, 0 );
MPI_Win_fence( 0, win );
cache_flush();
timers[i] = MPI_Wtime() - timers[i];
}
free(send_iov);
free(iov);
print_result( 8 * scount, REP, timers );
} else if( rank == 1 ){
MPI_Win_create( sbuf, slen, 1, MPI_INFO_NULL, MPI_COMM_WORLD, &win );
struct iovec *iov = malloc( sizeof(struct iovec) * rcount );
for( int p = 0; p < rcount; p++ ){
iov[p].iov_base = (char*)sbuf + p * 16;
iov[p].iov_base = 8;
}
pid = getpid();
MPI_Send( &pid, sizeof(pid_t), MPI_BYTE, 0, 0, MPI_COMM_WORLD );
MPI_Send( &rcount, 1, MPI_INT, 0, 1, MPI_COMM_WORLD );
MPI_Send( iov, rcount * sizeof(struct iovec), MPI_BYTE, 0, 2, MPI_COMM_WORLD );
for( int i = 0; i < REP; i++ ){
cache_flush();
MPI_Win_fence( 0, win );
MPI_Win_fence( 0, win );
}
free(iov);
}
Found in the man page of process_vm_readv(2) is the following text:
The values specified in the liovcnt and riovcnt arguments must be less than or equal to IOV_MAX (defined in <limits.h> or accessible via the call sysconf(_SC_IOV_MAX)).
On my Linux system, the value of IOV_MAX (ultimately defined in /usr/include/x86_64-linux-gnu/bits/uio_lim.h) is 1024.

How to edit global attributes in netcdf file with NCO

I am trying to edit one of the global attributes in my netcdf file:
START_DATE = "2016-05-12_00:00:00"
I want to change the date string to another date. How do you do this with the nco package?
I've seen that I can use
ncatted [-a ...] [-D dbg_lvl] [-h] [-l path] [-O] [-o out.nc] [-p path] [-R] [-r] in.nc [[out.nc]]
I've read the docs, but there are limited examples shown.
This is how I used it:
ncatted -O -h -a START_DATE,,m,c,"2016-06-12_00:00:00" wrfchemi_d01.nc wrfnew.nc
Upon checking the output with ncdump, the global attribute did not change as seen here:
// global attributes:
:TITLE = " OUTPUT FROM * PROGRAM:WRF-Chem V4.1.2 MODEL" ;
:START_DATE = "2016-05-12_00:00:00" ;
:WEST-EAST_GRID_DIMENSION = 70 ;
:SOUTH-NORTH_GRID_DIMENSION = 70 ;
:BOTTOM-TOP_GRID_DIMENSION = 51 ;
:DX = 25000.f ;
:DY = 25000.f ;
:AERCU_OPT = 0 ;
:AERCU_FCT = 1.f ;
:IDEAL_CASE = 0 ;
:DIFF_6TH_SLOPEOPT = 0 ;
:AUTO_LEVELS_OPT = 2 ;
:DIFF_6TH_THRESH = 0.1f ;
:DZBOT = 50.f ;
:DZSTRETCH_S = 1.3f ;
:DZSTRETCH_U = 1.1f ;
:GRIDTYPE = "C" ;
:DIFF_OPT = 1 ;
:KM_OPT = 4 ;
:DAMP_OPT = 3 ;
:DAMPCOEF = 0.2f ;
:KHDIF = 0.f ;
:KVDIF = 0.f ;
:MP_PHYSICS = -1 ;
:RA_LW_PHYSICS = 1 ;
:RA_SW_PHYSICS = 1 ;
:SF_SFCLAY_PHYSICS = 2 ;
:SF_SURFACE_PHYSICS = 2 ;
:BL_PBL_PHYSICS = 2 ;
:CU_PHYSICS = 5 ;
:SF_LAKE_PHYSICS = 0 ;
:SURFACE_INPUT_SOURCE = 1 ;
:SST_UPDATE = 0 ;
:GRID_FDDA = 0 ;
:GFDDA_INTERVAL_M = 0 ;
:GFDDA_END_H = 0 ;
:GRID_SFDDA = 0 ;
:SGFDDA_INTERVAL_M = 0 ;
:SGFDDA_END_H = 0 ;
:HYPSOMETRIC_OPT = 2 ;
:USE_THETA_M = 1 ;
:GWD_OPT = 0 ;
:SF_URBAN_PHYSICS = 0 ;
:SF_SURFACE_MOSAIC = 0 ;
:SF_OCEAN_PHYSICS = 0 ;
:WEST-EAST_PATCH_START_UNSTAG = 1 ;
:WEST-EAST_PATCH_END_UNSTAG = 69 ;
:WEST-EAST_PATCH_START_STAG = 1 ;
:WEST-EAST_PATCH_END_STAG = 70 ;
:SOUTH-NORTH_PATCH_START_UNSTAG = 1 ;
:SOUTH-NORTH_PATCH_END_UNSTAG = 69 ;
:SOUTH-NORTH_PATCH_START_STAG = 1 ;
:SOUTH-NORTH_PATCH_END_STAG = 70 ;
:BOTTOM-TOP_PATCH_START_UNSTAG = 1 ;
:BOTTOM-TOP_PATCH_END_UNSTAG = 50 ;
:BOTTOM-TOP_PATCH_START_STAG = 1 ;
:BOTTOM-TOP_PATCH_END_STAG = 51 ;
:GRID_ID = 1 ;
:PARENT_ID = 1 ;
:I_PARENT_START = 1 ;
:J_PARENT_START = 1 ;
:PARENT_GRID_RATIO = 1 ;
:DT = 150.f ;
:CEN_LAT = 14.60003f ;
:CEN_LON = 120.98f ;
:TRUELAT1 = 14.6f ;
:TRUELAT2 = 14.6f ;
:MOAD_CEN_LAT = 14.60003f ;
:STAND_LON = 120.98f ;
:POLE_LAT = 90.f ;
:POLE_LON = 0.f ;
:GMT = 0.f ;
:JULYR = 2016 ;
:JULDAY = 133 ;
:MAP_PROJ = 1 ;
:MAP_PROJ_CHAR = "Lambert Conformal" ;
:MMINLU = "USGS" ;
:NUM_LAND_CAT = 28 ;
:ISWATER = 16 ;
:ISLAKE = 28 ;
:ISICE = 24 ;
:ISURBAN = 1 ;
:ISOILWATER = 14 ;
:HYBRID_OPT = 2 ;
:ETAC = 0.2f ;
Can someone show me how its done for this simple change?
Thanks!
It is a global attribute and the syntax you invoked will only change the attribute for all variable attributes of that name, not global attributes. Read the docs on that point and try
ncatted -O -h -a START_DATE,global,m,c,"2016-06-12_00:00:00" wrfchemi_d01.nc wrfnew.nc

netlink_broadcast fail with return value -3

I can't broadcast netlink message to userspace by the following code. However, I can't find anything wrong. My userspace program can recieve broadcast message of other types, for example sock_fd=socket(PF_NETLINK, SOCK_RAW, NETLINK_KOBJECT_UEVENT);, but not my type SYSHOOK_NL_NUM.
I think that bugs hide in my kernel code. Can anyone figure out what's wrong? Thanks.
syshook_nl_sk = netlink_kernel_create(&init_net, SYSHOOK_NL_NUM, 1, NULL, NULL, THIS_MODULE);
skb = alloc_skb(NLMSG_SPACE(nl_send_len), GFP_ATOMIC);
if(!skb) {
error = -ENOMEM;
goto err;
}
nlh = (struct nlmsghdr *)skb->data;
nlh->nlmsg_len = NLMSG_SPACE(nl_send_len);
nlh->nlmsg_pid = 0;
nlh->nlmsg_flags = 0;
nlh = nlmsg_put(skb, 0, 0, 0, NLMSG_SPACE(nl_send_len) - sizeof (struct nlmsghdr), 0);
NETLINK_CB(skb).pid = 0;
NETLINK_CB(skb).dst_group = 1;
error = netlink_broadcast(syshook_nl_sk, skb, 0, 1, GFP_KERNEL);
Userspace code that receive broadcast messages from kernel.
sock_fd=socket(PF_NETLINK, SOCK_RAW, NETLINK_TEST);
// sock_fd=socket(PF_NETLINK, SOCK_RAW, 15);
if(sock_fd < 0) {
printf("create nl failed.\n");
return -1;
}
memset(&src_addr, 0, sizeof(src_addr));
memset(&msg, 0, sizeof(msg));
src_addr.nl_family = AF_NETLINK;
src_addr.nl_pid = 100; /* self pid */
/* interested in group 1<<0 */
src_addr.nl_groups = 1;
// setsockopt(sock_fd, SOL_SOCKET, SO_RCVBUF, &buffersize, sizeof(buffersize));
bind(sock_fd, (struct sockaddr*)&src_addr, sizeof(src_addr));
memset(&dest_addr, 0, sizeof(dest_addr));
nlh = (struct nlmsghdr *)malloc(NLMSG_SPACE(MAX_PAYLOAD));
memset(nlh, 0, NLMSG_SPACE(MAX_PAYLOAD));
iov.iov_base = (void *)nlh;
iov.iov_len = NLMSG_SPACE(MAX_PAYLOAD);
msg.msg_name = (void *)&dest_addr;
msg.msg_namelen = sizeof(dest_addr);
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
char buf[1024] = {0};
printf("begin to recvmsg jiang \n");
int rcvlen;
while (1) {
/* Read message from kernel */
rcvlen = recv(sock_fd, &buf, sizeof(buf), 0);
// rcvlen = recvmsg(sock_fd, &msg, 0);
printf("--%d--%s\n",rcvlen, buf);
}
sudo make it works. Seems the code is OK.

Searching for the best prescaler (closest integer multiple)

Let's say we have a timer with a counter (cnt) and a prescaler (psc), which triggers clk_freq / div times per second (Hz), where div = cnt * psc and clk_freq is a clock frequency, which is irrelevant. Value range for both counter and prescaler is [1;65536].
Which is the best (quickest) method of picking cnt and psc so that cnt * psc would be as close as possible to some desired_div value?
Example:
desired_div = 3849586
psc = 251, cnt = 15337, psc * cnt = 3849587, distance = 1
psc = 313, cnt = 12299, distance = 1
psc = 1757, cnt = 2191, distance = 1
psc = 2191, cnt = 1757, distance = 1
psc = 12299, cnt = 313, distance = 1
psc = 15337, cnt = 251, distance = 1
The code used to acquire these values (not effective enough):
int main(int argc, char *argv[])
{
uint32_t val, cnt, psc;
if (argc < 2) {
printf("Usage: %s <u32_value>\n", argv[0]);
return 1;
}
sscanf(argv[1], "%u", &val);
printf("Searching for %u\n", val);
uint32_t hlimit = min(65536, val);
uint32_t llimit = max(1, val / 65536);
uint32_t minpsc = 0, minredif = 0xFFFFFFFF;
for (psc = llimit; psc <= hlimit; ++psc) {
cnt = min(65536, val / psc);
uint32_t redif = abs(val - cnt * psc);
if (cnt < 65536) {
redif = min(redif, abs((cnt + 1) * psc - val));
}
if (redif < minredif) {
minpsc = psc;
minredif = redif;
}
printf("%u %u\n", psc, redif);
}
printf("Optimal psc: %u, difference: %u\n", minpsc, minredif);
return 0;
}
not sure how much faster or slower, not calling any libraries so that helps (well other than printf).
#include <stdio.h>
void fun ( unsigned int x )
{
unsigned int ra;
unsigned int rb;
unsigned int rc;
unsigned int rd;
unsigned int min;
min=0; min--;
for(ra=1;ra<32768;ra++)
{
rb=x/ra;
if(rb>65536) continue;
if(1)
{
rc=rb*ra;
if(rc>x) rd=rc-x;
else rd=x-rc;
if(rd<=min)
{
printf("%u %u %u\n",ra,rb,rd);
min=rd;
}
}
if(1)
{
rc=(rb+1)*ra;
if(rc>x) rd=rc-x;
else rd=x-rc;
if(rd<=min)
{
printf("%u %u %u\n",ra,rb+1,rd);
min=rd;
}
}
}
}
for your value the +1 gave the closest results.
59 65247 13
61 63108 2
122 31554 2
183 21036 2
244 15777 2
251 15337 1
313 12299 1
1757 2191 1
2191 1757 1
12299 313 1
15337 251 1
but dont know off hand if that will always be the case (expect not).
You shouldnt need to go past the halfway point as you are just testing the same pairs twice. ab = ba

Autoit get CPU temp and put it into a graph

This is the code i have so far:
#RequireAdmin
#include <GUIConstants.au3>
$wbemFlagReturnImmediately = 0x10
$wbemFlagForwardOnly = 0x20
$strComputer = "."
$objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\wmi")
$Instances = $objWMIService.InstancesOf("MSAcpi_ThermalZoneTemperature")
For $Item in $Instances
$temp=($Item.CurrentTemperature - 2732) / 10
Next
Opt("GUIOnEventMode", 1)
GUICreate("", 340, 330)
GUISetOnEvent($GUI_EVENT_CLOSE,"close")
$GraphWidth = 273
$GraphHeight = 273
$graph = GUICtrlCreateGraphic(48, 15, $GraphWidth, $GraphHeight)
GUICtrlSetBkColor(-1,0xFFFFFF)
GUICtrlSetColor(-1,0x000000)
$yMax = 100
$yMin = 0
$xMax = 100
$xMin = 0
GUICtrlCreateLabel($yMax,15,10,20,15,$SS_RIGHT)
GUICtrlCreateLabel($yMin,15,280,20,15,$SS_RIGHT)
GUICtrlCreateLabel($xMax,307,295,20,15,$SS_CENTER)
GUICtrlCreateLabel($xMin,38,295,20,15,$SS_CENTER)
GUICtrlCreateLabel("TEMP",10,120)
$tmp=GUICtrlCreateLabel($temp,20,140)
GUISetState()
while 1
sleep(10000)
$wbemFlagReturnImmediately = 0x10
$wbemFlagForwardOnly = 0x20
$strComputer = "."
$objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\wmi")
$Instances = $objWMIService.InstancesOf("MSAcpi_ThermalZoneTemperature")
For $Item in $Instances
$temp=($Item.CurrentTemperature - 2732) / 10
Next
GUICtrlSetData($tmp, $temp)
WEnd
func close()
Exit
EndFunc
The code gets the CPU temperature and makes a graph. My questions is how do i put the temperature in to the graph and make it update every 10 seconds. Thanks for any help.
I have made this script using parts of your code, the getting of the temperature and creating and setting the event of it.
I have added the use of the library GraphGDIPlus.au3 which can be downloaded and put into your program files -> autoit -> include; link to GraphGDIPlus.
Here is the script (commented for understanding):
#RequireAdmin
#include <GraphGDIPlus.au3>
#include <GUIConstants.au3>
AdlibRegister("findTemp", 9000)
AdlibRegister("_Draw_Graph", 10000)
Local $hGUI, $hGraph, $temp, $Counter = 1, $iCheck, $msg, $xVal = 1
$hGUI = GUICreate("", 600, 350) ; create the GUI window
$iCheck = GUICtrlCreateCheckbox("Reset on next interval", 462, 1)
GUISetState() ; show the window
CreateGraph() ; create the graph
findTemp() ; find the temp
_Draw_Graph() ; draw the graph
While 1
$msg = GUIGetMsg()
Switch $msg
Case $GUI_EVENT_CLOSE
Quit()
EndSwitch
WEnd
Func CreateGraph()
If IsArray($hGraph) = 0 Then
$hGraph = _GraphGDIPlus_Create($hGUI, 37, 24, 545, 300, 0xFF000000, 0xFF88B3DD) ; create the graph
EndIf
If $Counter > 24 Then
_GraphGDIPlus_Set_RangeX($hGraph, $xVal, $Counter, 24)
$xVal += 1
Else
_GraphGDIPlus_Set_RangeX($hGraph, 0, 24, 24) ; set the x range from 0 - 24 putting all 24 ticks on screen
_GraphGDIPlus_Set_RangeY($hGraph, 0, 125, 5) ; set the y range from 0 - 125 only putting 5 ticks on screen
_GraphGDIPlus_Set_GridX($hGraph, 1, 0xFF6993BE) ; set the x grid
_GraphGDIPlus_Set_GridY($hGraph, 1, 0xFF6993BE) ; set the y grid
EndIf
EndFunc ;==>CreateGraph
Func _Draw_Graph()
Local $rCheckbox
$rCheckbox = GUICtrlRead($iCheck)
If $rCheckbox = 1 Then
ControlClick($hGUI, "Reset on next interval", $iCheck)
_GraphGDIPlus_Delete($hGUI, $hGraph) ; delete the graph
$Counter = 1 ; reset the counter
$xVal = 1 ; reset the x range counter
CreateGraph() ; and create the graph again
EndIf
If $Counter > 24 Then ; if we've reached the end
CreateGraph() ; and create the graph again
EndIf
_GraphGDIPlus_Set_PenColor($hGraph, 0xFF325D87) ; set the color of the line
_GraphGDIPlus_Set_PenSize($hGraph, 2) ; set the size of the line
_GraphGDIPlus_Plot_Start($hGraph, $Counter, 0) ; set the start on the graph plot
_GraphGDIPlus_Plot_Line($hGraph, $Counter, $temp) ; set the line ending
_GraphGDIPlus_Refresh($hGraph) ; draw it to the screen
$Counter += 1 ; add one to our counter
EndFunc ;==>_Draw_Graph
Func findTemp()
$wbemFlagReturnImmediately = 0x10
$wbemFlagForwardOnly = 0x20
$strComputer = "."
$objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\wmi")
$Instances = $objWMIService.InstancesOf("MSAcpi_ThermalZoneTemperature")
For $Item In $Instances
$temp = ($Item.CurrentTemperature - 2732) / 10 ; set the temp
Next
EndFunc ;==>findTemp
Func Quit()
_GraphGDIPlus_Delete($hGUI, $hGraph) ; delete the graph
Exit ; get us out
EndFunc ;==>Quit

Resources